Merged revisions 74609,74627,74634,74645,74651,74738,74840,75016,75316-75317,75323-75324,75326,75328,75330,75338,75340-75341,75343,75352-75353,75355,75357,75359 via svnmerge from
svn+ssh://svn.python.org/python/branches/py3k ................ r74609 | senthil.kumaran | 2009-08-31 18:43:45 +0200 (Mo, 31 Aug 2009) | 3 lines Doc fix for issue2637. ................ r74627 | georg.brandl | 2009-09-02 22:31:26 +0200 (Mi, 02 Sep 2009) | 1 line #6819: fix typo. ................ r74634 | georg.brandl | 2009-09-03 14:34:10 +0200 (Do, 03 Sep 2009) | 9 lines Merged revisions 74633 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74633 | georg.brandl | 2009-09-03 14:31:39 +0200 (Do, 03 Sep 2009) | 1 line #6757: complete the list of types that marshal can serialize. ........ ................ r74645 | georg.brandl | 2009-09-04 10:07:32 +0200 (Fr, 04 Sep 2009) | 1 line #5221: fix related topics: SEQUENCEMETHODS[12] doesnt exist any more. ................ r74651 | georg.brandl | 2009-09-04 13:20:54 +0200 (Fr, 04 Sep 2009) | 9 lines Recorded merge of revisions 74650 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74650 | georg.brandl | 2009-09-04 13:19:34 +0200 (Fr, 04 Sep 2009) | 1 line #5101: add back tests to test_funcattrs that were lost during unittest conversion, and make some PEP8 cleanups. ........ ................ r74738 | georg.brandl | 2009-09-09 18:51:05 +0200 (Mi, 09 Sep 2009) | 9 lines Merged revisions 74737 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74737 | georg.brandl | 2009-09-09 18:49:13 +0200 (Mi, 09 Sep 2009) | 1 line Properly document copy and deepcopy as functions. ........ ................ r74840 | georg.brandl | 2009-09-16 18:40:45 +0200 (Mi, 16 Sep 2009) | 13 lines Merged revisions 74838-74839 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74838 | georg.brandl | 2009-09-16 18:22:12 +0200 (Mi, 16 Sep 2009) | 1 line Remove some more boilerplate from the actual tests in test_pdb. ........ r74839 | georg.brandl | 2009-09-16 18:36:39 +0200 (Mi, 16 Sep 2009) | 1 line Make the pdb displayhook compatible with the standard displayhook: do not print Nones. Add a test for that. ........ ................ r75016 | georg.brandl | 2009-09-22 15:53:14 +0200 (Di, 22 Sep 2009) | 1 line #6969: make it explicit that configparser writes/reads text files, and fix the example. ................ r75316 | georg.brandl | 2009-10-10 23:12:35 +0200 (Sa, 10 Okt 2009) | 9 lines Merged revisions 75313 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75313 | georg.brandl | 2009-10-10 23:07:35 +0200 (Sa, 10 Okt 2009) | 1 line Bring old demo up-to-date. ........ ................ r75317 | georg.brandl | 2009-10-10 23:13:21 +0200 (Sa, 10 Okt 2009) | 9 lines Merged revisions 75315 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75315 | georg.brandl | 2009-10-10 23:10:05 +0200 (Sa, 10 Okt 2009) | 1 line Remove unneeded "L" suffixes. ........ ................ r75323 | georg.brandl | 2009-10-10 23:48:05 +0200 (Sa, 10 Okt 2009) | 9 lines Recorded merge of revisions 75321 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75321 | georg.brandl | 2009-10-10 23:43:21 +0200 (Sa, 10 Okt 2009) | 1 line Remove outdated comment and fix a few style issues. ........ ................ r75324 | georg.brandl | 2009-10-10 23:49:24 +0200 (Sa, 10 Okt 2009) | 9 lines Merged revisions 75322 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75322 | georg.brandl | 2009-10-10 23:47:31 +0200 (Sa, 10 Okt 2009) | 1 line Show use of range() step argument nicely. ........ ................ r75326 | georg.brandl | 2009-10-10 23:57:03 +0200 (Sa, 10 Okt 2009) | 9 lines Merged revisions 75325 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75325 | georg.brandl | 2009-10-10 23:55:11 +0200 (Sa, 10 Okt 2009) | 1 line Modernize factorisation demo (mostly augassign.) ........ ................ r75328 | georg.brandl | 2009-10-11 00:05:26 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75327 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75327 | georg.brandl | 2009-10-11 00:03:43 +0200 (So, 11 Okt 2009) | 1 line Style fixes. ........ ................ r75330 | georg.brandl | 2009-10-11 00:32:28 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75329 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75329 | georg.brandl | 2009-10-11 00:26:45 +0200 (So, 11 Okt 2009) | 1 line Modernize all around (dont ask me how useful that script is nowadays...) ........ ................ r75338 | georg.brandl | 2009-10-11 10:31:41 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75337 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75337 | georg.brandl | 2009-10-11 10:18:44 +0200 (So, 11 Okt 2009) | 1 line Update morse script, avoid globals, use iterators. ........ ................ r75340 | georg.brandl | 2009-10-11 10:42:09 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75339 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75339 | georg.brandl | 2009-10-11 10:39:16 +0200 (So, 11 Okt 2009) | 1 line Update markov demo. ........ ................ r75341 | georg.brandl | 2009-10-11 10:43:08 +0200 (So, 11 Okt 2009) | 1 line Fix README description. ................ r75343 | georg.brandl | 2009-10-11 10:46:56 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75342 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75342 | georg.brandl | 2009-10-11 10:45:03 +0200 (So, 11 Okt 2009) | 1 line Remove useless script "mkrcs" and update README. ........ ................ r75352 | georg.brandl | 2009-10-11 14:04:10 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75350 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75350 | georg.brandl | 2009-10-11 14:00:18 +0200 (So, 11 Okt 2009) | 1 line Use getopt in script.py demo. ........ ................ r75353 | georg.brandl | 2009-10-11 14:04:40 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75351 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75351 | georg.brandl | 2009-10-11 14:03:01 +0200 (So, 11 Okt 2009) | 1 line Fix variable. ........ ................ r75355 | georg.brandl | 2009-10-11 16:27:51 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75354 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75354 | georg.brandl | 2009-10-11 16:23:49 +0200 (So, 11 Okt 2009) | 1 line Update lpwatch script. ........ ................ r75357 | georg.brandl | 2009-10-11 16:50:57 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75356 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75356 | georg.brandl | 2009-10-11 16:49:37 +0200 (So, 11 Okt 2009) | 1 line Remove ftpstats script, the daemon whose log files it reads is long gone. ........ ................ r75359 | georg.brandl | 2009-10-11 17:56:06 +0200 (So, 11 Okt 2009) | 9 lines Merged revisions 75358 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75358 | georg.brandl | 2009-10-11 17:06:44 +0200 (So, 11 Okt 2009) | 1 line Overhaul of Demo/xml. ........ ................
This commit is contained in:
parent
7dc008d001
commit
22fff43633
|
@ -5,15 +5,14 @@ See also the Tools/scripts directory!
|
|||
beer.py Print the classic 'bottles of beer' list.
|
||||
eqfix.py Fix .py files to use the correct equality test operator
|
||||
fact.py Factorize numbers
|
||||
find-uname.py Search for Unicode characters using regexps.
|
||||
find-uname.py Search for Unicode characters using regexps
|
||||
from.py Summarize mailbox
|
||||
ftpstats.py Summarize ftp daemon log file
|
||||
lpwatch.py Watch BSD line printer queues
|
||||
makedir.py Like mkdir -p
|
||||
markov.py Markov chain simulation of words or characters
|
||||
mboxconvvert.py Convert MH or MMDF mailboxes to unix mailbox format
|
||||
mkrcs.py Fix symlinks named RCS into parallel tree
|
||||
morse.py Produce morse code (audible or on AIFF file)
|
||||
mboxconvert.py Convert MH or MMDF mailboxes to unix mailbox format
|
||||
morse.py Produce morse code (as an AIFF file)
|
||||
newslist.py List all newsgroups on a NNTP server as HTML pages
|
||||
pi.py Print all digits of pi -- given enough time and memory
|
||||
pp.py Emulate some Perl command line options
|
||||
primes.py Print prime numbers
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# By GvR, demystified after a version by Fredrik Lundh.
|
||||
|
||||
import sys
|
||||
|
||||
n = 100
|
||||
if sys.argv[1:]: n = int(sys.argv[1])
|
||||
if sys.argv[1:]:
|
||||
n = int(sys.argv[1])
|
||||
|
||||
def bottle(n):
|
||||
if n == 0: return "no more bottles of beer"
|
||||
if n == 1: return "one bottle of beer"
|
||||
return str(n) + " bottles of beer"
|
||||
for i in range(n):
|
||||
print(bottle(n-i), "on the wall,")
|
||||
print(bottle(n-i) + ".")
|
||||
|
||||
for i in range(n, 0, -1):
|
||||
print(bottle(i), "on the wall,")
|
||||
print(bottle(i) + ".")
|
||||
print("Take one down, pass it around,")
|
||||
print(bottle(n-i-1), "on the wall.")
|
||||
print(bottle(i-1), "on the wall.")
|
||||
|
|
|
@ -9,39 +9,41 @@ import sys
|
|||
from math import sqrt
|
||||
|
||||
def fact(n):
|
||||
if n < 1: raise ValueError # fact() argument should be >= 1
|
||||
if n == 1: return [] # special case
|
||||
if n < 1:
|
||||
raise ValueError('fact() argument should be >= 1')
|
||||
if n == 1:
|
||||
return [] # special case
|
||||
res = []
|
||||
# Treat even factors special, so we can use i = i+2 later
|
||||
while n%2 == 0:
|
||||
# Treat even factors special, so we can use i += 2 later
|
||||
while n % 2 == 0:
|
||||
res.append(2)
|
||||
n = n//2
|
||||
n //= 2
|
||||
# Try odd numbers up to sqrt(n)
|
||||
limit = sqrt(float(n+1))
|
||||
limit = sqrt(n+1)
|
||||
i = 3
|
||||
while i <= limit:
|
||||
if n%i == 0:
|
||||
if n % i == 0:
|
||||
res.append(i)
|
||||
n = n//i
|
||||
n //= i
|
||||
limit = sqrt(n+1)
|
||||
else:
|
||||
i = i+2
|
||||
i += 2
|
||||
if n != 1:
|
||||
res.append(n)
|
||||
return res
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1:
|
||||
for arg in sys.argv[1:]:
|
||||
n = eval(arg)
|
||||
print(n, fact(n))
|
||||
source = sys.argv[1:]
|
||||
else:
|
||||
source = iter(input, '')
|
||||
for arg in source:
|
||||
try:
|
||||
while 1:
|
||||
n = eval(input())
|
||||
print(n, fact(n))
|
||||
except EOFError:
|
||||
pass
|
||||
n = int(arg)
|
||||
except ValueError:
|
||||
print(arg, 'is not an integer')
|
||||
else:
|
||||
print(n, fact(n))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -21,20 +21,20 @@ import sys
|
|||
import re
|
||||
|
||||
def main(args):
|
||||
unicode_names= []
|
||||
unicode_names = []
|
||||
for ix in range(sys.maxunicode+1):
|
||||
try:
|
||||
unicode_names.append( (ix, unicodedata.name(chr(ix))) )
|
||||
unicode_names.append((ix, unicodedata.name(chr(ix))))
|
||||
except ValueError: # no name for the character
|
||||
pass
|
||||
for arg in args:
|
||||
pat = re.compile(arg, re.I)
|
||||
matches = [(x,y) for (x,y) in unicode_names
|
||||
if pat.search(y) is not None]
|
||||
matches = [(y,x) for (x,y) in unicode_names
|
||||
if pat.search(y) is not None]
|
||||
if matches:
|
||||
print("***", arg, "matches", "***")
|
||||
for (x,y) in matches:
|
||||
print("%s (%d)" % (y,x))
|
||||
for match in matches:
|
||||
print("%s (%d)" % match)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Extract statistics from ftp daemon log.
|
||||
|
||||
# Usage:
|
||||
# ftpstats [-m maxitems] [-s search] [file]
|
||||
# -m maxitems: restrict number of items in "top-N" lists, default 25.
|
||||
# -s string: restrict statistics to lines containing this string.
|
||||
# Default file is /usr/adm/ftpd; a "-" means read standard input.
|
||||
|
||||
# The script must be run on the host where the ftp daemon runs.
|
||||
# (At CWI this is currently buizerd.)
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import string
|
||||
import getopt
|
||||
|
||||
pat = '^([a-zA-Z0-9 :]*)!(.*)!(.*)!([<>].*)!([0-9]+)!([0-9]+)$'
|
||||
prog = re.compile(pat)
|
||||
|
||||
def main():
|
||||
maxitems = 25
|
||||
search = None
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'm:s:')
|
||||
except getopt.error as msg:
|
||||
print(msg)
|
||||
print('usage: ftpstats [-m maxitems] [file]')
|
||||
sys.exit(2)
|
||||
for o, a in opts:
|
||||
if o == '-m':
|
||||
maxitems = string.atoi(a)
|
||||
if o == '-s':
|
||||
search = a
|
||||
file = '/usr/adm/ftpd'
|
||||
if args: file = args[0]
|
||||
if file == '-':
|
||||
f = sys.stdin
|
||||
else:
|
||||
try:
|
||||
f = open(file, 'r')
|
||||
except IOError as msg:
|
||||
print(file, ':', msg)
|
||||
sys.exit(1)
|
||||
bydate = {}
|
||||
bytime = {}
|
||||
byfile = {}
|
||||
bydir = {}
|
||||
byhost = {}
|
||||
byuser = {}
|
||||
bytype = {}
|
||||
lineno = 0
|
||||
try:
|
||||
while 1:
|
||||
line = f.readline()
|
||||
if not line: break
|
||||
lineno = lineno + 1
|
||||
if search and string.find(line, search) < 0:
|
||||
continue
|
||||
if prog.match(line) < 0:
|
||||
print('Bad line', lineno, ':', repr(line))
|
||||
continue
|
||||
items = prog.group(1, 2, 3, 4, 5, 6)
|
||||
(logtime, loguser, loghost, logfile, logbytes,
|
||||
logxxx2) = items
|
||||
## print logtime
|
||||
## print '-->', loguser
|
||||
## print '--> -->', loghost
|
||||
## print '--> --> -->', logfile
|
||||
## print '--> --> --> -->', logbytes
|
||||
## print '--> --> --> --> -->', logxxx2
|
||||
## for i in logtime, loghost, logbytes, logxxx2:
|
||||
## if '!' in i: print '???', i
|
||||
add(bydate, logtime[-4:] + ' ' + logtime[:6], items)
|
||||
add(bytime, logtime[7:9] + ':00-59', items)
|
||||
direction, logfile = logfile[0], logfile[1:]
|
||||
# The real path probably starts at the last //...
|
||||
while 1:
|
||||
i = string.find(logfile, '//')
|
||||
if i < 0: break
|
||||
logfile = logfile[i+1:]
|
||||
add(byfile, logfile + ' ' + direction, items)
|
||||
logdir = os.path.dirname(logfile)
|
||||
## logdir = os.path.normpath(logdir) + '/.'
|
||||
while 1:
|
||||
add(bydir, logdir + ' ' + direction, items)
|
||||
dirhead = os.path.dirname(logdir)
|
||||
if dirhead == logdir: break
|
||||
logdir = dirhead
|
||||
add(byhost, loghost, items)
|
||||
add(byuser, loguser, items)
|
||||
add(bytype, direction, items)
|
||||
except KeyboardInterrupt:
|
||||
print('Interrupted at line', lineno)
|
||||
show(bytype, 'by transfer direction', maxitems)
|
||||
show(bydir, 'by directory', maxitems)
|
||||
show(byfile, 'by file', maxitems)
|
||||
show(byhost, 'by host', maxitems)
|
||||
show(byuser, 'by user', maxitems)
|
||||
showbar(bydate, 'by date')
|
||||
showbar(bytime, 'by time of day')
|
||||
|
||||
def showbar(dict, title):
|
||||
n = len(title)
|
||||
print('='*((70-n)//2), title, '='*((71-n)//2))
|
||||
list = []
|
||||
for key in sorted(dict.keys()):
|
||||
n = len(str(key))
|
||||
list.append((len(dict[key]), key))
|
||||
maxkeylength = 0
|
||||
maxcount = 0
|
||||
for count, key in list:
|
||||
maxkeylength = max(maxkeylength, len(key))
|
||||
maxcount = max(maxcount, count)
|
||||
maxbarlength = 72 - maxkeylength - 7
|
||||
for count, key in list:
|
||||
barlength = int(round(maxbarlength*float(count)/maxcount))
|
||||
bar = '*'*barlength
|
||||
print('%5d %-*s %s' % (count, maxkeylength, key, bar))
|
||||
|
||||
def show(dict, title, maxitems):
|
||||
if len(dict) > maxitems:
|
||||
title = title + ' (first %d)'%maxitems
|
||||
n = len(title)
|
||||
print('='*((70-n)//2), title, '='*((71-n)//2))
|
||||
list = []
|
||||
for key in dict.keys():
|
||||
list.append((-len(dict[key]), key))
|
||||
list.sort()
|
||||
for count, key in list[:maxitems]:
|
||||
print('%5d %s' % (-count, key))
|
||||
|
||||
def add(dict, key, item):
|
||||
if key in dict:
|
||||
dict[key].append(item)
|
||||
else:
|
||||
dict[key] = [item]
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -3,10 +3,9 @@
|
|||
# Watch line printer queue(s).
|
||||
# Intended for BSD 4.3 lpq.
|
||||
|
||||
import posix
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import string
|
||||
|
||||
DEF_PRINTER = 'psc'
|
||||
DEF_DELAY = 10
|
||||
|
@ -14,94 +13,87 @@ DEF_DELAY = 10
|
|||
def main():
|
||||
delay = DEF_DELAY # XXX Use getopt() later
|
||||
try:
|
||||
thisuser = posix.environ['LOGNAME']
|
||||
thisuser = os.environ['LOGNAME']
|
||||
except:
|
||||
thisuser = posix.environ['USER']
|
||||
thisuser = os.environ['USER']
|
||||
printers = sys.argv[1:]
|
||||
if printers:
|
||||
# Strip '-P' from printer names just in case
|
||||
# the user specified it...
|
||||
for i in range(len(printers)):
|
||||
if printers[i][:2] == '-P':
|
||||
printers[i] = printers[i][2:]
|
||||
for i, name in enumerate(printers):
|
||||
if name[:2] == '-P':
|
||||
printers[i] = name[2:]
|
||||
else:
|
||||
if 'PRINTER' in posix.environ:
|
||||
printers = [posix.environ['PRINTER']]
|
||||
if 'PRINTER' in os.environ:
|
||||
printers = [os.environ['PRINTER']]
|
||||
else:
|
||||
printers = [DEF_PRINTER]
|
||||
#
|
||||
clearhome = posix.popen('clear', 'r').read()
|
||||
#
|
||||
while 1:
|
||||
|
||||
clearhome = os.popen('clear', 'r').read()
|
||||
|
||||
while True:
|
||||
text = clearhome
|
||||
for name in printers:
|
||||
text = text + makestatus(name, thisuser) + '\n'
|
||||
text += makestatus(name, thisuser) + '\n'
|
||||
print(text)
|
||||
time.sleep(delay)
|
||||
|
||||
def makestatus(name, thisuser):
|
||||
pipe = posix.popen('lpq -P' + name + ' 2>&1', 'r')
|
||||
pipe = os.popen('lpq -P' + name + ' 2>&1', 'r')
|
||||
lines = []
|
||||
users = {}
|
||||
aheadbytes = 0
|
||||
aheadjobs = 0
|
||||
userseen = 0
|
||||
userseen = False
|
||||
totalbytes = 0
|
||||
totaljobs = 0
|
||||
while 1:
|
||||
line = pipe.readline()
|
||||
if not line: break
|
||||
fields = string.split(line)
|
||||
for line in pipe:
|
||||
fields = line.split()
|
||||
n = len(fields)
|
||||
if len(fields) >= 6 and fields[n-1] == 'bytes':
|
||||
rank = fields[0]
|
||||
user = fields[1]
|
||||
job = fields[2]
|
||||
rank, user, job = fields[0:3]
|
||||
files = fields[3:-2]
|
||||
bytes = eval(fields[n-2])
|
||||
bytes = int(fields[n-2])
|
||||
if user == thisuser:
|
||||
userseen = 1
|
||||
userseen = True
|
||||
elif not userseen:
|
||||
aheadbytes = aheadbytes + bytes
|
||||
aheadjobs = aheadjobs + 1
|
||||
totalbytes = totalbytes + bytes
|
||||
totaljobs = totaljobs + 1
|
||||
if user in users:
|
||||
ujobs, ubytes = users[user]
|
||||
else:
|
||||
ujobs, ubytes = 0, 0
|
||||
ujobs = ujobs + 1
|
||||
ubytes = ubytes + bytes
|
||||
aheadbytes += bytes
|
||||
aheadjobs += 1
|
||||
totalbytes += bytes
|
||||
totaljobs += 1
|
||||
ujobs, ubytes = users.get(user, (0, 0))
|
||||
ujobs += 1
|
||||
ubytes += bytes
|
||||
users[user] = ujobs, ubytes
|
||||
else:
|
||||
if fields and fields[0] != 'Rank':
|
||||
line = string.strip(line)
|
||||
line = line.strip()
|
||||
if line == 'no entries':
|
||||
line = name + ': idle'
|
||||
elif line[-22:] == ' is ready and printing':
|
||||
line = name
|
||||
lines.append(line)
|
||||
#
|
||||
|
||||
if totaljobs:
|
||||
line = '%d K' % ((totalbytes+1023)//1024)
|
||||
line = '%d K' % ((totalbytes+1023) // 1024)
|
||||
if totaljobs != len(users):
|
||||
line = line + ' (%d jobs)' % totaljobs
|
||||
line += ' (%d jobs)' % totaljobs
|
||||
if len(users) == 1:
|
||||
line = line + ' for %s' % (list(users.keys())[0],)
|
||||
line += ' for %s' % next(iter(users))
|
||||
else:
|
||||
line = line + ' for %d users' % len(users)
|
||||
line += ' for %d users' % len(users)
|
||||
if userseen:
|
||||
if aheadjobs == 0:
|
||||
line = line + ' (%s first)' % thisuser
|
||||
line += ' (%s first)' % thisuser
|
||||
else:
|
||||
line = line + ' (%d K before %s)' % (
|
||||
(aheadbytes+1023)//1024, thisuser)
|
||||
line += ' (%d K before %s)' % (
|
||||
(aheadbytes+1023) // 1024, thisuser)
|
||||
lines.append(line)
|
||||
#
|
||||
|
||||
sts = pipe.close()
|
||||
if sts:
|
||||
lines.append('lpq exit status %r' % (sts,))
|
||||
return string.joinfields(lines, ': ')
|
||||
return ': '.join(lines)
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
|
|
|
@ -5,11 +5,10 @@ class Markov:
|
|||
self.histsize = histsize
|
||||
self.choice = choice
|
||||
self.trans = {}
|
||||
|
||||
def add(self, state, next):
|
||||
if state not in self.trans:
|
||||
self.trans[state] = [next]
|
||||
else:
|
||||
self.trans[state].append(next)
|
||||
self.trans.setdefault(state, []).append(next)
|
||||
|
||||
def put(self, seq):
|
||||
n = self.histsize
|
||||
add = self.add
|
||||
|
@ -17,26 +16,29 @@ class Markov:
|
|||
for i in range(len(seq)):
|
||||
add(seq[max(0, i-n):i], seq[i:i+1])
|
||||
add(seq[len(seq)-n:], None)
|
||||
|
||||
def get(self):
|
||||
choice = self.choice
|
||||
trans = self.trans
|
||||
n = self.histsize
|
||||
seq = choice(trans[None])
|
||||
while 1:
|
||||
while True:
|
||||
subseq = seq[max(0, len(seq)-n):]
|
||||
options = trans[subseq]
|
||||
next = choice(options)
|
||||
if not next: break
|
||||
seq = seq + next
|
||||
if not next:
|
||||
break
|
||||
seq += next
|
||||
return seq
|
||||
|
||||
|
||||
def test():
|
||||
import sys, string, random, getopt
|
||||
import sys, random, getopt
|
||||
args = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.getopt(args, '0123456789cdw')
|
||||
opts, args = getopt.getopt(args, '0123456789cdwq')
|
||||
except getopt.error:
|
||||
print('Usage: markov [-#] [-cddqw] [file] ...')
|
||||
print('Usage: %s [-#] [-cddqw] [file] ...' % sys.argv[0])
|
||||
print('Options:')
|
||||
print('-#: 1-digit history size (default 2)')
|
||||
print('-c: characters (default)')
|
||||
|
@ -49,16 +51,19 @@ def test():
|
|||
print('exactly one space separating words.')
|
||||
print('Output consists of paragraphs separated by blank')
|
||||
print('lines, where lines are no longer than 72 characters.')
|
||||
sys.exit(2)
|
||||
histsize = 2
|
||||
do_words = 0
|
||||
do_words = False
|
||||
debug = 1
|
||||
for o, a in opts:
|
||||
if '-0' <= o <= '-9': histsize = eval(o[1:])
|
||||
if o == '-c': do_words = 0
|
||||
if o == '-d': debug = debug + 1
|
||||
if '-0' <= o <= '-9': histsize = int(o[1:])
|
||||
if o == '-c': do_words = False
|
||||
if o == '-d': debug += 1
|
||||
if o == '-q': debug = 0
|
||||
if o == '-w': do_words = 1
|
||||
if not args: args = ['-']
|
||||
if o == '-w': do_words = True
|
||||
if not args:
|
||||
args = ['-']
|
||||
|
||||
m = Markov(histsize, random.choice)
|
||||
try:
|
||||
for filename in args:
|
||||
|
@ -72,13 +77,15 @@ def test():
|
|||
if debug: print('processing', filename, '...')
|
||||
text = f.read()
|
||||
f.close()
|
||||
paralist = string.splitfields(text, '\n\n')
|
||||
paralist = text.split('\n\n')
|
||||
for para in paralist:
|
||||
if debug > 1: print('feeding ...')
|
||||
words = string.split(para)
|
||||
words = para.split()
|
||||
if words:
|
||||
if do_words: data = tuple(words)
|
||||
else: data = string.joinfields(words, ' ')
|
||||
if do_words:
|
||||
data = tuple(words)
|
||||
else:
|
||||
data = ' '.join(words)
|
||||
m.put(data)
|
||||
except KeyboardInterrupt:
|
||||
print('Interrupted -- continue with data read so far')
|
||||
|
@ -86,16 +93,19 @@ def test():
|
|||
print('No valid input files')
|
||||
return
|
||||
if debug: print('done.')
|
||||
|
||||
if debug > 1:
|
||||
for key in m.trans.keys():
|
||||
if key is None or len(key) < histsize:
|
||||
print(repr(key), m.trans[key])
|
||||
if histsize == 0: print(repr(''), m.trans[''])
|
||||
print()
|
||||
while 1:
|
||||
while True:
|
||||
data = m.get()
|
||||
if do_words: words = data
|
||||
else: words = string.split(data)
|
||||
if do_words:
|
||||
words = data
|
||||
else:
|
||||
words = data.split()
|
||||
n = 0
|
||||
limit = 72
|
||||
for w in words:
|
||||
|
@ -103,15 +113,9 @@ def test():
|
|||
print()
|
||||
n = 0
|
||||
print(w, end=' ')
|
||||
n = n + len(w) + 1
|
||||
n += len(w) + 1
|
||||
print()
|
||||
print()
|
||||
|
||||
def tuple(list):
|
||||
if len(list) == 0: return ()
|
||||
if len(list) == 1: return (list[0],)
|
||||
i = len(list)//2
|
||||
return tuple(list[:i]) + tuple(list[i:])
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# A rather specialized script to make sure that a symbolic link named
|
||||
# RCS exists pointing to a real RCS directory in a parallel tree
|
||||
# referenced as RCStree in an ancestor directory.
|
||||
# (I use this because I like my RCS files to reside on a physically
|
||||
# different machine).
|
||||
|
||||
import os
|
||||
|
||||
def main():
|
||||
rcstree = 'RCStree'
|
||||
rcs = 'RCS'
|
||||
if os.path.islink(rcs):
|
||||
print('%r is a symlink to %r' % (rcs, os.readlink(rcs)))
|
||||
return
|
||||
if os.path.isdir(rcs):
|
||||
print('%r is an ordinary directory' % (rcs,))
|
||||
return
|
||||
if os.path.exists(rcs):
|
||||
print('%r is a file?!?!' % (rcs,))
|
||||
return
|
||||
#
|
||||
p = os.getcwd()
|
||||
up = ''
|
||||
down = ''
|
||||
# Invariants:
|
||||
# (1) join(p, down) is the current directory
|
||||
# (2) up is the same directory as p
|
||||
# Ergo:
|
||||
# (3) join(up, down) is the current directory
|
||||
#print 'p =', repr(p)
|
||||
while not os.path.isdir(os.path.join(p, rcstree)):
|
||||
head, tail = os.path.split(p)
|
||||
#print 'head = %r; tail = %r' % (head, tail)
|
||||
if not tail:
|
||||
print('Sorry, no ancestor dir contains %r' % (rcstree,))
|
||||
return
|
||||
p = head
|
||||
up = os.path.join(os.pardir, up)
|
||||
down = os.path.join(tail, down)
|
||||
#print 'p = %r; up = %r; down = %r' % (p, up, down)
|
||||
there = os.path.join(up, rcstree)
|
||||
there = os.path.join(there, down)
|
||||
there = os.path.join(there, rcs)
|
||||
if os.path.isdir(there):
|
||||
print('%r already exists' % (there, ))
|
||||
else:
|
||||
print('making %r' % (there,))
|
||||
makedirs(there)
|
||||
print('making symlink %r -> %r' % (rcs, there))
|
||||
os.symlink(there, rcs)
|
||||
|
||||
def makedirs(p):
|
||||
if not os.path.isdir(p):
|
||||
head, tail = os.path.split(p)
|
||||
makedirs(head)
|
||||
os.mkdir(p, 0o777)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,128 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# DAH should be three DOTs.
|
||||
# Space between DOTs and DAHs should be one DOT.
|
||||
# Space between two letters should be one DAH.
|
||||
# Space between two words should be DOT DAH DAH.
|
||||
|
||||
import sys, math, aifc
|
||||
from contextlib import closing
|
||||
|
||||
DOT = 30
|
||||
DAH = 3 * DOT
|
||||
OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
|
||||
|
||||
morsetab = {
|
||||
'A': '.-', 'a': '.-',
|
||||
'B': '-...', 'b': '-...',
|
||||
'C': '-.-.', 'c': '-.-.',
|
||||
'D': '-..', 'd': '-..',
|
||||
'E': '.', 'e': '.',
|
||||
'F': '..-.', 'f': '..-.',
|
||||
'G': '--.', 'g': '--.',
|
||||
'H': '....', 'h': '....',
|
||||
'I': '..', 'i': '..',
|
||||
'J': '.---', 'j': '.---',
|
||||
'K': '-.-', 'k': '-.-',
|
||||
'L': '.-..', 'l': '.-..',
|
||||
'M': '--', 'm': '--',
|
||||
'N': '-.', 'n': '-.',
|
||||
'O': '---', 'o': '---',
|
||||
'P': '.--.', 'p': '.--.',
|
||||
'Q': '--.-', 'q': '--.-',
|
||||
'R': '.-.', 'r': '.-.',
|
||||
'S': '...', 's': '...',
|
||||
'T': '-', 't': '-',
|
||||
'U': '..-', 'u': '..-',
|
||||
'V': '...-', 'v': '...-',
|
||||
'W': '.--', 'w': '.--',
|
||||
'X': '-..-', 'x': '-..-',
|
||||
'Y': '-.--', 'y': '-.--',
|
||||
'Z': '--..', 'z': '--..',
|
||||
'0': '-----', ',': '--..--',
|
||||
'1': '.----', '.': '.-.-.-',
|
||||
'2': '..---', '?': '..--..',
|
||||
'3': '...--', ';': '-.-.-.',
|
||||
'4': '....-', ':': '---...',
|
||||
'5': '.....', "'": '.----.',
|
||||
'6': '-....', '-': '-....-',
|
||||
'7': '--...', '/': '-..-.',
|
||||
'8': '---..', '(': '-.--.-',
|
||||
'9': '----.', ')': '-.--.-',
|
||||
' ': ' ', '_': '..--.-',
|
||||
}
|
||||
|
||||
nowave = b'\0' * 200
|
||||
|
||||
# If we play at 44.1 kHz (which we do), then if we produce one sine
|
||||
# wave in 100 samples, we get a tone of 441 Hz. If we produce two
|
||||
# sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
|
||||
# appears to be a nice one for playing morse code.
|
||||
def mkwave(octave):
|
||||
sinewave = bytearray()
|
||||
for i in range(100):
|
||||
val = int(math.sin(math.pi * i * octave / 50.0) * 30000)
|
||||
sinewave.extend([(val >> 8) & 255, val & 255])
|
||||
return bytes(sinewave)
|
||||
|
||||
defaultwave = mkwave(OCTAVE)
|
||||
|
||||
def main():
|
||||
import getopt
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'o:p:')
|
||||
except getopt.error:
|
||||
sys.stderr.write('Usage ' + sys.argv[0] +
|
||||
' [ -o outfile ] [ -p octave ] [ words ] ...\n')
|
||||
sys.exit(1)
|
||||
wave = defaultwave
|
||||
outfile = 'morse.aifc'
|
||||
for o, a in opts:
|
||||
if o == '-o':
|
||||
outfile = a
|
||||
if o == '-p':
|
||||
wave = mkwave(int(a))
|
||||
with closing(aifc.open(outfile, 'w')) as fp:
|
||||
fp.setframerate(44100)
|
||||
fp.setsampwidth(2)
|
||||
fp.setnchannels(1)
|
||||
if args:
|
||||
source = [' '.join(args)]
|
||||
else:
|
||||
source = iter(sys.stdin.readline, '')
|
||||
for line in source:
|
||||
mline = morse(line)
|
||||
play(mline, fp, wave)
|
||||
|
||||
# Convert a string to morse code with \001 between the characters in
|
||||
# the string.
|
||||
def morse(line):
|
||||
res = ''
|
||||
for c in line:
|
||||
try:
|
||||
res += morsetab[c] + '\001'
|
||||
except KeyError:
|
||||
pass
|
||||
return res
|
||||
|
||||
# Play a line of morse code.
|
||||
def play(line, fp, wave):
|
||||
for c in line:
|
||||
if c == '.':
|
||||
sine(fp, DOT, wave)
|
||||
elif c == '-':
|
||||
sine(fp, DAH, wave)
|
||||
else: # space
|
||||
pause(fp, DAH + DOT)
|
||||
pause(fp, DOT)
|
||||
|
||||
def sine(fp, length, wave):
|
||||
for i in range(length):
|
||||
fp.writeframesraw(wave)
|
||||
|
||||
def pause(fp, length):
|
||||
for i in range(length):
|
||||
fp.writeframesraw(nowave)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -32,22 +32,22 @@
|
|||
# fraser@europarc.xerox.com qs101@cl.cam.ac.uk
|
||||
# #
|
||||
#######################################################################
|
||||
import sys,nntplib, string, marshal, time, os, posix, string
|
||||
import sys, nntplib, marshal, time, os
|
||||
|
||||
#######################################################################
|
||||
# Check these variables before running! #
|
||||
|
||||
# Top directory.
|
||||
# Filenames which don't start with / are taken as being relative to this.
|
||||
topdir='/anfs/qsbigdisc/web/html/newspage'
|
||||
topdir = os.path.expanduser('~/newspage')
|
||||
|
||||
# The name of your NNTP host
|
||||
# eg.
|
||||
# newshost = 'nntp-serv.cl.cam.ac.uk'
|
||||
# or use following to get the name from the NNTPSERVER environment
|
||||
# variable:
|
||||
# newshost = posix.environ['NNTPSERVER']
|
||||
newshost = 'nntp-serv.cl.cam.ac.uk'
|
||||
# newshost = os.environ['NNTPSERVER']
|
||||
newshost = 'news.example.com'
|
||||
|
||||
# The filename for a local cache of the newsgroup list
|
||||
treefile = 'grouptree'
|
||||
|
@ -81,7 +81,7 @@ skipempty = 1
|
|||
# pagelinkicon can contain html to put an icon after links to
|
||||
# further pages. This helps to make important links stand out.
|
||||
# Set to '' if not wanted, or '...' is quite a good one.
|
||||
pagelinkicon='... <img src="http://pelican.cl.cam.ac.uk/icons/page.xbm"> '
|
||||
pagelinkicon = '... <img src="http://pelican.cl.cam.ac.uk/icons/page.xbm"> '
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Less important personal preferences:
|
||||
|
@ -106,7 +106,7 @@ from nntplib import NNTP
|
|||
from stat import *
|
||||
|
||||
rcsrev = '$Revision$'
|
||||
rcsrev = string.join([s for s in string.split(rcsrev) if '$' not in s])
|
||||
rcsrev = ' '.join([s for s in rcsrev.split() if '$' not in s])
|
||||
desc = {}
|
||||
|
||||
# Make (possibly) relative filenames into absolute ones
|
||||
|
@ -120,7 +120,7 @@ page = os.path.join(topdir,pagedir)
|
|||
def addtotree(tree, groups):
|
||||
print('Updating tree...')
|
||||
for i in groups:
|
||||
parts = string.splitfields(i,'.')
|
||||
parts = i.split('.')
|
||||
makeleaf(tree, parts)
|
||||
|
||||
# Makeleaf makes a leaf and the branch leading to it if necessary
|
||||
|
@ -141,34 +141,38 @@ def makeleaf(tree,path):
|
|||
# to those groups beginning with <root>.
|
||||
|
||||
def createpage(root, tree, p):
|
||||
filename = os.path.join(pagedir,root+'.html')
|
||||
filename = os.path.join(pagedir, root+'.html')
|
||||
if root == rootpage:
|
||||
detail = ''
|
||||
else:
|
||||
detail = ' under ' + root
|
||||
f = open(filename,'w')
|
||||
# f.write('Content-Type: text/html\n')
|
||||
f.write('<TITLE>Newsgroups available' + detail + '</TITLE>\n')
|
||||
f.write('<H1>Newsgroups available' + detail +'</H1>\n')
|
||||
f.write('<A HREF="'+httppref+rootpage+'.html">Back to top level</A><P>\n')
|
||||
printtree(f,tree,0,p)
|
||||
f.write('<I>This page automatically created by \'newslist\' v. '+rcsrev+'.')
|
||||
f.write(time.ctime(time.time()) + '</I><P>')
|
||||
f.close()
|
||||
with open(filename, 'w') as f:
|
||||
# f.write('Content-Type: text/html\n')
|
||||
f.write('<html>\n<head>\n')
|
||||
f.write('<title>Newsgroups available%s</title>\n' % detail)
|
||||
f.write('</head>\n<body>\n')
|
||||
f.write('<h1>Newsgroups available%s</h1>\n' % detail)
|
||||
f.write('<a href="%s%s.html">Back to top level</a><p>\n' %
|
||||
(httppref, rootpage))
|
||||
printtree(f, tree, 0, p)
|
||||
f.write('\n<p>')
|
||||
f.write("<i>This page automatically created by 'newslist' v. %s." %
|
||||
rcsrev)
|
||||
f.write(time.ctime(time.time()) + '</i>\n')
|
||||
f.write('</body>\n</html>\n')
|
||||
|
||||
# Printtree prints the groups as a bulleted list. Groups with
|
||||
# more than <sublistsize> subgroups will be put on a separate page.
|
||||
# Other sets of subgroups are just indented.
|
||||
|
||||
def printtree(f, tree, indent, p):
|
||||
global desc
|
||||
l = len(tree)
|
||||
|
||||
if l > sublistsize and indent>0:
|
||||
if l > sublistsize and indent > 0:
|
||||
# Create a new page and a link to it
|
||||
f.write('<LI><B><A HREF="'+httppref+p[1:]+'.html">')
|
||||
f.write(p[1:]+'.*')
|
||||
f.write('</A></B>'+pagelinkicon+'\n')
|
||||
f.write('<li><b><a href="%s%s.html">' % (httppref, p[1:]))
|
||||
f.write(p[1:] + '.*')
|
||||
f.write('</a></b>%s\n' % pagelinkicon)
|
||||
createpage(p[1:], tree, p)
|
||||
return
|
||||
|
||||
|
@ -177,67 +181,64 @@ def printtree(f, tree, indent, p):
|
|||
if l > 1:
|
||||
if indent > 0:
|
||||
# Create a sub-list
|
||||
f.write('<LI>'+p[1:]+'\n<UL>')
|
||||
f.write('<li>%s\n<ul>' % p[1:])
|
||||
else:
|
||||
# Create a main list
|
||||
f.write('<UL>')
|
||||
f.write('<ul>')
|
||||
indent = indent + 1
|
||||
|
||||
for i in kl:
|
||||
if i == '.':
|
||||
# Output a newsgroup
|
||||
f.write('<LI><A HREF="news:' + p[1:] + '">'+ p[1:] + '</A> ')
|
||||
f.write('<li><a href="news:%s">%s</a> ' % (p[1:], p[1:]))
|
||||
if p[1:] in desc:
|
||||
f.write(' <I>'+desc[p[1:]]+'</I>\n')
|
||||
f.write(' <i>%s</i>\n' % desc[p[1:]])
|
||||
else:
|
||||
f.write('\n')
|
||||
else:
|
||||
# Output a hierarchy
|
||||
printtree(f,tree[i], indent, p+'.'+i)
|
||||
printtree(f, tree[i], indent, p+'.'+i)
|
||||
|
||||
if l > 1:
|
||||
f.write('\n</UL>')
|
||||
f.write('\n</ul>')
|
||||
|
||||
# Reading descriptions file ---------------------------------------
|
||||
|
||||
# This returns an array mapping group name to its description
|
||||
# This returns a dict mapping group name to its description
|
||||
|
||||
def readdesc(descfile):
|
||||
global desc
|
||||
|
||||
desc = {}
|
||||
|
||||
if descfile == '':
|
||||
return
|
||||
|
||||
try:
|
||||
d = open(descfile, 'r')
|
||||
print('Reading descriptions...')
|
||||
except (IOError):
|
||||
with open(descfile, 'r') as d:
|
||||
print('Reading descriptions...')
|
||||
for l in d:
|
||||
bits = l.split()
|
||||
try:
|
||||
grp = bits[0]
|
||||
dsc = ' '.join(bits[1:])
|
||||
if len(dsc) > 1:
|
||||
desc[grp] = dsc
|
||||
except IndexError:
|
||||
pass
|
||||
except IOError:
|
||||
print('Failed to open description file ' + descfile)
|
||||
return
|
||||
l = d.readline()
|
||||
while l != '':
|
||||
bits = string.split(l)
|
||||
try:
|
||||
grp = bits[0]
|
||||
dsc = string.join(bits[1:])
|
||||
if len(dsc)>1:
|
||||
desc[grp] = dsc
|
||||
except (IndexError):
|
||||
pass
|
||||
l = d.readline()
|
||||
|
||||
# Check that ouput directory exists, ------------------------------
|
||||
# and offer to create it if not
|
||||
|
||||
def checkopdir(pagedir):
|
||||
if not os.path.isdir(pagedir):
|
||||
print('Directory '+pagedir+' does not exist.')
|
||||
print('Directory %s does not exist.' % pagedir)
|
||||
print('Shall I create it for you? (y/n)')
|
||||
if sys.stdin.readline()[0] == 'y':
|
||||
try:
|
||||
os.mkdir(pagedir,0o777)
|
||||
os.mkdir(pagedir, 0o777)
|
||||
except:
|
||||
print('Sorry - failed!')
|
||||
sys.exit(1)
|
||||
|
@ -257,23 +258,21 @@ def readlocallist(treefile):
|
|||
print('If this is the first time you have run newslist, then')
|
||||
print('use the -a option to create it.')
|
||||
sys.exit(1)
|
||||
treedate = '%02d%02d%02d' % (treetime[0] % 100 ,treetime[1], treetime[2])
|
||||
treedate = '%02d%02d%02d' % (treetime[0] % 100, treetime[1], treetime[2])
|
||||
try:
|
||||
dump = open(treefile,'r')
|
||||
tree = marshal.load(dump)
|
||||
dump.close()
|
||||
except (IOError):
|
||||
with open(treefile, 'rb') as dump:
|
||||
tree = marshal.load(dump)
|
||||
except IOError:
|
||||
print('Cannot open local group list ' + treefile)
|
||||
return (tree, treedate)
|
||||
|
||||
def writelocallist(treefile, tree):
|
||||
try:
|
||||
dump = open(treefile,'w')
|
||||
groups = marshal.dump(tree,dump)
|
||||
dump.close()
|
||||
print('Saved list to '+treefile+'\n')
|
||||
with open(treefile, 'wb') as dump:
|
||||
groups = marshal.dump(tree, dump)
|
||||
print('Saved list to %s\n' % treefile)
|
||||
except:
|
||||
print('Sorry - failed to write to local group cache '+treefile)
|
||||
print('Sorry - failed to write to local group cache', treefile)
|
||||
print('Does it (or its directory) have the correct permissions?')
|
||||
sys.exit(1)
|
||||
|
||||
|
@ -281,18 +280,18 @@ def writelocallist(treefile, tree):
|
|||
|
||||
def getallgroups(server):
|
||||
print('Getting list of all groups...')
|
||||
treedate='010101'
|
||||
treedate = '010101'
|
||||
info = server.list()[1]
|
||||
groups = []
|
||||
print('Processing...')
|
||||
if skipempty:
|
||||
print('\nIgnoring following empty groups:')
|
||||
for i in info:
|
||||
grpname = string.split(i[0])[0]
|
||||
if skipempty and string.atoi(i[1]) < string.atoi(i[2]):
|
||||
print(grpname+' ', end=' ')
|
||||
grpname = i[0].split()[0]
|
||||
if skipempty and int(i[1]) < int(i[2]):
|
||||
print(grpname.decode() + ' ', end=' ')
|
||||
else:
|
||||
groups.append(grpname)
|
||||
groups.append(grpname.decode())
|
||||
print('\n')
|
||||
if skipempty:
|
||||
print('(End of empty groups)')
|
||||
|
@ -301,42 +300,39 @@ def getallgroups(server):
|
|||
# Return list of new groups on server -----------------------------
|
||||
|
||||
def getnewgroups(server, treedate):
|
||||
print('Getting list of new groups since start of '+treedate+'...', end=' ')
|
||||
info = server.newgroups(treedate,'000001')[1]
|
||||
print('Getting list of new groups since start of %s...' % treedate, end=' ')
|
||||
info = server.newgroups(treedate, '000001')[1]
|
||||
print('got %d.' % len(info))
|
||||
print('Processing...', end=' ')
|
||||
groups = []
|
||||
for i in info:
|
||||
grpname = string.split(i)[0]
|
||||
groups.append(grpname)
|
||||
grpname = i.split()[0]
|
||||
groups.append(grpname.decode())
|
||||
print('Done')
|
||||
return groups
|
||||
|
||||
# Now the main program --------------------------------------------
|
||||
|
||||
def main():
|
||||
global desc
|
||||
|
||||
tree={}
|
||||
tree = {}
|
||||
|
||||
# Check that the output directory exists
|
||||
checkopdir(pagedir)
|
||||
|
||||
try:
|
||||
print('Connecting to '+newshost+'...')
|
||||
print('Connecting to %s...' % newshost)
|
||||
if sys.version[0] == '0':
|
||||
s = NNTP.init(newshost)
|
||||
else:
|
||||
s = NNTP(newshost)
|
||||
connected = 1
|
||||
connected = True
|
||||
except (nntplib.error_temp, nntplib.error_perm) as x:
|
||||
print('Error connecting to host:', x)
|
||||
print('I\'ll try to use just the local list.')
|
||||
connected = 0
|
||||
connected = False
|
||||
|
||||
# If -a is specified, read the full list of groups from server
|
||||
if connected and len(sys.argv) > 1 and sys.argv[1] == '-a':
|
||||
|
||||
groups = getallgroups(s)
|
||||
|
||||
# Otherwise just read the local file and then add
|
||||
|
|
|
@ -12,7 +12,7 @@ import sys
|
|||
|
||||
def main():
|
||||
k, a, b, a1, b1 = 2, 4, 1, 12, 4
|
||||
while 1:
|
||||
while True:
|
||||
# Next approximation
|
||||
p, q, k = k*k, 2*k+1, k+1
|
||||
a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
|
||||
|
@ -25,7 +25,6 @@ def main():
|
|||
|
||||
def output(d):
|
||||
# Use write() to avoid spaces between the digits
|
||||
# Use str() to avoid the 'L'
|
||||
sys.stdout.write(str(d))
|
||||
# Flush so the output is seen immediately
|
||||
sys.stdout.flush()
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
# - except for -n/-p, run directly from the file if at all possible
|
||||
|
||||
import sys
|
||||
import string
|
||||
import getopt
|
||||
|
||||
FS = ''
|
||||
|
@ -36,7 +35,7 @@ PFLAG = 0
|
|||
try:
|
||||
optlist, ARGS = getopt.getopt(sys.argv[1:], 'acde:F:np')
|
||||
except getopt.error as msg:
|
||||
sys.stderr.write(sys.argv[0] + ': ' + msg + '\n')
|
||||
sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
|
||||
sys.exit(2)
|
||||
|
||||
for option, optarg in optlist:
|
||||
|
@ -47,7 +46,7 @@ for option, optarg in optlist:
|
|||
elif option == '-d':
|
||||
DFLAG = 1
|
||||
elif option == '-e':
|
||||
for line in string.splitfields(optarg, '\n'):
|
||||
for line in optarg.split('\n'):
|
||||
SCRIPT.append(line)
|
||||
elif option == '-F':
|
||||
FS = optarg
|
||||
|
@ -81,31 +80,31 @@ if CFLAG:
|
|||
elif NFLAG:
|
||||
# Note that it is on purpose that AFLAG and PFLAG are
|
||||
# tested dynamically each time through the loop
|
||||
prologue = [ \
|
||||
'LINECOUNT = 0', \
|
||||
'for FILE in ARGS:', \
|
||||
' \tif FILE == \'-\':', \
|
||||
' \t \tFP = sys.stdin', \
|
||||
' \telse:', \
|
||||
' \t \tFP = open(FILE, \'r\')', \
|
||||
' \tLINENO = 0', \
|
||||
' \twhile 1:', \
|
||||
' \t \tLINE = FP.readline()', \
|
||||
' \t \tif not LINE: break', \
|
||||
' \t \tLINENO = LINENO + 1', \
|
||||
' \t \tLINECOUNT = LINECOUNT + 1', \
|
||||
' \t \tL = LINE[:-1]', \
|
||||
' \t \taflag = AFLAG', \
|
||||
' \t \tif aflag:', \
|
||||
' \t \t \tif FS: F = string.splitfields(L, FS)', \
|
||||
' \t \t \telse: F = string.split(L)' \
|
||||
prologue = [
|
||||
'LINECOUNT = 0',
|
||||
'for FILE in ARGS:',
|
||||
' \tif FILE == \'-\':',
|
||||
' \t \tFP = sys.stdin',
|
||||
' \telse:',
|
||||
' \t \tFP = open(FILE, \'r\')',
|
||||
' \tLINENO = 0',
|
||||
' \twhile 1:',
|
||||
' \t \tLINE = FP.readline()',
|
||||
' \t \tif not LINE: break',
|
||||
' \t \tLINENO = LINENO + 1',
|
||||
' \t \tLINECOUNT = LINECOUNT + 1',
|
||||
' \t \tL = LINE[:-1]',
|
||||
' \t \taflag = AFLAG',
|
||||
' \t \tif aflag:',
|
||||
' \t \t \tif FS: F = L.split(FS)',
|
||||
' \t \t \telse: F = L.split()'
|
||||
]
|
||||
epilogue = [ \
|
||||
' \t \tif not PFLAG: continue', \
|
||||
' \t \tif aflag:', \
|
||||
' \t \t \tif FS: print string.joinfields(F, FS)', \
|
||||
' \t \t \telse: print string.join(F)', \
|
||||
' \t \telse: print L', \
|
||||
epilogue = [
|
||||
' \t \tif not PFLAG: continue',
|
||||
' \t \tif aflag:',
|
||||
' \t \t \tif FS: print(FS.join(F))',
|
||||
' \t \t \telse: print(\' \'.join(F))',
|
||||
' \t \telse: print(L)',
|
||||
]
|
||||
else:
|
||||
prologue = ['if 1:']
|
||||
|
@ -114,18 +113,13 @@ else:
|
|||
# Note that we indent using tabs only, so that any indentation style
|
||||
# used in 'command' will come out right after re-indentation.
|
||||
|
||||
program = string.joinfields(prologue, '\n') + '\n'
|
||||
program = '\n'.join(prologue) + '\n'
|
||||
for line in SCRIPT:
|
||||
program = program + (' \t \t' + line + '\n')
|
||||
program = program + (string.joinfields(epilogue, '\n') + '\n')
|
||||
program += ' \t \t' + line + '\n'
|
||||
program += '\n'.join(epilogue) + '\n'
|
||||
|
||||
import tempfile
|
||||
fp = tempfile.NamedTemporaryFile()
|
||||
fp.write(program)
|
||||
fp.flush()
|
||||
script = open(tfn).read()
|
||||
if DFLAG:
|
||||
import pdb
|
||||
pdb.run(script)
|
||||
pdb.run(program)
|
||||
else:
|
||||
exec(script)
|
||||
exec(program)
|
||||
|
|
|
@ -19,8 +19,8 @@ class Queens:
|
|||
|
||||
def reset(self):
|
||||
n = self.n
|
||||
self.y = [None]*n # Where is the queen in column x
|
||||
self.row = [0]*n # Is row[y] safe?
|
||||
self.y = [None] * n # Where is the queen in column x
|
||||
self.row = [0] * n # Is row[y] safe?
|
||||
self.up = [0] * (2*n-1) # Is upward diagonal[x-y] safe?
|
||||
self.down = [0] * (2*n-1) # Is downward diagonal[x+y] safe?
|
||||
self.nfound = 0 # Instrumentation
|
||||
|
@ -50,7 +50,7 @@ class Queens:
|
|||
self.up[x-y] = 0
|
||||
self.down[x+y] = 0
|
||||
|
||||
silent = 0 # If set, count solutions only
|
||||
silent = 0 # If true, count solutions only
|
||||
|
||||
def display(self):
|
||||
self.nfound = self.nfound + 1
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# script.py -- Make typescript of terminal session.
|
||||
# Usage:
|
||||
# -a Append to typescript.
|
||||
|
@ -6,28 +7,36 @@
|
|||
# Author: Steen Lumholt.
|
||||
|
||||
|
||||
import os, time, sys
|
||||
import os, time, sys, getopt
|
||||
import pty
|
||||
|
||||
def read(fd):
|
||||
data = os.read(fd, 1024)
|
||||
file.write(data)
|
||||
script.write(data)
|
||||
return data
|
||||
|
||||
shell = 'sh'
|
||||
filename = 'typescript'
|
||||
mode = 'w'
|
||||
mode = 'wb'
|
||||
if 'SHELL' in os.environ:
|
||||
shell = os.environ['SHELL']
|
||||
if '-a' in sys.argv:
|
||||
mode = 'a'
|
||||
if '-p' in sys.argv:
|
||||
shell = 'python'
|
||||
|
||||
file = open(filename, mode)
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'ap')
|
||||
except getopt.error as msg:
|
||||
print('%s: %s' % (sys.argv[0], msg))
|
||||
sys.exit(2)
|
||||
|
||||
for o, a in opts:
|
||||
if o == '-a':
|
||||
mode = 'ab'
|
||||
elif o == '-p':
|
||||
shell = 'python'
|
||||
|
||||
script = open(filename, mode)
|
||||
|
||||
sys.stdout.write('Script started, file is %s\n' % filename)
|
||||
file.write('Script started on %s\n' % time.ctime(time.time()))
|
||||
script.write(('Script started on %s\n' % time.ctime(time.time())).encode())
|
||||
pty.spawn(shell, read)
|
||||
file.write('Script done on %s\n' % time.ctime(time.time()))
|
||||
script.write(('Script done on %s\n' % time.ctime(time.time())).encode())
|
||||
sys.stdout.write('Script done, file is %s\n' % filename)
|
||||
|
|
|
@ -9,35 +9,27 @@ import sys
|
|||
import time
|
||||
import calendar
|
||||
|
||||
def raw_input(prompt):
|
||||
sys.stdout.write(prompt)
|
||||
sys.stdout.flush()
|
||||
return sys.stdin.readline()
|
||||
|
||||
def main():
|
||||
# Note that the range checks below also check for bad types,
|
||||
# e.g. 3.14 or (). However syntactically invalid replies
|
||||
# will raise an exception.
|
||||
if sys.argv[1:]:
|
||||
year = int(sys.argv[1])
|
||||
else:
|
||||
year = int(input('In which year were you born? '))
|
||||
if 0<=year<100:
|
||||
if 0 <= year < 100:
|
||||
print("I'll assume that by", year, end=' ')
|
||||
year = year + 1900
|
||||
print('you mean', year, 'and not the early Christian era')
|
||||
elif not (1850<=year<=2002):
|
||||
elif not (1850 <= year <= time.localtime()[0]):
|
||||
print("It's hard to believe you were born in", year)
|
||||
return
|
||||
#
|
||||
|
||||
if sys.argv[2:]:
|
||||
month = int(sys.argv[2])
|
||||
else:
|
||||
month = int(input('And in which month? (1-12) '))
|
||||
if not (1<=month<=12):
|
||||
if not (1 <= month <= 12):
|
||||
print('There is no month numbered', month)
|
||||
return
|
||||
#
|
||||
|
||||
if sys.argv[3:]:
|
||||
day = int(sys.argv[3])
|
||||
else:
|
||||
|
@ -46,36 +38,36 @@ def main():
|
|||
maxday = 29
|
||||
else:
|
||||
maxday = calendar.mdays[month]
|
||||
if not (1<=day<=maxday):
|
||||
if not (1 <= day <= maxday):
|
||||
print('There are no', day, 'days in that month!')
|
||||
return
|
||||
#
|
||||
|
||||
bdaytuple = (year, month, day)
|
||||
bdaydate = mkdate(bdaytuple)
|
||||
print('You were born on', format(bdaytuple))
|
||||
#
|
||||
|
||||
todaytuple = time.localtime()[:3]
|
||||
todaydate = mkdate(todaytuple)
|
||||
print('Today is', format(todaytuple))
|
||||
#
|
||||
|
||||
if bdaytuple > todaytuple:
|
||||
print('You are a time traveler. Go back to the future!')
|
||||
return
|
||||
#
|
||||
|
||||
if bdaytuple == todaytuple:
|
||||
print('You were born today. Have a nice life!')
|
||||
return
|
||||
#
|
||||
|
||||
days = todaydate - bdaydate
|
||||
print('You have lived', days, 'days')
|
||||
#
|
||||
|
||||
age = 0
|
||||
for y in range(year, todaytuple[0] + 1):
|
||||
if bdaytuple < (y, month, day) <= todaytuple:
|
||||
age = age + 1
|
||||
#
|
||||
|
||||
print('You are', age, 'years old')
|
||||
#
|
||||
|
||||
if todaytuple[1:] == bdaytuple[1:]:
|
||||
print('Congratulations! Today is your', nth(age), 'birthday')
|
||||
print('Yesterday was your', end=' ')
|
||||
|
@ -83,8 +75,8 @@ def main():
|
|||
print('Today is your', end=' ')
|
||||
print(nth(days - age), 'unbirthday')
|
||||
|
||||
def format(xxx_todo_changeme):
|
||||
(year, month, day) = xxx_todo_changeme
|
||||
def format(date):
|
||||
(year, month, day) = date
|
||||
return '%d %s %d' % (day, calendar.month_name[month], year)
|
||||
|
||||
def nth(n):
|
||||
|
@ -93,12 +85,12 @@ def nth(n):
|
|||
if n == 3: return '3rd'
|
||||
return '%dth' % n
|
||||
|
||||
def mkdate(xxx_todo_changeme1):
|
||||
# Januari 1st, in 0 A.D. is arbitrarily defined to be day 1,
|
||||
def mkdate(date):
|
||||
# January 1st, in 0 A.D. is arbitrarily defined to be day 1,
|
||||
# even though that day never actually existed and the calendar
|
||||
# was different then...
|
||||
(year, month, day) = xxx_todo_changeme1
|
||||
days = year*365 # years, roughly
|
||||
(year, month, day) = date
|
||||
days = year*365 # years, roughly
|
||||
days = days + (year+3)//4 # plus leap years, roughly
|
||||
days = days - (year+99)//100 # minus non-leap years every century
|
||||
days = days + (year+399)//400 # plus leap years every 4 centirues
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
"""
|
||||
A simple demo that reads in an XML document and displays the number of
|
||||
elements and attributes as well as a tally of elements and attributes by name.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
|
||||
from xml.sax import make_parser, handler
|
||||
|
||||
|
@ -7,16 +13,16 @@ class FancyCounter(handler.ContentHandler):
|
|||
def __init__(self):
|
||||
self._elems = 0
|
||||
self._attrs = 0
|
||||
self._elem_types = {}
|
||||
self._attr_types = {}
|
||||
self._elem_types = defaultdict(int)
|
||||
self._attr_types = defaultdict(int)
|
||||
|
||||
def startElement(self, name, attrs):
|
||||
self._elems = self._elems + 1
|
||||
self._attrs = self._attrs + len(attrs)
|
||||
self._elem_types[name] = self._elem_types.get(name, 0) + 1
|
||||
self._elems += 1
|
||||
self._attrs += len(attrs)
|
||||
self._elem_types[name] += 1
|
||||
|
||||
for name in attrs.keys():
|
||||
self._attr_types[name] = self._attr_types.get(name, 0) + 1
|
||||
self._attr_types[name] += 1
|
||||
|
||||
def endDocument(self):
|
||||
print("There were", self._elems, "elements.")
|
||||
|
@ -30,7 +36,7 @@ class FancyCounter(handler.ContentHandler):
|
|||
for pair in self._attr_types.items():
|
||||
print("%20s %d" % pair)
|
||||
|
||||
|
||||
parser = make_parser()
|
||||
parser.setContentHandler(FancyCounter())
|
||||
parser.parse(sys.argv[1])
|
||||
if __name__ == '__main__':
|
||||
parser = make_parser()
|
||||
parser.setContentHandler(FancyCounter())
|
||||
parser.parse(sys.argv[1])
|
||||
|
|
|
@ -3,7 +3,7 @@ A simple demo that reads in an XML document and spits out an equivalent,
|
|||
but not necessarily identical, document.
|
||||
"""
|
||||
|
||||
import sys, string
|
||||
import sys
|
||||
|
||||
from xml.sax import saxutils, handler, make_parser
|
||||
|
||||
|
@ -11,7 +11,7 @@ from xml.sax import saxutils, handler, make_parser
|
|||
|
||||
class ContentGenerator(handler.ContentHandler):
|
||||
|
||||
def __init__(self, out = sys.stdout):
|
||||
def __init__(self, out=sys.stdout):
|
||||
handler.ContentHandler.__init__(self)
|
||||
self._out = out
|
||||
|
||||
|
@ -40,6 +40,7 @@ class ContentGenerator(handler.ContentHandler):
|
|||
|
||||
# --- The main program
|
||||
|
||||
parser = make_parser()
|
||||
parser.setContentHandler(ContentGenerator())
|
||||
parser.parse(sys.argv[1])
|
||||
if __name__ == '__main__':
|
||||
parser = make_parser()
|
||||
parser.setContentHandler(ContentGenerator())
|
||||
parser.parse(sys.argv[1])
|
||||
|
|
|
@ -1,45 +1,50 @@
|
|||
"""
|
||||
A demo that reads in an RSS XML document and emits an HTML file containing
|
||||
a list of the individual items in the feed.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import codecs
|
||||
|
||||
from xml.sax import make_parser, handler
|
||||
|
||||
# --- Templates
|
||||
|
||||
top = \
|
||||
"""
|
||||
top = """\
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>%s</TITLE>
|
||||
</HEAD>
|
||||
<html>
|
||||
<head>
|
||||
<title>%s</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
|
||||
<BODY>
|
||||
<H1>%s</H1>
|
||||
<body>
|
||||
<h1>%s</h1>
|
||||
"""
|
||||
|
||||
bottom = \
|
||||
"""
|
||||
bottom = """
|
||||
</ul>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
Converted to HTML by sax_rss2html.py.
|
||||
</ADDRESS>
|
||||
<hr>
|
||||
<address>
|
||||
Converted to HTML by rss2html.py.
|
||||
</address>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
# --- The ContentHandler
|
||||
|
||||
class RSSHandler(handler.ContentHandler):
|
||||
|
||||
def __init__(self, out = sys.stdout):
|
||||
def __init__(self, out=sys.stdout):
|
||||
handler.ContentHandler.__init__(self)
|
||||
self._out = out
|
||||
|
||||
self._text = ""
|
||||
self._parent = None
|
||||
self._list_started = 0
|
||||
self._list_started = False
|
||||
self._title = None
|
||||
self._link = None
|
||||
self._descr = ""
|
||||
|
@ -69,7 +74,7 @@ class RSSHandler(handler.ContentHandler):
|
|||
elif name == "item":
|
||||
if not self._list_started:
|
||||
self._out.write("<ul>\n")
|
||||
self._list_started = 1
|
||||
self._list_started = True
|
||||
|
||||
self._out.write(' <li><a href="%s">%s</a> %s\n' %
|
||||
(self._link, self._title, self._descr))
|
||||
|
@ -86,6 +91,7 @@ class RSSHandler(handler.ContentHandler):
|
|||
|
||||
# --- Main program
|
||||
|
||||
parser = make_parser()
|
||||
parser.setContentHandler(RSSHandler())
|
||||
parser.parse(sys.argv[1])
|
||||
if __name__ == '__main__':
|
||||
parser = make_parser()
|
||||
parser.setContentHandler(RSSHandler())
|
||||
parser.parse(sys.argv[1])
|
||||
|
|
|
@ -231,9 +231,11 @@ RawConfigParser Objects
|
|||
.. method:: RawConfigParser.readfp(fp, filename=None)
|
||||
|
||||
Read and parse configuration data from the file or file-like object in *fp*
|
||||
(only the :meth:`readline` method is used). If *filename* is omitted and *fp*
|
||||
has a :attr:`name` attribute, that is used for *filename*; the default is
|
||||
``<???>``.
|
||||
(only the :meth:`readline` method is used). The file-like object must
|
||||
operate in text mode, i.e. return strings from :meth:`readline`.
|
||||
|
||||
If *filename* is omitted and *fp* has a :attr:`name` attribute, that is used
|
||||
for *filename*; the default is ``<???>``.
|
||||
|
||||
|
||||
.. method:: RawConfigParser.get(section, option)
|
||||
|
@ -279,8 +281,9 @@ RawConfigParser Objects
|
|||
|
||||
.. method:: RawConfigParser.write(fileobject)
|
||||
|
||||
Write a representation of the configuration to the specified file object. This
|
||||
representation can be parsed by a future :meth:`read` call.
|
||||
Write a representation of the configuration to the specified file object,
|
||||
which must be opened in text mode (accepting strings). This representation
|
||||
can be parsed by a future :meth:`read` call.
|
||||
|
||||
|
||||
.. method:: RawConfigParser.remove_option(section, option)
|
||||
|
@ -370,7 +373,7 @@ An example of writing to a configuration file::
|
|||
config.set('Section1', 'foo', '%(bar)s is %(baz)s!')
|
||||
|
||||
# Writing our configuration file to 'example.cfg'
|
||||
with open('example.cfg', 'wb') as configfile:
|
||||
with open('example.cfg', 'w') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
An example of reading the configuration file again::
|
||||
|
|
|
@ -4,21 +4,25 @@
|
|||
.. module:: copy
|
||||
:synopsis: Shallow and deep copy operations.
|
||||
|
||||
|
||||
.. index::
|
||||
single: copy() (in copy)
|
||||
single: deepcopy() (in copy)
|
||||
|
||||
This module provides generic (shallow and deep) copying operations.
|
||||
|
||||
Interface summary::
|
||||
|
||||
import copy
|
||||
Interface summary:
|
||||
|
||||
x = copy.copy(y) # make a shallow copy of y
|
||||
x = copy.deepcopy(y) # make a deep copy of y
|
||||
.. function:: copy(x)
|
||||
|
||||
Return a shallow copy of *x*.
|
||||
|
||||
|
||||
.. function:: deepcopy(x)
|
||||
|
||||
Return a deep copy of *x*.
|
||||
|
||||
|
||||
.. exception:: error
|
||||
|
||||
Raised for module specific errors.
|
||||
|
||||
For module specific errors, :exc:`copy.error` is raised.
|
||||
|
||||
The difference between shallow and deep copying is only relevant for compound
|
||||
objects (objects that contain other objects, like lists or class instances):
|
||||
|
|
|
@ -36,12 +36,14 @@ supports a substantially wider range of objects than marshal.
|
|||
|
||||
Not all Python object types are supported; in general, only objects whose value
|
||||
is independent from a particular invocation of Python can be written and read by
|
||||
this module. The following types are supported: ``None``, integers,
|
||||
floating point numbers, strings, bytes, bytearrays, tuples, lists, sets,
|
||||
dictionaries, and code objects, where it should be understood that tuples, lists
|
||||
and dictionaries are only supported as long as the values contained therein are
|
||||
themselves supported; and recursive lists and dictionaries should not be written
|
||||
(they will cause infinite loops).
|
||||
this module. The following types are supported: booleans, integers, floating
|
||||
point numbers, complex numbers, strings, bytes, bytearrays, tuples, lists, sets,
|
||||
frozensets, dictionaries, and code objects, where it should be understood that
|
||||
tuples, lists, sets, frozensets and dictionaries are only supported as long as
|
||||
the values contained therein are themselves supported; and recursive lists, sets
|
||||
and dictionaries should not be written (they will cause infinite loops). The
|
||||
singletons :const:`None`, :const:`Ellipsis` and :exc:`StopIteration` can also be
|
||||
marshalled and unmarshalled.
|
||||
|
||||
There are functions that read/write files as well as functions operating on
|
||||
strings.
|
||||
|
|
|
@ -227,7 +227,8 @@ The :mod:`urllib.parse` module defines the following functions:
|
|||
.. function:: quote(string, safe='/', encoding=None, errors=None)
|
||||
|
||||
Replace special characters in *string* using the ``%xx`` escape. Letters,
|
||||
digits, and the characters ``'_.-'`` are never quoted. The optional *safe*
|
||||
digits, and the characters ``'_.-'`` are never quoted. By default, this
|
||||
function is intended for quoting the path section of URL. The optional *safe*
|
||||
parameter specifies additional ASCII characters that should not be quoted
|
||||
--- its default value is ``'/'``.
|
||||
|
||||
|
|
|
@ -666,7 +666,7 @@ Modules
|
|||
of the shared library file.
|
||||
|
||||
Custom classes
|
||||
Custon class types are typically created by class definitions (see section
|
||||
Custom class types are typically created by class definitions (see section
|
||||
:ref:`class`). A class has a namespace implemented by a dictionary object.
|
||||
Class attribute references are translated to lookups in this dictionary, e.g.,
|
||||
``C.x`` is translated to ``C.__dict__["x"]`` (although there are a number of
|
||||
|
|
|
@ -208,7 +208,9 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
|||
"""Custom displayhook for the exec in default(), which prevents
|
||||
assignment of the _ variable in the builtins.
|
||||
"""
|
||||
print(repr(obj))
|
||||
# reproduce the behavior of the standard displayhook, not printing None
|
||||
if obj is not None:
|
||||
print(repr(obj))
|
||||
|
||||
def default(self, line):
|
||||
if line[:1] == '!': line = line[1:]
|
||||
|
|
12
Lib/pydoc.py
12
Lib/pydoc.py
|
@ -1557,7 +1557,7 @@ class Helper:
|
|||
'global': ('global', 'NAMESPACES'),
|
||||
'if': ('if', 'TRUTHVALUE'),
|
||||
'import': ('import', 'MODULES'),
|
||||
'in': ('in', 'SEQUENCEMETHODS2'),
|
||||
'in': ('in', 'SEQUENCEMETHODS'),
|
||||
'is': 'COMPARISON',
|
||||
'lambda': ('lambda', 'FUNCTIONS'),
|
||||
'not': 'BOOLEAN',
|
||||
|
@ -1643,12 +1643,12 @@ class Helper:
|
|||
'PRECEDENCE': 'EXPRESSIONS',
|
||||
'OBJECTS': ('objects', 'TYPES'),
|
||||
'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS '
|
||||
'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS '
|
||||
'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),
|
||||
'CALLABLEMETHODS SEQUENCEMETHODS MAPPINGMETHODS '
|
||||
'NUMBERMETHODS CLASSES'),
|
||||
'BASICMETHODS': ('customization', 'hash repr str SPECIALMETHODS'),
|
||||
'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),
|
||||
'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),
|
||||
'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 '
|
||||
'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS '
|
||||
'SPECIALMETHODS'),
|
||||
'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'),
|
||||
'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT '
|
||||
|
@ -1672,8 +1672,8 @@ class Helper:
|
|||
'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'),
|
||||
'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'),
|
||||
'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr ATTRIBUTEMETHODS'),
|
||||
'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'),
|
||||
'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'),
|
||||
'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS'),
|
||||
'SLICINGS': ('slicings', 'SEQUENCEMETHODS'),
|
||||
'CALLS': ('calls', 'EXPRESSIONS'),
|
||||
'POWER': ('power', 'EXPRESSIONS'),
|
||||
'UNARY': ('unary', 'EXPRESSIONS'),
|
||||
|
|
|
@ -56,8 +56,29 @@ class FunctionPropertiesTest(FuncAttrsTest):
|
|||
self.assertEqual(test(), 3) # self.b always returns 3, arbitrarily
|
||||
|
||||
def test___globals__(self):
|
||||
self.assertEqual(self.b.__globals__, globals())
|
||||
self.cannot_set_attr(self.b, '__globals__', 2, (AttributeError, TypeError))
|
||||
self.assertIs(self.b.__globals__, globals())
|
||||
self.cannot_set_attr(self.b, '__globals__', 2,
|
||||
(AttributeError, TypeError))
|
||||
|
||||
def test___closure__(self):
|
||||
a = 12
|
||||
def f(): print(a)
|
||||
c = f.__closure__
|
||||
self.assertTrue(isinstance(c, tuple))
|
||||
self.assertEqual(len(c), 1)
|
||||
# don't have a type object handy
|
||||
self.assertEqual(c[0].__class__.__name__, "cell")
|
||||
self.cannot_set_attr(f, "__closure__", c, AttributeError)
|
||||
|
||||
def test_empty_cell(self):
|
||||
def f(): print(a)
|
||||
try:
|
||||
f.__closure__[0].cell_contents
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("shouldn't be able to read an empty cell")
|
||||
a = 12
|
||||
|
||||
def test___name__(self):
|
||||
self.assertEqual(self.b.__name__, 'b')
|
||||
|
@ -90,16 +111,20 @@ class FunctionPropertiesTest(FuncAttrsTest):
|
|||
self.assertEqual(c.__code__, d.__code__)
|
||||
self.assertEqual(c(), 7)
|
||||
# self.assertEqual(d(), 7)
|
||||
try: b.__code__ = c.__code__
|
||||
except ValueError: pass
|
||||
else: self.fail(
|
||||
"__code__ with different numbers of free vars should not be "
|
||||
"possible")
|
||||
try: e.__code__ = d.__code__
|
||||
except ValueError: pass
|
||||
else: self.fail(
|
||||
"__code__ with different numbers of free vars should not be "
|
||||
"possible")
|
||||
try:
|
||||
b.__code__ = c.__code__
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("__code__ with different numbers of free vars should "
|
||||
"not be possible")
|
||||
try:
|
||||
e.__code__ = d.__code__
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("__code__ with different numbers of free vars should "
|
||||
"not be possible")
|
||||
|
||||
def test_blank_func_defaults(self):
|
||||
self.assertEqual(self.b.__defaults__, None)
|
||||
|
@ -120,13 +145,16 @@ class FunctionPropertiesTest(FuncAttrsTest):
|
|||
self.assertEqual(first_func(3, 5), 8)
|
||||
del second_func.__defaults__
|
||||
self.assertEqual(second_func.__defaults__, None)
|
||||
try: second_func()
|
||||
except TypeError: pass
|
||||
else: self.fail(
|
||||
"func_defaults does not update; deleting it does not remove "
|
||||
"requirement")
|
||||
try:
|
||||
second_func()
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("__defaults__ does not update; deleting it does not "
|
||||
"remove requirement")
|
||||
|
||||
class ImplicitReferencesTest(FuncAttrsTest):
|
||||
|
||||
class InstancemethodAttrTest(FuncAttrsTest):
|
||||
|
||||
def test___class__(self):
|
||||
self.assertEqual(self.fi.a.__self__.__class__, self.F)
|
||||
|
@ -146,31 +174,45 @@ class ImplicitReferencesTest(FuncAttrsTest):
|
|||
self.fi.id = types.MethodType(id, self.fi)
|
||||
self.assertEqual(self.fi.id(), id(self.fi))
|
||||
# Test usage
|
||||
try: self.fi.id.unknown_attr
|
||||
except AttributeError: pass
|
||||
else: self.fail("using unknown attributes should raise AttributeError")
|
||||
try:
|
||||
self.fi.id.unknown_attr
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("using unknown attributes should raise AttributeError")
|
||||
# Test assignment and deletion
|
||||
self.cannot_set_attr(self.fi.id, 'unknown_attr', 2, AttributeError)
|
||||
|
||||
|
||||
class ArbitraryFunctionAttrTest(FuncAttrsTest):
|
||||
def test_set_attr(self):
|
||||
self.b.known_attr = 7
|
||||
self.assertEqual(self.b.known_attr, 7)
|
||||
try: self.fi.a.known_attr = 7
|
||||
except AttributeError: pass
|
||||
else: self.fail("setting attributes on methods should raise error")
|
||||
try:
|
||||
self.fi.a.known_attr = 7
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("setting attributes on methods should raise error")
|
||||
|
||||
def test_delete_unknown_attr(self):
|
||||
try: del self.b.unknown_attr
|
||||
except AttributeError: pass
|
||||
else: self.fail("deleting unknown attribute should raise TypeError")
|
||||
try:
|
||||
del self.b.unknown_attr
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("deleting unknown attribute should raise TypeError")
|
||||
|
||||
def test_unset_attr(self):
|
||||
for func in [self.b, self.fi.a]:
|
||||
try: func.non_existent_attr
|
||||
except AttributeError: pass
|
||||
else: self.fail("using unknown attributes should raise "
|
||||
"AttributeError")
|
||||
try:
|
||||
func.non_existent_attr
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("using unknown attributes should raise "
|
||||
"AttributeError")
|
||||
|
||||
|
||||
class FunctionDictsTest(FuncAttrsTest):
|
||||
def test_setting_dict_to_invalid(self):
|
||||
|
@ -183,11 +225,11 @@ class FunctionDictsTest(FuncAttrsTest):
|
|||
d = {'known_attr': 7}
|
||||
self.b.__dict__ = d
|
||||
# Test assignment
|
||||
self.assertEqual(d, self.b.__dict__)
|
||||
self.assertIs(d, self.b.__dict__)
|
||||
# ... and on all the different ways of referencing the method's func
|
||||
self.F.a.__dict__ = d
|
||||
self.assertEqual(d, self.fi.a.__func__.__dict__)
|
||||
self.assertEqual(d, self.fi.a.__dict__)
|
||||
self.assertIs(d, self.fi.a.__func__.__dict__)
|
||||
self.assertIs(d, self.fi.a.__dict__)
|
||||
# Test value
|
||||
self.assertEqual(self.b.known_attr, 7)
|
||||
self.assertEqual(self.b.__dict__['known_attr'], 7)
|
||||
|
@ -196,9 +238,12 @@ class FunctionDictsTest(FuncAttrsTest):
|
|||
self.assertEqual(self.fi.a.known_attr, 7)
|
||||
|
||||
def test_delete___dict__(self):
|
||||
try: del self.b.__dict__
|
||||
except TypeError: pass
|
||||
else: self.fail("deleting function dictionary should raise TypeError")
|
||||
try:
|
||||
del self.b.__dict__
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("deleting function dictionary should raise TypeError")
|
||||
|
||||
def test_unassigned_dict(self):
|
||||
self.assertEqual(self.b.__dict__, {})
|
||||
|
@ -209,6 +254,7 @@ class FunctionDictsTest(FuncAttrsTest):
|
|||
d[self.b] = value
|
||||
self.assertEqual(d[self.b], value)
|
||||
|
||||
|
||||
class FunctionDocstringTest(FuncAttrsTest):
|
||||
def test_set_docstring_attr(self):
|
||||
self.assertEqual(self.b.__doc__, None)
|
||||
|
@ -224,6 +270,7 @@ class FunctionDocstringTest(FuncAttrsTest):
|
|||
del self.b.__doc__
|
||||
self.assertEqual(self.b.__doc__, None)
|
||||
|
||||
|
||||
def cell(value):
|
||||
"""Create a cell containing the given value."""
|
||||
def f():
|
||||
|
@ -242,6 +289,7 @@ def empty_cell(empty=True):
|
|||
a = 1729
|
||||
return f.__closure__[0]
|
||||
|
||||
|
||||
class CellTest(unittest.TestCase):
|
||||
def test_comparison(self):
|
||||
# These tests are here simply to exercise the comparison code;
|
||||
|
@ -254,6 +302,7 @@ class CellTest(unittest.TestCase):
|
|||
self.assertTrue(cell(-36) == cell(-36.0))
|
||||
self.assertTrue(cell(True) > empty_cell())
|
||||
|
||||
|
||||
class StaticMethodAttrsTest(unittest.TestCase):
|
||||
def test_func_attribute(self):
|
||||
def f():
|
||||
|
@ -267,7 +316,7 @@ class StaticMethodAttrsTest(unittest.TestCase):
|
|||
|
||||
|
||||
def test_main():
|
||||
support.run_unittest(FunctionPropertiesTest, ImplicitReferencesTest,
|
||||
support.run_unittest(FunctionPropertiesTest, InstancemethodAttrTest,
|
||||
ArbitraryFunctionAttrTest, FunctionDictsTest,
|
||||
FunctionDocstringTest, CellTest,
|
||||
StaticMethodAttrsTest)
|
||||
|
|
|
@ -12,6 +12,49 @@ from test import support
|
|||
from test.test_doctest import _FakeInput
|
||||
|
||||
|
||||
class PdbTestInput(object):
|
||||
"""Context manager that makes testing Pdb in doctests easier."""
|
||||
|
||||
def __init__(self, input):
|
||||
self.input = input
|
||||
|
||||
def __enter__(self):
|
||||
self.real_stdin = sys.stdin
|
||||
sys.stdin = _FakeInput(self.input)
|
||||
|
||||
def __exit__(self, *exc):
|
||||
sys.stdin = self.real_stdin
|
||||
|
||||
|
||||
def test_pdb_displayhook():
|
||||
"""This tests the custom displayhook for pdb.
|
||||
|
||||
>>> def test_function(foo, bar):
|
||||
... import pdb; pdb.Pdb().set_trace()
|
||||
... pass
|
||||
|
||||
>>> with PdbTestInput([
|
||||
... 'foo',
|
||||
... 'bar',
|
||||
... 'for i in range(5): print(i)',
|
||||
... 'continue',
|
||||
... ]):
|
||||
... test_function(1, None)
|
||||
> <doctest test.test_pdb.test_pdb_displayhook[0]>(3)test_function()
|
||||
-> pass
|
||||
(Pdb) foo
|
||||
1
|
||||
(Pdb) bar
|
||||
(Pdb) for i in range(5): print(i)
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
(Pdb) continue
|
||||
"""
|
||||
|
||||
|
||||
def test_pdb_skip_modules():
|
||||
"""This illustrates the simple case of module skipping.
|
||||
|
||||
|
@ -19,16 +62,12 @@ def test_pdb_skip_modules():
|
|||
... import string
|
||||
... import pdb; pdb.Pdb(skip=['stri*']).set_trace()
|
||||
... string.capwords('FOO')
|
||||
>>> real_stdin = sys.stdin
|
||||
>>> sys.stdin = _FakeInput([
|
||||
... 'step',
|
||||
... 'continue',
|
||||
... ])
|
||||
|
||||
>>> try:
|
||||
>>> with PdbTestInput([
|
||||
... 'step',
|
||||
... 'continue',
|
||||
... ]):
|
||||
... skip_module()
|
||||
... finally:
|
||||
... sys.stdin = real_stdin
|
||||
> <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()
|
||||
-> string.capwords('FOO')
|
||||
(Pdb) step
|
||||
|
@ -36,7 +75,7 @@ def test_pdb_skip_modules():
|
|||
> <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()->None
|
||||
-> string.capwords('FOO')
|
||||
(Pdb) continue
|
||||
"""
|
||||
"""
|
||||
|
||||
|
||||
# Module for testing skipping of module that makes a callback
|
||||
|
@ -50,22 +89,19 @@ def test_pdb_skip_modules_with_callback():
|
|||
>>> def skip_module():
|
||||
... def callback():
|
||||
... return None
|
||||
... import pdb;pdb.Pdb(skip=['module_to_skip*']).set_trace()
|
||||
... import pdb; pdb.Pdb(skip=['module_to_skip*']).set_trace()
|
||||
... mod.foo_pony(callback)
|
||||
>>> real_stdin = sys.stdin
|
||||
>>> sys.stdin = _FakeInput([
|
||||
... 'step',
|
||||
... 'step',
|
||||
... 'step',
|
||||
... 'step',
|
||||
... 'step',
|
||||
... 'continue',
|
||||
... ])
|
||||
|
||||
>>> try:
|
||||
>>> with PdbTestInput([
|
||||
... 'step',
|
||||
... 'step',
|
||||
... 'step',
|
||||
... 'step',
|
||||
... 'step',
|
||||
... 'continue',
|
||||
... ]):
|
||||
... skip_module()
|
||||
... finally:
|
||||
... sys.stdin = real_stdin
|
||||
... pass # provides something to "step" to
|
||||
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()
|
||||
-> mod.foo_pony(callback)
|
||||
(Pdb) step
|
||||
|
@ -84,10 +120,10 @@ def test_pdb_skip_modules_with_callback():
|
|||
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()->None
|
||||
-> mod.foo_pony(callback)
|
||||
(Pdb) step
|
||||
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[3]>(4)<module>()
|
||||
-> sys.stdin = real_stdin
|
||||
> <doctest test.test_pdb.test_pdb_skip_modules_with_callback[1]>(10)<module>()
|
||||
-> pass # provides something to "step" to
|
||||
(Pdb) continue
|
||||
"""
|
||||
"""
|
||||
|
||||
|
||||
def test_main():
|
||||
|
|
Loading…
Reference in New Issue