History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Demo/scripts (23 of 3706 files). Show all

Unified · Split

23 files
  1. sys/src/cmd/python/Demo/scripts/README +23 −0
  2. sys/src/cmd/python/Demo/scripts/beer.py +14 −0
  3. sys/src/cmd/python/Demo/scripts/eqfix.py +198 −0
  4. sys/src/cmd/python/Demo/scripts/fact.py +49 −0
  5. sys/src/cmd/python/Demo/scripts/find-uname.py +40 −0
  6. sys/src/cmd/python/Demo/scripts/from.py +35 −0
  7. sys/src/cmd/python/Demo/scripts/ftpstats.py +145 −0
  8. sys/src/cmd/python/Demo/scripts/lpwatch.py +110 −0
  9. sys/src/cmd/python/Demo/scripts/makedir.py +21 −0
  10. sys/src/cmd/python/Demo/scripts/markov.py +117 −0
  11. sys/src/cmd/python/Demo/scripts/mboxconvert.py +124 −0
  12. sys/src/cmd/python/Demo/scripts/mkrcs.py +61 −0
  13. sys/src/cmd/python/Demo/scripts/morse.py +149 −0
  14. sys/src/cmd/python/Demo/scripts/newslist.doc +59 −0
  15. sys/src/cmd/python/Demo/scripts/newslist.py +366 −0
  16. sys/src/cmd/python/Demo/scripts/pi.py +34 −0
  17. sys/src/cmd/python/Demo/scripts/pp.py +130 −0
  18. sys/src/cmd/python/Demo/scripts/primes.py +27 −0
  19. sys/src/cmd/python/Demo/scripts/queens.py +85 −0
  20. sys/src/cmd/python/Demo/scripts/script.py +33 −0
  21. sys/src/cmd/python/Demo/scripts/unbirthday.py +107 −0
  22. sys/src/cmd/python/Demo/scripts/update.py +92 −0
  23. sys/src/cmd/python/Demo/scripts/wh.py +2 −0
