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:
Georg Brandl 2009-10-27 20:19:02 +00:00
parent 7dc008d001
commit 22fff43633
27 changed files with 623 additions and 595 deletions

View File

@ -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

View File

@ -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.")

View File

@ -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()

View File

@ -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:])

View File

@ -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()

View File

@ -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:

View File

@ -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()

View File

@ -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()

128
Demo/scripts/morse.py Executable file
View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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])

View File

@ -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])

View File

@ -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])

View File

@ -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::

View File

@ -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):

View File

@ -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.

View File

@ -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 ``'/'``.

View File

@ -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

View File

@ -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:]

View File

@ -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'),

View File

@ -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)

View File

@ -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():