sys/src/cmd/python/Demo/scripts/README+23−0
@@ -0,0 +1,23 @@
1This directory contains a collection of executable Python scripts.
2
3See also the Tools/scripts directory!
4
5beer.py Print the classic 'bottles of beer' list.
6eqfix.py Fix .py files to use the correct equality test operator
7fact.py Factorize numbers
8find-uname.py Search for Unicode characters using regexps.
9from.py Summarize mailbox
10ftpstats.py Summarize ftp daemon log file
11lpwatch.py Watch BSD line printer queues
12makedir.py Like mkdir -p
13markov.py Markov chain simulation of words or characters
14mboxconvvert.py Convert MH or MMDF mailboxes to unix mailbox format
15mkrcs.py Fix symlinks named RCS into parallel tree
16morse.py Produce morse code (audible or on AIFF file)
17pi.py Print all digits of pi -- given enough time and memory
18pp.py Emulate some Perl command line options
19primes.py Print prime numbers
20queens.py Dijkstra's solution to Wirth's "N Queens problem"
21script.py Equivalent to BSD script(1) -- by Steen Lumholt
22unbirthday.py Print unbirthday count
23update.py Update a bunch of files according to a script.
sys/src/cmd/python/Demo/scripts/beer.py+14−0
@@ -0,0 +1,14 @@
1#! /usr/bin/env python
2# By GvR, demystified after a version by Fredrik Lundh.
3import sys
4n = 100
5if sys.argv[1:]: n = int(sys.argv[1])
6def bottle(n):
7 if n == 0: return "no more bottles of beer"
8 if n == 1: return "one bottle of beer"
9 return str(n) + " bottles of beer"
10for i in range(n):
11 print bottle(n-i), "on the wall,"
12 print bottle(n-i) + "."
13 print "Take one down, pass it around,"
14 print bottle(n-i-1), "on the wall."
sys/src/cmd/python/Demo/scripts/eqfix.py+198−0
@@ -0,0 +1,198 @@
1#! /usr/bin/env python
2
3# Fix Python source files to use the new equality test operator, i.e.,
4# if x = y: ...
5# is changed to
6# if x == y: ...
7# The script correctly tokenizes the Python program to reliably
8# distinguish between assignments and equality tests.
9#
10# Command line arguments are files or directories to be processed.
11# Directories are searched recursively for files whose name looks
12# like a python module.
13# Symbolic links are always ignored (except as explicit directory
14# arguments). Of course, the original file is kept as a back-up
15# (with a "~" attached to its name).
16# It complains about binaries (files containing null bytes)
17# and about files that are ostensibly not Python files: if the first
18# line starts with '#!' and does not contain the string 'python'.
19#
20# Changes made are reported to stdout in a diff-like format.
21#
22# Undoubtedly you can do this using find and sed or perl, but this is
23# a nice example of Python code that recurses down a directory tree
24# and uses regular expressions. Also note several subtleties like
25# preserving the file's mode and avoiding to even write a temp file
26# when no changes are needed for a file.
27#
28# NB: by changing only the function fixline() you can turn this
29# into a program for a different change to Python programs...
30
31import sys
32import re
33import os
34from stat import *
35import string
36
37err = sys.stderr.write
38dbg = err
39rep = sys.stdout.write
40
41def main():
42 bad = 0
43 if not sys.argv[1:]: # No arguments
44 err('usage: ' + sys.argv[0] + ' file-or-directory ...\n')
45 sys.exit(2)
46 for arg in sys.argv[1:]:
47 if os.path.isdir(arg):
48 if recursedown(arg): bad = 1
49 elif os.path.islink(arg):
50 err(arg + ': will not process symbolic links\n')
51 bad = 1
52 else:
53 if fix(arg): bad = 1
54 sys.exit(bad)
55
56ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
57def ispython(name):
58 return ispythonprog.match(name) >= 0
59
60def recursedown(dirname):
61 dbg('recursedown(%r)\n' % (dirname,))
62 bad = 0
63 try:
64 names = os.listdir(dirname)
65 except os.error, msg:
66 err('%s: cannot list directory: %r\n' % (dirname, msg))
67 return 1
68 names.sort()
69 subdirs = []
70 for name in names:
71 if name in (os.curdir, os.pardir): continue
72 fullname = os.path.join(dirname, name)
73 if os.path.islink(fullname): pass
74 elif os.path.isdir(fullname):
75 subdirs.append(fullname)
76 elif ispython(name):
77 if fix(fullname): bad = 1
78 for fullname in subdirs:
79 if recursedown(fullname): bad = 1
80 return bad
81
82def fix(filename):
83## dbg('fix(%r)\n' % (dirname,))
84 try:
85 f = open(filename, 'r')
86 except IOError, msg:
87 err('%s: cannot open: %r\n' % (filename, msg))
88 return 1
89 head, tail = os.path.split(filename)
90 tempname = os.path.join(head, '@' + tail)
91 g = None
92 # If we find a match, we rewind the file and start over but
93 # now copy everything to a temp file.
94 lineno = 0
95 while 1:
96 line = f.readline()
97 if not line: break
98 lineno = lineno + 1
99 if g is None and '\0' in line:
100 # Check for binary files
101 err(filename + ': contains null bytes; not fixed\n')
102 f.close()
103 return 1
104 if lineno == 1 and g is None and line[:2] == '#!':
105 # Check for non-Python scripts
106 words = string.split(line[2:])
107 if words and re.search('[pP]ython', words[0]) < 0:
108 msg = filename + ': ' + words[0]
109 msg = msg + ' script; not fixed\n'
110 err(msg)
111 f.close()
112 return 1
113 while line[-2:] == '\\\n':
114 nextline = f.readline()
115 if not nextline: break
116 line = line + nextline
117 lineno = lineno + 1
118 newline = fixline(line)
119 if newline != line:
120 if g is None:
121 try:
122 g = open(tempname, 'w')
123 except IOError, msg:
124 f.close()
125 err('%s: cannot create: %r\n' % (tempname, msg))
126 return 1
127 f.seek(0)
128 lineno = 0
129 rep(filename + ':\n')
130 continue # restart from the beginning
131 rep(repr(lineno) + '\n')
132 rep('< ' + line)
133 rep('> ' + newline)
134 if g is not None:
135 g.write(newline)
136
137 # End of file
138 f.close()
139 if not g: return 0 # No changes
140
141 # Finishing touch -- move files
142
143 # First copy the file's mode to the temp file
144 try:
145 statbuf = os.stat(filename)
146 os.chmod(tempname, statbuf[ST_MODE] & 07777)
147 except os.error, msg:
148 err('%s: warning: chmod failed (%r)\n' % (tempname, msg))
149 # Then make a backup of the original file as filename~
150 try:
151 os.rename(filename, filename + '~')
152 except os.error, msg:
153 err('%s: warning: backup failed (%r)\n' % (filename, msg))
154 # Now move the temp file to the original file
155 try:
156 os.rename(tempname, filename)
157 except os.error, msg:
158 err('%s: rename failed (%r)\n' % (filename, msg))
159 return 1
160 # Return succes
161 return 0
162
163
164from tokenize import tokenprog
165
166match = {'if':':', 'elif':':', 'while':':', 'return':'\n', \
167 '(':')', '[':']', '{':'}', '`':'`'}
168
169def fixline(line):
170 # Quick check for easy case
171 if '=' not in line: return line
172
173 i, n = 0, len(line)
174 stack = []
175 while i < n:
176 j = tokenprog.match(line, i)
177 if j < 0:
178 # A bad token; forget about the rest of this line
179 print '(Syntax error:)'
180 print line,
181 return line
182 a, b = tokenprog.regs[3] # Location of the token proper
183 token = line[a:b]
184 i = i+j
185 if stack and token == stack[-1]:
186 del stack[-1]
187 elif match.has_key(token):
188 stack.append(match[token])
189 elif token == '=' and stack:
190 line = line[:a] + '==' + line[b:]
191 i, n = a + len('=='), len(line)
192 elif token == '==' and not stack:
193 print '(Warning: \'==\' at top level:)'
194 print line,
195 return line
196
197if __name__ == "__main__":
198 main()
sys/src/cmd/python/Demo/scripts/fact.py+49−0
@@ -0,0 +1,49 @@
1#! /usr/bin/env python
2
3# Factorize numbers.
4# The algorithm is not efficient, but easy to understand.
5# If there are large factors, it will take forever to find them,
6# because we try all odd numbers between 3 and sqrt(n)...
7
8import sys
9from math import sqrt
10
11error = 'fact.error' # exception
12
13def fact(n):
14 if n < 1: raise error # fact() argument should be >= 1
15 if n == 1: return [] # special case
16 res = []
17 # Treat even factors special, so we can use i = i+2 later
18 while n%2 == 0:
19 res.append(2)
20 n = n/2
21 # Try odd numbers up to sqrt(n)
22 limit = sqrt(float(n+1))
23 i = 3
24 while i <= limit:
25 if n%i == 0:
26 res.append(i)
27 n = n/i
28 limit = sqrt(n+1)
29 else:
30 i = i+2
31 if n != 1:
32 res.append(n)
33 return res
34
35def main():
36 if len(sys.argv) > 1:
37 for arg in sys.argv[1:]:
38 n = eval(arg)
39 print n, fact(n)
40 else:
41 try:
42 while 1:
43 n = input()
44 print n, fact(n)
45 except EOFError:
46 pass
47
48if __name__ == "__main__":
49 main()
sys/src/cmd/python/Demo/scripts/find-uname.py+40−0
@@ -0,0 +1,40 @@
1#!/usr/bin/env python
2
3"""
4For each argument on the command line, look for it in the set of all Unicode
5names. Arguments are treated as case-insensitive regular expressions, e.g.:
6
7 % find-uname 'small letter a$' 'horizontal line'
8 *** small letter a$ matches ***
9 LATIN SMALL LETTER A (97)
10 COMBINING LATIN SMALL LETTER A (867)
11 CYRILLIC SMALL LETTER A (1072)
12 PARENTHESIZED LATIN SMALL LETTER A (9372)
13 CIRCLED LATIN SMALL LETTER A (9424)
14 FULLWIDTH LATIN SMALL LETTER A (65345)
15 *** horizontal line matches ***
16 HORIZONTAL LINE EXTENSION (9135)
17"""
18
19import unicodedata
20import sys
21import re
22
23def main(args):
24 unicode_names= []
25 for ix in range(sys.maxunicode+1):
26 try:
27 unicode_names.append( (ix, unicodedata.name(unichr(ix))) )
28 except ValueError: # no name for the character
29 pass
30 for arg in args:
31 pat = re.compile(arg, re.I)
32 matches = [(x,y) for (x,y) in unicode_names
33 if pat.search(y) is not None]
34 if matches:
35 print "***", arg, "matches", "***"
36 for (x,y) in matches:
37 print "%s (%d)" % (y,x)
38
39if __name__ == "__main__":
40 main(sys.argv[1:])
sys/src/cmd/python/Demo/scripts/from.py+35−0
@@ -0,0 +1,35 @@
1#! /usr/bin/env python
2
3# Print From and Subject of messages in $MAIL.
4# Extension to multiple mailboxes and other bells & whistles are left
5# as exercises for the reader.
6
7import sys, os
8
9# Open mailbox file. Exits with exception when this fails.
10
11try:
12 mailbox = os.environ['MAIL']
13except (AttributeError, KeyError):
14 sys.stderr.write('No environment variable $MAIL\n')
15 sys.exit(2)
16
17try:
18 mail = open(mailbox)
19except IOError:
20 sys.exit('Cannot open mailbox file: ' + mailbox)
21
22while 1:
23 line = mail.readline()
24 if not line:
25 break # EOF
26 if line.startswith('From '):
27 # Start of message found
28 print line[:-1],
29 while 1:
30 line = mail.readline()
31 if not line or line == '\n':
32 break
33 if line.startswith('Subject: '):
34 print repr(line[9:-1]),
35 print
sys/src/cmd/python/Demo/scripts/ftpstats.py+145−0
@@ -0,0 +1,145 @@
1#! /usr/bin/env python
2
3# Extract statistics from ftp daemon log.
4
5# Usage:
6# ftpstats [-m maxitems] [-s search] [file]
7# -m maxitems: restrict number of items in "top-N" lists, default 25.
8# -s string: restrict statistics to lines containing this string.
9# Default file is /usr/adm/ftpd; a "-" means read standard input.
10
11# The script must be run on the host where the ftp daemon runs.
12# (At CWI this is currently buizerd.)
13
14import os
15import sys
16import re
17import string
18import getopt
19
20pat = '^([a-zA-Z0-9 :]*)!(.*)!(.*)!([<>].*)!([0-9]+)!([0-9]+)$'
21prog = re.compile(pat)
22
23def main():
24 maxitems = 25
25 search = None
26 try:
27 opts, args = getopt.getopt(sys.argv[1:], 'm:s:')
28 except getopt.error, msg:
29 print msg
30 print 'usage: ftpstats [-m maxitems] [file]'
31 sys.exit(2)
32 for o, a in opts:
33 if o == '-m':
34 maxitems = string.atoi(a)
35 if o == '-s':
36 search = a
37 file = '/usr/adm/ftpd'
38 if args: file = args[0]
39 if file == '-':
40 f = sys.stdin
41 else:
42 try:
43 f = open(file, 'r')
44 except IOError, msg:
45 print file, ':', msg
46 sys.exit(1)
47 bydate = {}
48 bytime = {}
49 byfile = {}
50 bydir = {}
51 byhost = {}
52 byuser = {}
53 bytype = {}
54 lineno = 0
55 try:
56 while 1:
57 line = f.readline()
58 if not line: break
59 lineno = lineno + 1
60 if search and string.find(line, search) < 0:
61 continue
62 if prog.match(line) < 0:
63 print 'Bad line', lineno, ':', repr(line)
64 continue
65 items = prog.group(1, 2, 3, 4, 5, 6)
66 (logtime, loguser, loghost, logfile, logbytes,
67 logxxx2) = items
68## print logtime
69## print '-->', loguser
70## print '--> -->', loghost
71## print '--> --> -->', logfile
72## print '--> --> --> -->', logbytes
73## print '--> --> --> --> -->', logxxx2
74## for i in logtime, loghost, logbytes, logxxx2:
75## if '!' in i: print '???', i
76 add(bydate, logtime[-4:] + ' ' + logtime[:6], items)
77 add(bytime, logtime[7:9] + ':00-59', items)
78 direction, logfile = logfile[0], logfile[1:]
79 # The real path probably starts at the last //...
80 while 1:
81 i = string.find(logfile, '//')
82 if i < 0: break
83 logfile = logfile[i+1:]
84 add(byfile, logfile + ' ' + direction, items)
85 logdir = os.path.dirname(logfile)
86## logdir = os.path.normpath(logdir) + '/.'
87 while 1:
88 add(bydir, logdir + ' ' + direction, items)
89 dirhead = os.path.dirname(logdir)
90 if dirhead == logdir: break
91 logdir = dirhead
92 add(byhost, loghost, items)
93 add(byuser, loguser, items)
94 add(bytype, direction, items)
95 except KeyboardInterrupt:
96 print 'Interrupted at line', lineno
97 show(bytype, 'by transfer direction', maxitems)
98 show(bydir, 'by directory', maxitems)
99 show(byfile, 'by file', maxitems)
100 show(byhost, 'by host', maxitems)
101 show(byuser, 'by user', maxitems)
102 showbar(bydate, 'by date')
103 showbar(bytime, 'by time of day')
104
105def showbar(dict, title):
106 n = len(title)
107 print '='*((70-n)/2), title, '='*((71-n)/2)
108 list = []
109 keys = dict.keys()
110 keys.sort()
111 for key in keys:
112 n = len(str(key))
113 list.append((len(dict[key]), key))
114 maxkeylength = 0
115 maxcount = 0
116 for count, key in list:
117 maxkeylength = max(maxkeylength, len(key))
118 maxcount = max(maxcount, count)
119 maxbarlength = 72 - maxkeylength - 7
120 for count, key in list:
121 barlength = int(round(maxbarlength*float(count)/maxcount))
122 bar = '*'*barlength
123 print '%5d %-*s %s' % (count, maxkeylength, key, bar)
124
125def show(dict, title, maxitems):
126 if len(dict) > maxitems:
127 title = title + ' (first %d)'%maxitems
128 n = len(title)
129 print '='*((70-n)/2), title, '='*((71-n)/2)
130 list = []
131 keys = dict.keys()
132 for key in keys:
133 list.append((-len(dict[key]), key))
134 list.sort()
135 for count, key in list[:maxitems]:
136 print '%5d %s' % (-count, key)
137
138def add(dict, key, item):
139 if dict.has_key(key):
140 dict[key].append(item)
141 else:
142 dict[key] = [item]
143
144if __name__ == "__main__":
145 main()
sys/src/cmd/python/Demo/scripts/lpwatch.py+110−0
@@ -0,0 +1,110 @@
1#! /usr/bin/env python
2
3# Watch line printer queue(s).
4# Intended for BSD 4.3 lpq.
5
6import posix
7import sys
8import time
9import string
10
11DEF_PRINTER = 'psc'
12DEF_DELAY = 10
13
14def main():
15 delay = DEF_DELAY # XXX Use getopt() later
16 try:
17 thisuser = posix.environ['LOGNAME']
18 except:
19 thisuser = posix.environ['USER']
20 printers = sys.argv[1:]
21 if printers:
22 # Strip '-P' from printer names just in case
23 # the user specified it...
24 for i in range(len(printers)):
25 if printers[i][:2] == '-P':
26 printers[i] = printers[i][2:]
27 else:
28 if posix.environ.has_key('PRINTER'):
29 printers = [posix.environ['PRINTER']]
30 else:
31 printers = [DEF_PRINTER]
32 #
33 clearhome = posix.popen('clear', 'r').read()
34 #
35 while 1:
36 text = clearhome
37 for name in printers:
38 text = text + makestatus(name, thisuser) + '\n'
39 print text
40 time.sleep(delay)
41
42def makestatus(name, thisuser):
43 pipe = posix.popen('lpq -P' + name + ' 2>&1', 'r')
44 lines = []
45 users = {}
46 aheadbytes = 0
47 aheadjobs = 0
48 userseen = 0
49 totalbytes = 0
50 totaljobs = 0
51 while 1:
52 line = pipe.readline()
53 if not line: break
54 fields = string.split(line)
55 n = len(fields)
56 if len(fields) >= 6 and fields[n-1] == 'bytes':
57 rank = fields[0]
58 user = fields[1]
59 job = fields[2]
60 files = fields[3:-2]
61 bytes = eval(fields[n-2])
62 if user == thisuser:
63 userseen = 1
64 elif not userseen:
65 aheadbytes = aheadbytes + bytes
66 aheadjobs = aheadjobs + 1
67 totalbytes = totalbytes + bytes
68 totaljobs = totaljobs + 1
69 if users.has_key(user):
70 ujobs, ubytes = users[user]
71 else:
72 ujobs, ubytes = 0, 0
73 ujobs = ujobs + 1
74 ubytes = ubytes + bytes
75 users[user] = ujobs, ubytes
76 else:
77 if fields and fields[0] <> 'Rank':
78 line = string.strip(line)
79 if line == 'no entries':
80 line = name + ': idle'
81 elif line[-22:] == ' is ready and printing':
82 line = name
83 lines.append(line)
84 #
85 if totaljobs:
86 line = '%d K' % ((totalbytes+1023)/1024)
87 if totaljobs <> len(users):
88 line = line + ' (%d jobs)' % totaljobs
89 if len(users) == 1:
90 line = line + ' for %s' % (users.keys()[0],)
91 else:
92 line = line + ' for %d users' % len(users)
93 if userseen:
94 if aheadjobs == 0:
95 line = line + ' (%s first)' % thisuser
96 else:
97 line = line + ' (%d K before %s)' % (
98 (aheadbytes+1023)/1024, thisuser)
99 lines.append(line)
100 #
101 sts = pipe.close()
102 if sts:
103 lines.append('lpq exit status %r' % (sts,))
104 return string.joinfields(lines, ': ')
105
106if __name__ == "__main__":
107 try:
108 main()
109 except KeyboardInterrupt:
110 pass
sys/src/cmd/python/Demo/scripts/makedir.py+21−0
@@ -0,0 +1,21 @@
1#! /usr/bin/env python
2
3# Like mkdir, but also make intermediate directories if necessary.
4# It is not an error if the given directory already exists (as long
5# as it is a directory).
6# Errors are not treated specially -- you just get a Python exception.
7
8import sys, os
9
10def main():
11 for p in sys.argv[1:]:
12 makedirs(p)
13
14def makedirs(p):
15 if p and not os.path.isdir(p):
16 head, tail = os.path.split(p)
17 makedirs(head)
18 os.mkdir(p, 0777)
19
20if __name__ == "__main__":
21 main()
sys/src/cmd/python/Demo/scripts/markov.py+117−0
@@ -0,0 +1,117 @@
1#! /usr/bin/env python
2
3class Markov:
4 def __init__(self, histsize, choice):
5 self.histsize = histsize
6 self.choice = choice
7 self.trans = {}
8 def add(self, state, next):
9 if not self.trans.has_key(state):
10 self.trans[state] = [next]
11 else:
12 self.trans[state].append(next)
13 def put(self, seq):
14 n = self.histsize
15 add = self.add
16 add(None, seq[:0])
17 for i in range(len(seq)):
18 add(seq[max(0, i-n):i], seq[i:i+1])
19 add(seq[len(seq)-n:], None)
20 def get(self):
21 choice = self.choice
22 trans = self.trans
23 n = self.histsize
24 seq = choice(trans[None])
25 while 1:
26 subseq = seq[max(0, len(seq)-n):]
27 options = trans[subseq]
28 next = choice(options)
29 if not next: break
30 seq = seq + next
31 return seq
32
33def test():
34 import sys, string, random, getopt
35 args = sys.argv[1:]
36 try:
37 opts, args = getopt.getopt(args, '0123456789cdw')
38 except getopt.error:
39 print 'Usage: markov [-#] [-cddqw] [file] ...'
40 print 'Options:'
41 print '-#: 1-digit history size (default 2)'
42 print '-c: characters (default)'
43 print '-w: words'
44 print '-d: more debugging output'
45 print '-q: no debugging output'
46 print 'Input files (default stdin) are split in paragraphs'
47 print 'separated blank lines and each paragraph is split'
48 print 'in words by whitespace, then reconcatenated with'
49 print 'exactly one space separating words.'
50 print 'Output consists of paragraphs separated by blank'
51 print 'lines, where lines are no longer than 72 characters.'
52 histsize = 2
53 do_words = 0
54 debug = 1
55 for o, a in opts:
56 if '-0' <= o <= '-9': histsize = eval(o[1:])
57 if o == '-c': do_words = 0
58 if o == '-d': debug = debug + 1
59 if o == '-q': debug = 0
60 if o == '-w': do_words = 1
61 if not args: args = ['-']
62 m = Markov(histsize, random.choice)
63 try:
64 for filename in args:
65 if filename == '-':
66 f = sys.stdin
67 if f.isatty():
68 print 'Sorry, need stdin from file'
69 continue
70 else:
71 f = open(filename, 'r')
72 if debug: print 'processing', filename, '...'
73 text = f.read()
74 f.close()
75 paralist = string.splitfields(text, '\n\n')
76 for para in paralist:
77 if debug > 1: print 'feeding ...'
78 words = string.split(para)
79 if words:
80 if do_words: data = tuple(words)
81 else: data = string.joinfields(words, ' ')
82 m.put(data)
83 except KeyboardInterrupt:
84 print 'Interrupted -- continue with data read so far'
85 if not m.trans:
86 print 'No valid input files'
87 return
88 if debug: print 'done.'
89 if debug > 1:
90 for key in m.trans.keys():
91 if key is None or len(key) < histsize:
92 print repr(key), m.trans[key]
93 if histsize == 0: print repr(''), m.trans['']
94 print
95 while 1:
96 data = m.get()
97 if do_words: words = data
98 else: words = string.split(data)
99 n = 0
100 limit = 72
101 for w in words:
102 if n + len(w) > limit:
103 print
104 n = 0
105 print w,
106 n = n + len(w) + 1
107 print
108 print
109
110def tuple(list):
111 if len(list) == 0: return ()
112 if len(list) == 1: return (list[0],)
113 i = len(list)/2
114 return tuple(list[:i]) + tuple(list[i:])
115
116if __name__ == "__main__":
117 test()
sys/src/cmd/python/Demo/scripts/mboxconvert.py+124−0
@@ -0,0 +1,124 @@
1#! /usr/bin/env python
2
3# Convert MH directories (1 message per file) or MMDF mailboxes (4x^A
4# delimited) to unix mailbox (From ... delimited) on stdout.
5# If -f is given, files contain one message per file (e.g. MH messages)
6
7import rfc822
8import sys
9import time
10import os
11import stat
12import getopt
13import re
14
15def main():
16 dofile = mmdf
17 try:
18 opts, args = getopt.getopt(sys.argv[1:], 'f')
19 except getopt.error, msg:
20 sys.stderr.write('%s\n' % msg)
21 sys.exit(2)
22 for o, a in opts:
23 if o == '-f':
24 dofile = message
25 if not args:
26 args = ['-']
27 sts = 0
28 for arg in args:
29 if arg == '-' or arg == '':
30 sts = dofile(sys.stdin) or sts
31 elif os.path.isdir(arg):
32 sts = mh(arg) or sts
33 elif os.path.isfile(arg):
34 try:
35 f = open(arg)
36 except IOError, msg:
37 sys.stderr.write('%s: %s\n' % (arg, msg))
38 sts = 1
39 continue
40 sts = dofile(f) or sts
41 f.close()
42 else:
43 sys.stderr.write('%s: not found\n' % arg)
44 sts = 1
45 if sts:
46 sys.exit(sts)
47
48numeric = re.compile('[1-9][0-9]*')
49
50def mh(dir):
51 sts = 0
52 msgs = os.listdir(dir)
53 for msg in msgs:
54 if numeric.match(msg) != len(msg):
55 continue
56 fn = os.path.join(dir, msg)
57 try:
58 f = open(fn)
59 except IOError, msg:
60 sys.stderr.write('%s: %s\n' % (fn, msg))
61 sts = 1
62 continue
63 sts = message(f) or sts
64 return sts
65
66def mmdf(f):
67 sts = 0
68 while 1:
69 line = f.readline()
70 if not line:
71 break
72 if line == '\1\1\1\1\n':
73 sts = message(f, line) or sts
74 else:
75 sys.stderr.write(
76 'Bad line in MMFD mailbox: %r\n' % (line,))
77 return sts
78
79counter = 0 # for generating unique Message-ID headers
80
81def message(f, delimiter = ''):
82 sts = 0
83 # Parse RFC822 header
84 m = rfc822.Message(f)
85 # Write unix header line
86 fullname, email = m.getaddr('From')
87 tt = m.getdate('Date')
88 if tt:
89 t = time.mktime(tt)
90 else:
91 sys.stderr.write(
92 'Unparseable date: %r\n' % (m.getheader('Date'),))
93 t = os.fstat(f.fileno())[stat.ST_MTIME]
94 print 'From', email, time.ctime(t)
95 # Copy RFC822 header
96 for line in m.headers:
97 print line,
98 # Invent Message-ID header if none is present
99 if not m.has_key('message-id'):
100 global counter
101 counter = counter + 1
102 msgid = "<%s.%d>" % (hex(t), counter)
103 sys.stderr.write("Adding Message-ID %s (From %s)\n" %
104 (msgid, email))
105 print "Message-ID:", msgid
106 print
107 # Copy body
108 while 1:
109 line = f.readline()
110 if line == delimiter:
111 break
112 if not line:
113 sys.stderr.write('Unexpected EOF in message\n')
114 sts = 1
115 break
116 if line[:5] == 'From ':
117 line = '>' + line
118 print line,
119 # Print trailing newline
120 print
121 return sts
122
123if __name__ == "__main__":
124 main()
sys/src/cmd/python/Demo/scripts/mkrcs.py+61−0
@@ -0,0 +1,61 @@
1#! /usr/bin/env python
2
3# A rather specialized script to make sure that a symbolic link named
4# RCS exists pointing to a real RCS directory in a parallel tree
5# referenced as RCStree in an ancestor directory.
6# (I use this because I like my RCS files to reside on a physically
7# different machine).
8
9import os
10
11def main():
12 rcstree = 'RCStree'
13 rcs = 'RCS'
14 if os.path.islink(rcs):
15 print '%r is a symlink to %r' % (rcs, os.readlink(rcs))
16 return
17 if os.path.isdir(rcs):
18 print '%r is an ordinary directory' % (rcs,)
19 return
20 if os.path.exists(rcs):
21 print '%r is a file?!?!' % (rcs,)
22 return
23 #
24 p = os.getcwd()
25 up = ''
26 down = ''
27 # Invariants:
28 # (1) join(p, down) is the current directory
29 # (2) up is the same directory as p
30 # Ergo:
31 # (3) join(up, down) is the current directory
32 #print 'p =', repr(p)
33 while not os.path.isdir(os.path.join(p, rcstree)):
34 head, tail = os.path.split(p)
35 #print 'head = %r; tail = %r' % (head, tail)
36 if not tail:
37 print 'Sorry, no ancestor dir contains %r' % (rcstree,)
38 return
39 p = head
40 up = os.path.join(os.pardir, up)
41 down = os.path.join(tail, down)
42 #print 'p = %r; up = %r; down = %r' % (p, up, down)
43 there = os.path.join(up, rcstree)
44 there = os.path.join(there, down)
45 there = os.path.join(there, rcs)
46 if os.path.isdir(there):
47 print '%r already exists' % (there, )
48 else:
49 print 'making %r' % (there,)
50 makedirs(there)
51 print 'making symlink %r -> %r' % (rcs, there)
52 os.symlink(there, rcs)
53
54def makedirs(p):
55 if not os.path.isdir(p):
56 head, tail = os.path.split(p)
57 makedirs(head)
58 os.mkdir(p, 0777)
59
60if __name__ == "__main__":
61 main()
sys/src/cmd/python/Demo/scripts/morse.py+149−0
@@ -0,0 +1,149 @@
1# DAH should be three DOTs.
2# Space between DOTs and DAHs should be one DOT.
3# Space between two letters should be one DAH.
4# Space between two words should be DOT DAH DAH.
5
6import sys, math, audiodev
7
8DOT = 30
9DAH = 3 * DOT
10OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
11
12morsetab = {
13 'A': '.-', 'a': '.-',
14 'B': '-...', 'b': '-...',
15 'C': '-.-.', 'c': '-.-.',
16 'D': '-..', 'd': '-..',
17 'E': '.', 'e': '.',
18 'F': '..-.', 'f': '..-.',
19 'G': '--.', 'g': '--.',
20 'H': '....', 'h': '....',
21 'I': '..', 'i': '..',
22 'J': '.---', 'j': '.---',
23 'K': '-.-', 'k': '-.-',
24 'L': '.-..', 'l': '.-..',
25 'M': '--', 'm': '--',
26 'N': '-.', 'n': '-.',
27 'O': '---', 'o': '---',
28 'P': '.--.', 'p': '.--.',
29 'Q': '--.-', 'q': '--.-',
30 'R': '.-.', 'r': '.-.',
31 'S': '...', 's': '...',
32 'T': '-', 't': '-',
33 'U': '..-', 'u': '..-',
34 'V': '...-', 'v': '...-',
35 'W': '.--', 'w': '.--',
36 'X': '-..-', 'x': '-..-',
37 'Y': '-.--', 'y': '-.--',
38 'Z': '--..', 'z': '--..',
39 '0': '-----',
40 '1': '.----',
41 '2': '..---',
42 '3': '...--',
43 '4': '....-',
44 '5': '.....',
45 '6': '-....',
46 '7': '--...',
47 '8': '---..',
48 '9': '----.',
49 ',': '--..--',
50 '.': '.-.-.-',
51 '?': '..--..',
52 ';': '-.-.-.',
53 ':': '---...',
54 "'": '.----.',
55 '-': '-....-',
56 '/': '-..-.',
57 '(': '-.--.-',
58 ')': '-.--.-',
59 '_': '..--.-',
60 ' ': ' '
61}
62
63# If we play at 44.1 kHz (which we do), then if we produce one sine
64# wave in 100 samples, we get a tone of 441 Hz. If we produce two
65# sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
66# appears to be a nice one for playing morse code.
67def mkwave(octave):
68 global sinewave, nowave
69 sinewave = ''
70 for i in range(100):
71 val = int(math.sin(math.pi * float(i) * octave / 50.0) * 30000)
72 sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255)
73 nowave = '\0' * 200
74
75mkwave(OCTAVE)
76
77def main():
78 import getopt, string
79 try:
80 opts, args = getopt.getopt(sys.argv[1:], 'o:p:')
81 except getopt.error:
82 sys.stderr.write('Usage ' + sys.argv[0] +
83 ' [ -o outfile ] [ args ] ...\n')
84 sys.exit(1)
85 dev = None
86 for o, a in opts:
87 if o == '-o':
88 import aifc
89 dev = aifc.open(a, 'w')
90 dev.setframerate(44100)
91 dev.setsampwidth(2)
92 dev.setnchannels(1)
93 if o == '-p':
94 mkwave(string.atoi(a))
95 if not dev:
96 import audiodev
97 dev = audiodev.AudioDev()
98 dev.setoutrate(44100)
99 dev.setsampwidth(2)
100 dev.setnchannels(1)
101 dev.close = dev.stop
102 dev.writeframesraw = dev.writeframes
103 if args:
104 line = string.join(args)
105 else:
106 line = sys.stdin.readline()
107 while line:
108 mline = morse(line)
109 play(mline, dev)
110 if hasattr(dev, 'wait'):
111 dev.wait()
112 if not args:
113 line = sys.stdin.readline()
114 else:
115 line = ''
116 dev.close()
117
118# Convert a string to morse code with \001 between the characters in
119# the string.
120def morse(line):
121 res = ''
122 for c in line:
123 try:
124 res = res + morsetab[c] + '\001'
125 except KeyError:
126 pass
127 return res
128
129# Play a line of morse code.
130def play(line, dev):
131 for c in line:
132 if c == '.':
133 sine(dev, DOT)
134 elif c == '-':
135 sine(dev, DAH)
136 else: # space
137 pause(dev, DAH + DOT)
138 pause(dev, DOT)
139
140def sine(dev, length):
141 for i in range(length):
142 dev.writeframesraw(sinewave)
143
144def pause(dev, length):
145 for i in range(length):
146 dev.writeframesraw(nowave)
147
148if __name__ == '__main__' or sys.argv[0] == __name__:
149 main()
sys/src/cmd/python/Demo/scripts/newslist.doc+59−0
@@ -0,0 +1,59 @@
1 NEWSLIST
2 ========
3 A program to assist HTTP browsing of newsgroups
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6WWW browsers such as NCSA Mosaic allow the user to read newsgroup
7articles by specifying the group name in a URL eg 'news:comp.answers'.
8
9To browse through many groups, though, (and there are several thousand
10of them) you really need a page or pages containing links to all the
11groups. There are some good ones out there, for example,
12
13 http://info.cern.ch/hypertext/DataSources/News/Groups/Overview.html
14
15is the standard one at CERN, but it only shows the groups available there,
16which may be rather different from those available on your machine.
17
18Newslist is a program which creates a hierarchy of pages for you based
19on the groups available from YOUR server. It is written in python - a
20splendid interpreted object-oriented language which I suggest you get
21right now from the directory /pub/python at ftp.cwi.nl, if you haven't
22already got it.
23
24You should be able to see some sample output by looking at:
25 http://pelican.cl.cam.ac.uk/newspage/root.html
26
27Descriptions of newsgroups can be added from a file with one group
28per line. eg:
29
30 alt.foo Articles about foo
31 comp.bar Programming in 'bar' and related languages
32
33A suitable list detailing most groups can be found at ftp.uu.net in
34/uunet-info/newsgroups.gz.
35
36Make sure you read the information at the beginning of the program source and
37configure the variables before running.
38
39In addition to python, you need:
40
41 An NNTP-based news feed.
42 A directory in which to put the pages.
43
44The programming is not very beautiful, but it works! It comes with no
45warranty, express or implied, but with the hope that some others may
46find it useful.
47
48Comments, improvements & suggestions welcomed.
49Quentin Stafford-Fraser
50
51 ----------------------------------------------------------------------
52 Quentin Stafford-Fraser
53 http://pelican.cl.cam.ac.uk/people/qs101/me.html
54
55 Cambridge University Computer Lab Rank Xerox Cambridge EuroPARC
56 qs101@cl.cam.ac.uk fraser@europarc.xerox.com
57 Tel: +44 223 334411 Tel: +44 223 341521
58 Fax: +44 223 334679 Fax: +44 223 341510
59 ----------------------------------------------------------------------
sys/src/cmd/python/Demo/scripts/newslist.py+366−0
@@ -0,0 +1,366 @@
1#! /usr/bin/env python
2#######################################################################
3# Newslist $Revision: 37320 $
4#
5# Syntax:
6# newslist [ -a ]
7#
8# This is a program to create a directory full of HTML pages
9# which between them contain links to all the newsgroups available
10# on your server.
11#
12# The -a option causes a complete list of all groups to be read from
13# the server rather than just the ones which have appeared since last
14# execution. This recreates the local list from scratch. Use this on
15# the first invocation of the program, and from time to time thereafter.
16# When new groups are first created they may appear on your server as
17# empty groups. By default, empty groups are ignored by the -a option.
18# However, these new groups will not be created again, and so will not
19# appear in the server's list of 'new groups' at a later date. Hence it
20# won't appear until you do a '-a' after some articles have appeared.
21#
22# I should really keep a list of ignored empty groups and re-check them
23# for articles on every run, but I haven't got around to it yet.
24#
25# This assumes an NNTP news feed.
26#
27# Feel free to copy, distribute and modify this code for
28# non-commercial use. If you make any useful modifications, let me
29# know!
30#
31# (c) Quentin Stafford-Fraser 1994
32# fraser@europarc.xerox.com qs101@cl.cam.ac.uk
33# #
34#######################################################################
35import sys,nntplib, string, marshal, time, os, posix, string
36
37#######################################################################
38# Check these variables before running! #
39
40# Top directory.
41# Filenames which don't start with / are taken as being relative to this.
42topdir='/anfs/qsbigdisc/web/html/newspage'
43
44# The name of your NNTP host
45# eg.
46# newshost = 'nntp-serv.cl.cam.ac.uk'
47# or use following to get the name from the NNTPSERVER environment
48# variable:
49# newshost = posix.environ['NNTPSERVER']
50newshost = 'nntp-serv.cl.cam.ac.uk'
51
52# The filename for a local cache of the newsgroup list
53treefile = 'grouptree'
54
55# The filename for descriptions of newsgroups
56# I found a suitable one at ftp.uu.net in /uunet-info/newgroups.gz
57# You can set this to '' if you don't wish to use one.
58descfile = 'newsgroups'
59
60# The directory in which HTML pages should be created
61# eg.
62# pagedir = '/usr/local/lib/html/newspage'
63# pagedir = 'pages'
64pagedir = topdir
65
66# The html prefix which will refer to this directory
67# eg.
68# httppref = '/newspage/',
69# or leave blank for relative links between pages: (Recommended)
70# httppref = ''
71httppref = ''
72
73# The name of the 'root' news page in this directory.
74# A .html suffix will be added.
75rootpage = 'root'
76
77# Set skipempty to 0 if you wish to see links to empty groups as well.
78# Only affects the -a option.
79skipempty = 1
80
81# pagelinkicon can contain html to put an icon after links to
82# further pages. This helps to make important links stand out.
83# Set to '' if not wanted, or '...' is quite a good one.
84pagelinkicon='... <img src="http://pelican.cl.cam.ac.uk/icons/page.xbm"> '
85
86# ---------------------------------------------------------------------
87# Less important personal preferences:
88
89# Sublistsize controls the maximum number of items the will appear as
90# an indented sub-list before the whole thing is moved onto a different
91# page. The smaller this is, the more pages you will have, but the
92# shorter each will be.
93sublistsize = 4
94
95# That should be all. #
96#######################################################################
97
98for dir in os.curdir, os.environ['HOME']:
99 rcfile = os.path.join(dir, '.newslistrc.py')
100 if os.path.exists(rcfile):
101 print rcfile
102 execfile(rcfile)
103 break
104
105from nntplib import NNTP
106from stat import *
107
108rcsrev = '$Revision: 37320 $'
109rcsrev = string.join(filter(lambda s: '$' not in s, string.split(rcsrev)))
110desc = {}
111
112# Make (possibly) relative filenames into absolute ones
113treefile = os.path.join(topdir,treefile)
114descfile = os.path.join(topdir,descfile)
115page = os.path.join(topdir,pagedir)
116
117# First the bits for creating trees ---------------------------
118
119# Addtotree creates/augments a tree from a list of group names
120def addtotree(tree, groups):
121 print 'Updating tree...'
122 for i in groups:
123 parts = string.splitfields(i,'.')
124 makeleaf(tree, parts)
125
126# Makeleaf makes a leaf and the branch leading to it if necessary
127def makeleaf(tree,path):
128 j = path[0]
129 l = len(path)
130
131 if not tree.has_key(j):
132 tree[j] = {}
133 if l == 1:
134 tree[j]['.'] = '.'
135 if l > 1:
136 makeleaf(tree[j],path[1:])
137
138# Then the bits for outputting trees as pages ----------------
139
140# Createpage creates an HTML file named <root>.html containing links
141# to those groups beginning with <root>.
142
143def createpage(root, tree, p):
144 filename = os.path.join(pagedir,root+'.html')
145 if root == rootpage:
146 detail = ''
147 else:
148 detail = ' under ' + root
149 f = open(filename,'w')
150 # f.write('Content-Type: text/html\n')
151 f.write('<TITLE>Newsgroups available' + detail + '</TITLE>\n')
152 f.write('<H1>Newsgroups available' + detail +'</H1>\n')
153 f.write('<A HREF="'+httppref+rootpage+'.html">Back to top level</A><P>\n')
154 printtree(f,tree,0,p)
155 f.write('<I>This page automatically created by \'newslist\' v. '+rcsrev+'.')
156 f.write(time.ctime(time.time()) + '</I><P>')
157 f.close()
158
159# Printtree prints the groups as a bulleted list. Groups with
160# more than <sublistsize> subgroups will be put on a separate page.
161# Other sets of subgroups are just indented.
162
163def printtree(f, tree, indent, p):
164 global desc
165 l = len(tree)
166
167 if l > sublistsize and indent>0:
168 # Create a new page and a link to it
169 f.write('<LI><B><A HREF="'+httppref+p[1:]+'.html">')
170 f.write(p[1:]+'.*')
171 f.write('</A></B>'+pagelinkicon+'\n')
172 createpage(p[1:], tree, p)
173 return
174
175 kl = tree.keys()
176
177 if l > 1:
178 kl.sort()
179 if indent > 0:
180 # Create a sub-list
181 f.write('<LI>'+p[1:]+'\n<UL>')
182 else:
183 # Create a main list
184 f.write('<UL>')
185 indent = indent + 1
186
187 for i in kl:
188 if i == '.':
189 # Output a newsgroup
190 f.write('<LI><A HREF="news:' + p[1:] + '">'+ p[1:] + '</A> ')
191 if desc.has_key(p[1:]):
192 f.write(' <I>'+desc[p[1:]]+'</I>\n')
193 else:
194 f.write('\n')
195 else:
196 # Output a hierarchy
197 printtree(f,tree[i], indent, p+'.'+i)
198
199 if l > 1:
200 f.write('\n</UL>')
201
202# Reading descriptions file ---------------------------------------
203
204# This returns an array mapping group name to its description
205
206def readdesc(descfile):
207 global desc
208
209 desc = {}
210
211 if descfile == '':
212 return
213
214 try:
215 d = open(descfile, 'r')
216 print 'Reading descriptions...'
217 except (IOError):
218 print 'Failed to open description file ' + descfile
219 return
220 l = d.readline()
221 while l != '':
222 bits = string.split(l)
223 try:
224 grp = bits[0]
225 dsc = string.join(bits[1:])
226 if len(dsc)>1:
227 desc[grp] = dsc
228 except (IndexError):
229 pass
230 l = d.readline()
231
232# Check that ouput directory exists, ------------------------------
233# and offer to create it if not
234
235def checkopdir(pagedir):
236 if not os.path.isdir(pagedir):
237 print 'Directory '+pagedir+' does not exist.'
238 print 'Shall I create it for you? (y/n)'
239 if sys.stdin.readline()[0] == 'y':
240 try:
241 os.mkdir(pagedir,0777)
242 except:
243 print 'Sorry - failed!'
244 sys.exit(1)
245 else:
246 print 'OK. Exiting.'
247 sys.exit(1)
248
249# Read and write current local tree ----------------------------------
250
251def readlocallist(treefile):
252 print 'Reading current local group list...'
253 tree = {}
254 try:
255 treetime = time.localtime(os.stat(treefile)[ST_MTIME])
256 except:
257 print '\n*** Failed to open local group cache '+treefile
258 print 'If this is the first time you have run newslist, then'
259 print 'use the -a option to create it.'
260 sys.exit(1)
261 treedate = '%02d%02d%02d' % (treetime[0] % 100 ,treetime[1], treetime[2])
262 try:
263 dump = open(treefile,'r')
264 tree = marshal.load(dump)
265 dump.close()
266 except (IOError):
267 print 'Cannot open local group list ' + treefile
268 return (tree, treedate)
269
270def writelocallist(treefile, tree):
271 try:
272 dump = open(treefile,'w')
273 groups = marshal.dump(tree,dump)
274 dump.close()
275 print 'Saved list to '+treefile+'\n'
276 except:
277 print 'Sorry - failed to write to local group cache '+treefile
278 print 'Does it (or its directory) have the correct permissions?'
279 sys.exit(1)
280
281# Return list of all groups on server -----------------------------
282
283def getallgroups(server):
284 print 'Getting list of all groups...'
285 treedate='010101'
286 info = server.list()[1]
287 groups = []
288 print 'Processing...'
289 if skipempty:
290 print '\nIgnoring following empty groups:'
291 for i in info:
292 grpname = string.split(i[0])[0]
293 if skipempty and string.atoi(i[1]) < string.atoi(i[2]):
294 print grpname+' ',
295 else:
296 groups.append(grpname)
297 print '\n'
298 if skipempty:
299 print '(End of empty groups)'
300 return groups
301
302# Return list of new groups on server -----------------------------
303
304def getnewgroups(server, treedate):
305 print 'Getting list of new groups since start of '+treedate+'...',
306 info = server.newgroups(treedate,'000001')[1]
307 print 'got %d.' % len(info)
308 print 'Processing...',
309 groups = []
310 for i in info:
311 grpname = string.split(i)[0]
312 groups.append(grpname)
313 print 'Done'
314 return groups
315
316# Now the main program --------------------------------------------
317
318def main():
319 global desc
320
321 tree={}
322
323 # Check that the output directory exists
324 checkopdir(pagedir);
325
326 try:
327 print 'Connecting to '+newshost+'...'
328 if sys.version[0] == '0':
329 s = NNTP.init(newshost)
330 else:
331 s = NNTP(newshost)
332 connected = 1
333 except (nntplib.error_temp, nntplib.error_perm), x:
334 print 'Error connecting to host:', x
335 print 'I\'ll try to use just the local list.'
336 connected = 0
337
338 # If -a is specified, read the full list of groups from server
339 if connected and len(sys.argv) > 1 and sys.argv[1] == '-a':
340
341 groups = getallgroups(s)
342
343 # Otherwise just read the local file and then add
344 # groups created since local file last modified.
345 else:
346
347 (tree, treedate) = readlocallist(treefile)
348 if connected:
349 groups = getnewgroups(s, treedate)
350
351 if connected:
352 addtotree(tree, groups)
353 writelocallist(treefile,tree)
354
355 # Read group descriptions
356 readdesc(descfile)
357
358 print 'Creating pages...'
359 createpage(rootpage, tree, '')
360 print 'Done'
361
362if __name__ == "__main__":
363 main()
364
365# That's all folks
366######################################################################
sys/src/cmd/python/Demo/scripts/pi.py+34−0
@@ -0,0 +1,34 @@
1#! /usr/bin/env python
2
3# Print digits of pi forever.
4#
5# The algorithm, using Python's 'long' integers ("bignums"), works
6# with continued fractions, and was conceived by Lambert Meertens.
7#
8# See also the ABC Programmer's Handbook, by Geurts, Meertens & Pemberton,
9# published by Prentice-Hall (UK) Ltd., 1990.
10
11import sys
12
13def main():
14 k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
15 while 1:
16 # Next approximation
17 p, q, k = k*k, 2L*k+1L, k+1L
18 a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
19 # Print common digits
20 d, d1 = a/b, a1/b1
21 while d == d1:
22 output(d)
23 a, a1 = 10L*(a%b), 10L*(a1%b1)
24 d, d1 = a/b, a1/b1
25
26def output(d):
27 # Use write() to avoid spaces between the digits
28 # Use str() to avoid the 'L'
29 sys.stdout.write(str(d))
30 # Flush so the output is seen immediately
31 sys.stdout.flush()
32
33if __name__ == "__main__":
34 main()
sys/src/cmd/python/Demo/scripts/pp.py+130−0
@@ -0,0 +1,130 @@
1#! /usr/bin/env python
2
3# Emulate some Perl command line options.
4# Usage: pp [-a] [-c] [-d] [-e scriptline] [-F fieldsep] [-n] [-p] [file] ...
5# Where the options mean the following:
6# -a : together with -n or -p, splits each line into list F
7# -c : check syntax only, do not execute any code
8# -d : run the script under the debugger, pdb
9# -e scriptline : gives one line of the Python script; may be repeated
10# -F fieldsep : sets the field separator for the -a option [not in Perl]
11# -n : runs the script for each line of input
12# -p : prints the line after the script has run
13# When no script lines have been passed, the first file argument
14# contains the script. With -n or -p, the remaining arguments are
15# read as input to the script, line by line. If a file is '-'
16# or missing, standard input is read.
17
18# XXX To do:
19# - add -i extension option (change files in place)
20# - make a single loop over the files and lines (changes effect of 'break')?
21# - add an option to specify the record separator
22# - except for -n/-p, run directly from the file if at all possible
23
24import sys
25import string
26import getopt
27
28FS = ''
29SCRIPT = []
30AFLAG = 0
31CFLAG = 0
32DFLAG = 0
33NFLAG = 0
34PFLAG = 0
35
36try:
37 optlist, ARGS = getopt.getopt(sys.argv[1:], 'acde:F:np')
38except getopt.error, msg:
39 sys.stderr.write(sys.argv[0] + ': ' + msg + '\n')
40 sys.exit(2)
41
42for option, optarg in optlist:
43 if option == '-a':
44 AFLAG = 1
45 elif option == '-c':
46 CFLAG = 1
47 elif option == '-d':
48 DFLAG = 1
49 elif option == '-e':
50 for line in string.splitfields(optarg, '\n'):
51 SCRIPT.append(line)
52 elif option == '-F':
53 FS = optarg
54 elif option == '-n':
55 NFLAG = 1
56 PFLAG = 0
57 elif option == '-p':
58 NFLAG = 1
59 PFLAG = 1
60 else:
61 print option, 'not recognized???'
62
63if not ARGS: ARGS.append('-')
64
65if not SCRIPT:
66 if ARGS[0] == '-':
67 fp = sys.stdin
68 else:
69 fp = open(ARGS[0], 'r')
70 while 1:
71 line = fp.readline()
72 if not line: break
73 SCRIPT.append(line[:-1])
74 del fp
75 del ARGS[0]
76 if not ARGS: ARGS.append('-')
77
78if CFLAG:
79 prologue = ['if 0:']
80 epilogue = []
81elif NFLAG:
82 # Note that it is on purpose that AFLAG and PFLAG are
83 # tested dynamically each time through the loop
84 prologue = [ \
85 'LINECOUNT = 0', \
86 'for FILE in ARGS:', \
87 ' \tif FILE == \'-\':', \
88 ' \t \tFP = sys.stdin', \
89 ' \telse:', \
90 ' \t \tFP = open(FILE, \'r\')', \
91 ' \tLINENO = 0', \
92 ' \twhile 1:', \
93 ' \t \tLINE = FP.readline()', \
94 ' \t \tif not LINE: break', \
95 ' \t \tLINENO = LINENO + 1', \
96 ' \t \tLINECOUNT = LINECOUNT + 1', \
97 ' \t \tL = LINE[:-1]', \
98 ' \t \taflag = AFLAG', \
99 ' \t \tif aflag:', \
100 ' \t \t \tif FS: F = string.splitfields(L, FS)', \
101 ' \t \t \telse: F = string.split(L)' \
102 ]
103 epilogue = [ \
104 ' \t \tif not PFLAG: continue', \
105 ' \t \tif aflag:', \
106 ' \t \t \tif FS: print string.joinfields(F, FS)', \
107 ' \t \t \telse: print string.join(F)', \
108 ' \t \telse: print L', \
109 ]
110else:
111 prologue = ['if 1:']
112 epilogue = []
113
114# Note that we indent using tabs only, so that any indentation style
115# used in 'command' will come out right after re-indentation.
116
117program = string.joinfields(prologue, '\n') + '\n'
118for line in SCRIPT:
119 program = program + (' \t \t' + line + '\n')
120program = program + (string.joinfields(epilogue, '\n') + '\n')
121
122import tempfile
123fp = tempfile.NamedTemporaryFile()
124fp.write(program)
125fp.flush()
126if DFLAG:
127 import pdb
128 pdb.run('execfile(%r)' % (tfn,))
129else:
130 execfile(tfn)
sys/src/cmd/python/Demo/scripts/primes.py+27−0
@@ -0,0 +1,27 @@
1#! /usr/bin/env python
2
3# Print prime numbers in a given range
4
5def main():
6 import sys
7 min, max = 2, 0x7fffffff
8 if sys.argv[1:]:
9 min = int(eval(sys.argv[1]))
10 if sys.argv[2:]:
11 max = int(eval(sys.argv[2]))
12 primes(min, max)
13
14def primes(min, max):
15 if 2 >= min: print 2
16 primes = [2]
17 i = 3
18 while i <= max:
19 for p in primes:
20 if i%p == 0 or p*p > i: break
21 if i%p <> 0:
22 primes.append(i)
23 if i >= min: print i
24 i = i+2
25
26if __name__ == "__main__":
27 main()
sys/src/cmd/python/Demo/scripts/queens.py+85−0
@@ -0,0 +1,85 @@
1#! /usr/bin/env python
2
3"""N queens problem.
4
5The (well-known) problem is due to Niklaus Wirth.
6
7This solution is inspired by Dijkstra (Structured Programming). It is
8a classic recursive backtracking approach.
9
10"""
11
12N = 8 # Default; command line overrides
13
14class Queens:
15
16 def __init__(self, n=N):
17 self.n = n
18 self.reset()
19
20 def reset(self):
21 n = self.n
22 self.y = [None]*n # Where is the queen in column x
23 self.row = [0]*n # Is row[y] safe?
24 self.up = [0] * (2*n-1) # Is upward diagonal[x-y] safe?
25 self.down = [0] * (2*n-1) # Is downward diagonal[x+y] safe?
26 self.nfound = 0 # Instrumentation
27
28 def solve(self, x=0): # Recursive solver
29 for y in range(self.n):
30 if self.safe(x, y):
31 self.place(x, y)
32 if x+1 == self.n:
33 self.display()
34 else:
35 self.solve(x+1)
36 self.remove(x, y)
37
38 def safe(self, x, y):
39 return not self.row[y] and not self.up[x-y] and not self.down[x+y]
40
41 def place(self, x, y):
42 self.y[x] = y
43 self.row[y] = 1
44 self.up[x-y] = 1
45 self.down[x+y] = 1
46
47 def remove(self, x, y):
48 self.y[x] = None
49 self.row[y] = 0
50 self.up[x-y] = 0
51 self.down[x+y] = 0
52
53 silent = 0 # If set, count solutions only
54
55 def display(self):
56 self.nfound = self.nfound + 1
57 if self.silent:
58 return
59 print '+-' + '--'*self.n + '+'
60 for y in range(self.n-1, -1, -1):
61 print '|',
62 for x in range(self.n):
63 if self.y[x] == y:
64 print "Q",
65 else:
66 print ".",
67 print '|'
68 print '+-' + '--'*self.n + '+'
69
70def main():
71 import sys
72 silent = 0
73 n = N
74 if sys.argv[1:2] == ['-n']:
75 silent = 1
76 del sys.argv[1]
77 if sys.argv[1:]:
78 n = int(sys.argv[1])
79 q = Queens(n)
80 q.silent = silent
81 q.solve()
82 print "Found", q.nfound, "solutions."
83
84if __name__ == "__main__":
85 main()
sys/src/cmd/python/Demo/scripts/script.py+33−0
@@ -0,0 +1,33 @@
1#! /usr/bin/env python
2# script.py -- Make typescript of terminal session.
3# Usage:
4# -a Append to typescript.
5# -p Use Python as shell.
6# Author: Steen Lumholt.
7
8
9import os, time, sys
10import pty
11
12def read(fd):
13 data = os.read(fd, 1024)
14 file.write(data)
15 return data
16
17shell = 'sh'
18filename = 'typescript'
19mode = 'w'
20if os.environ.has_key('SHELL'):
21 shell = os.environ['SHELL']
22if '-a' in sys.argv:
23 mode = 'a'
24if '-p' in sys.argv:
25 shell = 'python'
26
27file = open(filename, mode)
28
29sys.stdout.write('Script started, file is %s\n' % filename)
30file.write('Script started on %s\n' % time.ctime(time.time()))
31pty.spawn(shell, read)
32file.write('Script done on %s\n' % time.ctime(time.time()))
33sys.stdout.write('Script done, file is %s\n' % filename)
sys/src/cmd/python/Demo/scripts/unbirthday.py+107−0
@@ -0,0 +1,107 @@
1#! /usr/bin/env python
2
3# Calculate your unbirthday count (see Alice in Wonderland).
4# This is defined as the number of days from your birth until today
5# that weren't your birthday. (The day you were born is not counted).
6# Leap years make it interesting.
7
8import sys
9import time
10import calendar
11
12def main():
13 # Note that the range checks below also check for bad types,
14 # e.g. 3.14 or (). However syntactically invalid replies
15 # will raise an exception.
16 if sys.argv[1:]:
17 year = int(sys.argv[1])
18 else:
19 year = int(raw_input('In which year were you born? '))
20 if 0<=year<100:
21 print "I'll assume that by", year,
22 year = year + 1900
23 print 'you mean', year, 'and not the early Christian era'
24 elif not (1850<=year<=2002):
25 print "It's hard to believe you were born in", year
26 return
27 #
28 if sys.argv[2:]:
29 month = int(sys.argv[2])
30 else:
31 month = int(raw_input('And in which month? (1-12) '))
32 if not (1<=month<=12):
33 print 'There is no month numbered', month
34 return
35 #
36 if sys.argv[3:]:
37 day = int(sys.argv[3])
38 else:
39 day = int(raw_input('And on what day of that month? (1-31) '))
40 if month == 2 and calendar.isleap(year):
41 maxday = 29
42 else:
43 maxday = calendar.mdays[month]
44 if not (1<=day<=maxday):
45 print 'There are no', day, 'days in that month!'
46 return
47 #
48 bdaytuple = (year, month, day)
49 bdaydate = mkdate(bdaytuple)
50 print 'You were born on', format(bdaytuple)
51 #
52 todaytuple = time.localtime()[:3]
53 todaydate = mkdate(todaytuple)
54 print 'Today is', format(todaytuple)
55 #
56 if bdaytuple > todaytuple:
57 print 'You are a time traveler. Go back to the future!'
58 return
59 #
60 if bdaytuple == todaytuple:
61 print 'You were born today. Have a nice life!'
62 return
63 #
64 days = todaydate - bdaydate
65 print 'You have lived', days, 'days'
66 #
67 age = 0
68 for y in range(year, todaytuple[0] + 1):
69 if bdaytuple < (y, month, day) <= todaytuple:
70 age = age + 1
71 #
72 print 'You are', age, 'years old'
73 #
74 if todaytuple[1:] == bdaytuple[1:]:
75 print 'Congratulations! Today is your', nth(age), 'birthday'
76 print 'Yesterday was your',
77 else:
78 print 'Today is your',
79 print nth(days - age), 'unbirthday'
80
81def format((year, month, day)):
82 return '%d %s %d' % (day, calendar.month_name[month], year)
83
84def nth(n):
85 if n == 1: return '1st'
86 if n == 2: return '2nd'
87 if n == 3: return '3rd'
88 return '%dth' % n
89
90def mkdate((year, month, day)):
91 # Januari 1st, in 0 A.D. is arbitrarily defined to be day 1,
92 # even though that day never actually existed and the calendar
93 # was different then...
94 days = year*365 # years, roughly
95 days = days + (year+3)/4 # plus leap years, roughly
96 days = days - (year+99)/100 # minus non-leap years every century
97 days = days + (year+399)/400 # plus leap years every 4 centirues
98 for i in range(1, month):
99 if i == 2 and calendar.isleap(year):
100 days = days + 29
101 else:
102 days = days + calendar.mdays[i]
103 days = days + day
104 return days
105
106if __name__ == "__main__":
107 main()
sys/src/cmd/python/Demo/scripts/update.py+92−0
@@ -0,0 +1,92 @@
1#! /usr/bin/env python
2
3# Update a bunch of files according to a script.
4# The input file contains lines of the form <filename>:<lineno>:<text>,
5# meaning that the given line of the given file is to be replaced
6# by the given text. This is useful for performing global substitutions
7# on grep output:
8
9import os
10import sys
11import re
12
13pat = '^([^: \t\n]+):([1-9][0-9]*):'
14prog = re.compile(pat)
15
16class FileObj:
17 def __init__(self, filename):
18 self.filename = filename
19 self.changed = 0
20 try:
21 self.lines = open(filename, 'r').readlines()
22 except IOError, msg:
23 print '*** Can\'t open "%s":' % filename, msg
24 self.lines = None
25 return
26 print 'diffing', self.filename
27
28 def finish(self):
29 if not self.changed:
30 print 'no changes to', self.filename
31 return
32 try:
33 os.rename(self.filename, self.filename + '~')
34 fp = open(self.filename, 'w')
35 except (os.error, IOError), msg:
36 print '*** Can\'t rewrite "%s":' % self.filename, msg
37 return
38 print 'writing', self.filename
39 for line in self.lines:
40 fp.write(line)
41 fp.close()
42 self.changed = 0
43
44 def process(self, lineno, rest):
45 if self.lines is None:
46 print '(not processed): %s:%s:%s' % (
47 self.filename, lineno, rest),
48 return
49 i = eval(lineno) - 1
50 if not 0 <= i < len(self.lines):
51 print '*** Line number out of range: %s:%s:%s' % (
52 self.filename, lineno, rest),
53 return
54 if self.lines[i] == rest:
55 print '(no change): %s:%s:%s' % (
56 self.filename, lineno, rest),
57 return
58 if not self.changed:
59 self.changed = 1
60 print '%sc%s' % (lineno, lineno)
61 print '<', self.lines[i],
62 print '---'
63 self.lines[i] = rest
64 print '>', self.lines[i],
65
66def main():
67 if sys.argv[1:]:
68 try:
69 fp = open(sys.argv[1], 'r')
70 except IOError, msg:
71 print 'Can\'t open "%s":' % sys.argv[1], msg
72 sys.exit(1)
73 else:
74 fp = sys.stdin
75 curfile = None
76 while 1:
77 line = fp.readline()
78 if not line:
79 if curfile: curfile.finish()
80 break
81 n = prog.match(line)
82 if n < 0:
83 print 'Funny line:', line,
84 continue
85 filename, lineno = prog.group(1, 2)
86 if not curfile or filename <> curfile.filename:
87 if curfile: curfile.finish()
88 curfile = FileObj(filename)
89 curfile.process(lineno, line[n:])
90
91if __name__ == "__main__":
92 main()
sys/src/cmd/python/Demo/scripts/wh.py+2−0
@@ -0,0 +1,2 @@
1# This is here so I can use 'wh' instead of 'which' in '~/bin/generic_python'
2import which