diff options
Diffstat (limited to 'Demo')
278 files changed, 0 insertions, 28846 deletions
diff --git a/Demo/README b/Demo/README deleted file mode 100644 index 9d150d6..0000000 --- a/Demo/README +++ /dev/null @@ -1,61 +0,0 @@ -This directory contains various demonstrations of what you can do with -Python. They were all written by me except where explicitly stated -otherwise -- in general, demos contributed by others ends up in the -../Contrib directory, unless I think they're of utmost general -importance (like Matt Conway's Tk demos). - -A fair number of utilities that are useful when while developing -Python code can be found in the ../Tools directory -- some of these -can also be considered good examples of how to write Python code. - -Finally, in order to save disk space and net bandwidth, not all -subdirectories listed here are distributed. They are listed just -in case I change my mind about them. - - -cgi CGI examples (see also ../Tools/faqwiz/.) - -classes Some examples of how to use classes. - -comparisons A set of responses to a really old language-comparison - challenge. - -curses A set of curses demos. - -embed An example of embedding Python in another application - (see also pysvr). - -imputil Demonstration subclasses of imputil.Importer. - -md5test Test program for the optional md5 module. - -metaclasses The code from the 1.5 metaclasses paper on the web. - -parser Example using the parser module. - -pdist Old, unfinished code messing with CVS, RCS and remote - files. - -pysvr An example of embedding Python in a threaded - application. - -rpc A set of classes for building clients and servers for - Sun RPC. - -scripts Some useful Python scripts that I put in my bin - directory. No optional built-in modules needed. - -sockets Examples for the new built-in module 'socket'. - -threads Demos that use the 'thread' module. (Currently these - only run on SGIs, but this may change in the future.) - -tix Demos using the Tix widget set addition to Tkinter. - -tkinter Demos using the Tk interface (including Matt Conway's - excellent set of demos). - -xml Some XML demos. - -zlib Some demos for the zlib module (see also the standard - library module gzip.py). diff --git a/Demo/cgi/README b/Demo/cgi/README deleted file mode 100644 index c0631b6..0000000 --- a/Demo/cgi/README +++ /dev/null @@ -1,10 +0,0 @@ -CGI Examples ------------- - -Here are some example CGI programs. - -cgi0.sh -- A shell script to test your server is configured for CGI -cgi1.py -- A Python script to test your server is configured for CGI -cgi2.py -- A Python script showing how to parse a form -cgi3.py -- A Python script for driving an arbitrary CGI application -wiki.py -- Sample CGI application: a minimal Wiki implementation diff --git a/Demo/cgi/cgi0.sh b/Demo/cgi/cgi0.sh deleted file mode 100755 index 5cefcd3..0000000 --- a/Demo/cgi/cgi0.sh +++ /dev/null @@ -1,8 +0,0 @@ -#! /bin/sh - -# If you can't get this to work, your web server isn't set up right - -echo Content-type: text/plain -echo -echo Hello world -echo This is cgi0.sh diff --git a/Demo/cgi/cgi1.py b/Demo/cgi/cgi1.py deleted file mode 100755 index 842fef2..0000000 --- a/Demo/cgi/cgi1.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/local/bin/python - -"""CGI test 1 - check server setup.""" - -# Until you get this to work, your web server isn't set up right or -# your Python isn't set up right. - -# If cgi0.sh works but cgi1.py doesn't, check the #! line and the file -# permissions. The docs for the cgi.py module have debugging tips. - -print("Content-type: text/html") -print() -print("<h1>Hello world</h1>") -print("<p>This is cgi1.py") diff --git a/Demo/cgi/cgi2.py b/Demo/cgi/cgi2.py deleted file mode 100755 index 1d5822c..0000000 --- a/Demo/cgi/cgi2.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/local/bin/python - -"""CGI test 2 - basic use of cgi module.""" - -import cgitb; cgitb.enable() - -import cgi - -def main(): - form = cgi.FieldStorage() - print("Content-type: text/html") - print() - if not form: - print("<h1>No Form Keys</h1>") - else: - print("<h1>Form Keys</h1>") - for key in form.keys(): - value = form[key].value - print("<p>", cgi.escape(key), ":", cgi.escape(value)) - -if __name__ == "__main__": - main() diff --git a/Demo/cgi/cgi3.py b/Demo/cgi/cgi3.py deleted file mode 100755 index a3421b5..0000000 --- a/Demo/cgi/cgi3.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/local/bin/python - -"""CGI test 3 (persistent data).""" - -import cgitb; cgitb.enable() - -from wiki import main - -if __name__ == "__main__": - main() diff --git a/Demo/cgi/wiki.py b/Demo/cgi/wiki.py deleted file mode 100644 index 6b97113..0000000 --- a/Demo/cgi/wiki.py +++ /dev/null @@ -1,123 +0,0 @@ -"""Wiki main program. Imported and run by cgi3.py.""" - -import os, re, cgi, sys, tempfile -escape = cgi.escape - -def main(): - form = cgi.FieldStorage() - print("Content-type: text/html") - print() - cmd = form.getvalue("cmd", "view") - page = form.getvalue("page", "FrontPage") - wiki = WikiPage(page) - method = getattr(wiki, 'cmd_' + cmd, None) or wiki.cmd_view - method(form) - -class WikiPage: - - homedir = tempfile.gettempdir() - scripturl = os.path.basename(sys.argv[0]) - - def __init__(self, name): - if not self.iswikiword(name): - raise ValueError("page name is not a wiki word") - self.name = name - self.load() - - def cmd_view(self, form): - print("<h1>", escape(self.splitwikiword(self.name)), "</h1>") - print("<p>") - for line in self.data.splitlines(): - line = line.rstrip() - if not line: - print("<p>") - else: - print(self.formatline(line)) - print("<hr>") - print("<p>", self.mklink("edit", self.name, "Edit this page") + ";") - print(self.mklink("view", "FrontPage", "go to front page") + ".") - - def formatline(self, line): - words = [] - for word in re.split('(\W+)', line): - if self.iswikiword(word): - if os.path.isfile(self.mkfile(word)): - word = self.mklink("view", word, word) - else: - word = self.mklink("new", word, word + "*") - else: - word = escape(word) - words.append(word) - return "".join(words) - - def cmd_edit(self, form, label="Change"): - print("<h1>", label, self.name, "</h1>") - print('<form method="POST" action="%s">' % self.scripturl) - s = '<textarea cols="70" rows="20" name="text">%s</textarea>' - print(s % self.data) - print('<input type="hidden" name="cmd" value="create">') - print('<input type="hidden" name="page" value="%s">' % self.name) - print('<br>') - print('<input type="submit" value="%s Page">' % label) - print("</form>") - - def cmd_create(self, form): - self.data = form.getvalue("text", "").strip() - error = self.store() - if error: - print("<h1>I'm sorry. That didn't work</h1>") - print("<p>An error occurred while attempting to write the file:") - print("<p>", escape(error)) - else: - # Use a redirect directive, to avoid "reload page" problems - print("<head>") - s = '<meta http-equiv="refresh" content="1; URL=%s">' - print(s % (self.scripturl + "?cmd=view&page=" + self.name)) - print("<head>") - print("<h1>OK</h1>") - print("<p>If nothing happens, please click here:", end=' ') - print(self.mklink("view", self.name, self.name)) - - def cmd_new(self, form): - self.cmd_edit(form, label="Create") - - def iswikiword(self, word): - return re.match("[A-Z][a-z]+([A-Z][a-z]*)+", word) - - def splitwikiword(self, word): - chars = [] - for c in word: - if chars and c.isupper(): - chars.append(' ') - chars.append(c) - return "".join(chars) - - def mkfile(self, name=None): - if name is None: - name = self.name - return os.path.join(self.homedir, name + ".txt") - - def mklink(self, cmd, page, text): - link = self.scripturl + "?cmd=" + cmd + "&page=" + page - return '<a href="%s">%s</a>' % (link, text) - - def load(self): - try: - f = open(self.mkfile()) - data = f.read().strip() - f.close() - except IOError: - data = "" - self.data = data - - def store(self): - data = self.data - try: - f = open(self.mkfile(), "w") - f.write(data) - if data and not data.endswith('\n'): - f.write('\n') - f.close() - return "" - except IOError as err: - return "IOError: %s" % str(err) diff --git a/Demo/classes/Complex.py b/Demo/classes/Complex.py deleted file mode 100755 index 64c56d4..0000000 --- a/Demo/classes/Complex.py +++ /dev/null @@ -1,314 +0,0 @@ -# Complex numbers -# --------------- - -# [Now that Python has a complex data type built-in, this is not very -# useful, but it's still a nice example class] - -# This module represents complex numbers as instances of the class Complex. -# A Complex instance z has two data attribues, z.re (the real part) and z.im -# (the imaginary part). In fact, z.re and z.im can have any value -- all -# arithmetic operators work regardless of the type of z.re and z.im (as long -# as they support numerical operations). -# -# The following functions exist (Complex is actually a class): -# Complex([re [,im]) -> creates a complex number from a real and an imaginary part -# IsComplex(z) -> true iff z is a complex number (== has .re and .im attributes) -# ToComplex(z) -> a complex number equal to z; z itself if IsComplex(z) is true -# if z is a tuple(re, im) it will also be converted -# PolarToComplex([r [,phi [,fullcircle]]]) -> -# the complex number z for which r == z.radius() and phi == z.angle(fullcircle) -# (r and phi default to 0) -# exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z). -# -# Complex numbers have the following methods: -# z.abs() -> absolute value of z -# z.radius() == z.abs() -# z.angle([fullcircle]) -> angle from positive X axis; fullcircle gives units -# z.phi([fullcircle]) == z.angle(fullcircle) -# -# These standard functions and unary operators accept complex arguments: -# abs(z) -# -z -# +z -# not z -# repr(z) == `z` -# str(z) -# hash(z) -> a combination of hash(z.re) and hash(z.im) such that if z.im is zero -# the result equals hash(z.re) -# Note that hex(z) and oct(z) are not defined. -# -# These conversions accept complex arguments only if their imaginary part is zero: -# int(z) -# float(z) -# -# The following operators accept two complex numbers, or one complex number -# and one real number (int, long or float): -# z1 + z2 -# z1 - z2 -# z1 * z2 -# z1 / z2 -# pow(z1, z2) -# cmp(z1, z2) -# Note that z1 % z2 and divmod(z1, z2) are not defined, -# nor are shift and mask operations. -# -# The standard module math does not support complex numbers. -# The cmath modules should be used instead. -# -# Idea: -# add a class Polar(r, phi) and mixed-mode arithmetic which -# chooses the most appropriate type for the result: -# Complex for +,-,cmp -# Polar for *,/,pow - -import math -import sys - -twopi = math.pi*2.0 -halfpi = math.pi/2.0 - -def IsComplex(obj): - return hasattr(obj, 're') and hasattr(obj, 'im') - -def ToComplex(obj): - if IsComplex(obj): - return obj - elif isinstance(obj, tuple): - return Complex(*obj) - else: - return Complex(obj) - -def PolarToComplex(r = 0, phi = 0, fullcircle = twopi): - phi = phi * (twopi / fullcircle) - return Complex(math.cos(phi)*r, math.sin(phi)*r) - -def Re(obj): - if IsComplex(obj): - return obj.re - return obj - -def Im(obj): - if IsComplex(obj): - return obj.im - return 0 - -class Complex: - - def __init__(self, re=0, im=0): - _re = 0 - _im = 0 - if IsComplex(re): - _re = re.re - _im = re.im - else: - _re = re - if IsComplex(im): - _re = _re - im.im - _im = _im + im.re - else: - _im = _im + im - # this class is immutable, so setting self.re directly is - # not possible. - self.__dict__['re'] = _re - self.__dict__['im'] = _im - - def __setattr__(self, name, value): - raise TypeError('Complex numbers are immutable') - - def __hash__(self): - if not self.im: - return hash(self.re) - return hash((self.re, self.im)) - - def __repr__(self): - if not self.im: - return 'Complex(%r)' % (self.re,) - else: - return 'Complex(%r, %r)' % (self.re, self.im) - - def __str__(self): - if not self.im: - return repr(self.re) - else: - return 'Complex(%r, %r)' % (self.re, self.im) - - def __neg__(self): - return Complex(-self.re, -self.im) - - def __pos__(self): - return self - - def __abs__(self): - return math.hypot(self.re, self.im) - - def __int__(self): - if self.im: - raise ValueError("can't convert Complex with nonzero im to int") - return int(self.re) - - def __float__(self): - if self.im: - raise ValueError("can't convert Complex with nonzero im to float") - return float(self.re) - - def __cmp__(self, other): - other = ToComplex(other) - return cmp((self.re, self.im), (other.re, other.im)) - - def __rcmp__(self, other): - other = ToComplex(other) - return cmp(other, self) - - def __bool__(self): - return not (self.re == self.im == 0) - - abs = radius = __abs__ - - def angle(self, fullcircle = twopi): - return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi) - - phi = angle - - def __add__(self, other): - other = ToComplex(other) - return Complex(self.re + other.re, self.im + other.im) - - __radd__ = __add__ - - def __sub__(self, other): - other = ToComplex(other) - return Complex(self.re - other.re, self.im - other.im) - - def __rsub__(self, other): - other = ToComplex(other) - return other - self - - def __mul__(self, other): - other = ToComplex(other) - return Complex(self.re*other.re - self.im*other.im, - self.re*other.im + self.im*other.re) - - __rmul__ = __mul__ - - def __div__(self, other): - other = ToComplex(other) - d = float(other.re*other.re + other.im*other.im) - if not d: raise ZeroDivisionError('Complex division') - return Complex((self.re*other.re + self.im*other.im) / d, - (self.im*other.re - self.re*other.im) / d) - - def __rdiv__(self, other): - other = ToComplex(other) - return other / self - - def __pow__(self, n, z=None): - if z is not None: - raise TypeError('Complex does not support ternary pow()') - if IsComplex(n): - if n.im: - if self.im: raise TypeError('Complex to the Complex power') - else: return exp(math.log(self.re)*n) - n = n.re - r = pow(self.abs(), n) - phi = n*self.angle() - return Complex(math.cos(phi)*r, math.sin(phi)*r) - - def __rpow__(self, base): - base = ToComplex(base) - return pow(base, self) - -def exp(z): - r = math.exp(z.re) - return Complex(math.cos(z.im)*r,math.sin(z.im)*r) - - -def checkop(expr, a, b, value, fuzz = 1e-6): - print(' ', a, 'and', b, end=' ') - try: - result = eval(expr) - except: - result = sys.exc_info()[0] - print('->', result) - if isinstance(result, str) or isinstance(value, str): - ok = (result == value) - else: - ok = abs(result - value) <= fuzz - if not ok: - print('!!\t!!\t!! should be', value, 'diff', abs(result - value)) - -def test(): - print('test constructors') - constructor_test = ( - # "expect" is an array [re,im] "got" the Complex. - ( (0,0), Complex() ), - ( (0,0), Complex() ), - ( (1,0), Complex(1) ), - ( (0,1), Complex(0,1) ), - ( (1,2), Complex(Complex(1,2)) ), - ( (1,3), Complex(Complex(1,2),1) ), - ( (0,0), Complex(0,Complex(0,0)) ), - ( (3,4), Complex(3,Complex(4)) ), - ( (-1,3), Complex(1,Complex(3,2)) ), - ( (-7,6), Complex(Complex(1,2),Complex(4,8)) ) ) - cnt = [0,0] - for t in constructor_test: - cnt[0] += 1 - if ((t[0][0]!=t[1].re)or(t[0][1]!=t[1].im)): - print(" expected", t[0], "got", t[1]) - cnt[1] += 1 - print(" ", cnt[1], "of", cnt[0], "tests failed") - # test operators - testsuite = { - 'a+b': [ - (1, 10, 11), - (1, Complex(0,10), Complex(1,10)), - (Complex(0,10), 1, Complex(1,10)), - (Complex(0,10), Complex(1), Complex(1,10)), - (Complex(1), Complex(0,10), Complex(1,10)), - ], - 'a-b': [ - (1, 10, -9), - (1, Complex(0,10), Complex(1,-10)), - (Complex(0,10), 1, Complex(-1,10)), - (Complex(0,10), Complex(1), Complex(-1,10)), - (Complex(1), Complex(0,10), Complex(1,-10)), - ], - 'a*b': [ - (1, 10, 10), - (1, Complex(0,10), Complex(0, 10)), - (Complex(0,10), 1, Complex(0,10)), - (Complex(0,10), Complex(1), Complex(0,10)), - (Complex(1), Complex(0,10), Complex(0,10)), - ], - 'a/b': [ - (1., 10, 0.1), - (1, Complex(0,10), Complex(0, -0.1)), - (Complex(0, 10), 1, Complex(0, 10)), - (Complex(0, 10), Complex(1), Complex(0, 10)), - (Complex(1), Complex(0,10), Complex(0, -0.1)), - ], - 'pow(a,b)': [ - (1, 10, 1), - (1, Complex(0,10), 1), - (Complex(0,10), 1, Complex(0,10)), - (Complex(0,10), Complex(1), Complex(0,10)), - (Complex(1), Complex(0,10), 1), - (2, Complex(4,0), 16), - ], - 'cmp(a,b)': [ - (1, 10, -1), - (1, Complex(0,10), 1), - (Complex(0,10), 1, -1), - (Complex(0,10), Complex(1), -1), - (Complex(1), Complex(0,10), 1), - ], - } - for expr in sorted(testsuite): - print(expr + ':') - t = (expr,) - for item in testsuite[expr]: - checkop(*(t+item)) - - -if __name__ == '__main__': - test() diff --git a/Demo/classes/Dates.py b/Demo/classes/Dates.py deleted file mode 100755 index e1b054f..0000000 --- a/Demo/classes/Dates.py +++ /dev/null @@ -1,227 +0,0 @@ -# Class Date supplies date objects that support date arithmetic. -# -# Date(month,day,year) returns a Date object. An instance prints as, -# e.g., 'Mon 16 Aug 1993'. -# -# Addition, subtraction, comparison operators, min, max, and sorting -# all work as expected for date objects: int+date or date+int returns -# the date `int' days from `date'; date+date raises an exception; -# date-int returns the date `int' days before `date'; date2-date1 returns -# an integer, the number of days from date1 to date2; int-date raises an -# exception; date1 < date2 is true iff date1 occurs before date2 (& -# similarly for other comparisons); min(date1,date2) is the earlier of -# the two dates and max(date1,date2) the later; and date objects can be -# used as dictionary keys. -# -# Date objects support one visible method, date.weekday(). This returns -# the day of the week the date falls on, as a string. -# -# Date objects also have 4 read-only data attributes: -# .month in 1..12 -# .day in 1..31 -# .year int or long int -# .ord the ordinal of the date relative to an arbitrary staring point -# -# The Dates module also supplies function today(), which returns the -# current date as a date object. -# -# Those entranced by calendar trivia will be disappointed, as no attempt -# has been made to accommodate the Julian (etc) system. On the other -# hand, at least this package knows that 2000 is a leap year but 2100 -# isn't, and works fine for years with a hundred decimal digits <wink>. - -# Tim Peters tim@ksr.com -# not speaking for Kendall Square Research Corp - -# Adapted to Python 1.1 (where some hacks to overcome coercion are unnecessary) -# by Guido van Rossum - -# Note that as of Python 2.3, a datetime module is included in the stardard -# library. - -# vi:set tabsize=8: - -_MONTH_NAMES = [ 'January', 'February', 'March', 'April', 'May', - 'June', 'July', 'August', 'September', 'October', - 'November', 'December' ] - -_DAY_NAMES = [ 'Friday', 'Saturday', 'Sunday', 'Monday', - 'Tuesday', 'Wednesday', 'Thursday' ] - -_DAYS_IN_MONTH = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] - -_DAYS_BEFORE_MONTH = [] -dbm = 0 -for dim in _DAYS_IN_MONTH: - _DAYS_BEFORE_MONTH.append(dbm) - dbm = dbm + dim -del dbm, dim - -_INT_TYPES = type(1), type(1) - -def _is_leap(year): # 1 if leap year, else 0 - if year % 4 != 0: return 0 - if year % 400 == 0: return 1 - return year % 100 != 0 - -def _days_in_year(year): # number of days in year - return 365 + _is_leap(year) - -def _days_before_year(year): # number of days before year - return year*365 + (year+3)//4 - (year+99)//100 + (year+399)//400 - -def _days_in_month(month, year): # number of days in month of year - if month == 2 and _is_leap(year): return 29 - return _DAYS_IN_MONTH[month-1] - -def _days_before_month(month, year): # number of days in year before month - return _DAYS_BEFORE_MONTH[month-1] + (month > 2 and _is_leap(year)) - -def _date2num(date): # compute ordinal of date.month,day,year - return _days_before_year(date.year) + \ - _days_before_month(date.month, date.year) + \ - date.day - -_DI400Y = _days_before_year(400) # number of days in 400 years - -def _num2date(n): # return date with ordinal n - if type(n) not in _INT_TYPES: - raise TypeError('argument must be integer: %r' % type(n)) - - ans = Date(1,1,1) # arguments irrelevant; just getting a Date obj - del ans.ord, ans.month, ans.day, ans.year # un-initialize it - ans.ord = n - - n400 = (n-1)//_DI400Y # # of 400-year blocks preceding - year, n = 400 * n400, n - _DI400Y * n400 - more = n // 365 - dby = _days_before_year(more) - if dby >= n: - more = more - 1 - dby = dby - _days_in_year(more) - year, n = year + more, int(n - dby) - - try: year = int(year) # chop to int, if it fits - except (ValueError, OverflowError): pass - - month = min(n//29 + 1, 12) - dbm = _days_before_month(month, year) - if dbm >= n: - month = month - 1 - dbm = dbm - _days_in_month(month, year) - - ans.month, ans.day, ans.year = month, n-dbm, year - return ans - -def _num2day(n): # return weekday name of day with ordinal n - return _DAY_NAMES[ int(n % 7) ] - - -class Date: - def __init__(self, month, day, year): - if not 1 <= month <= 12: - raise ValueError('month must be in 1..12: %r' % (month,)) - dim = _days_in_month(month, year) - if not 1 <= day <= dim: - raise ValueError('day must be in 1..%r: %r' % (dim, day)) - self.month, self.day, self.year = month, day, year - self.ord = _date2num(self) - - # don't allow setting existing attributes - def __setattr__(self, name, value): - if name in self.__dict__: - raise AttributeError('read-only attribute ' + name) - self.__dict__[name] = value - - def __cmp__(self, other): - return cmp(self.ord, other.ord) - - # define a hash function so dates can be used as dictionary keys - def __hash__(self): - return hash(self.ord) - - # print as, e.g., Mon 16 Aug 1993 - def __repr__(self): - return '%.3s %2d %.3s %r' % ( - self.weekday(), - self.day, - _MONTH_NAMES[self.month-1], - self.year) - - # Python 1.1 coerces neither int+date nor date+int - def __add__(self, n): - if type(n) not in _INT_TYPES: - raise TypeError('can\'t add %r to date' % type(n)) - return _num2date(self.ord + n) - __radd__ = __add__ # handle int+date - - # Python 1.1 coerces neither date-int nor date-date - def __sub__(self, other): - if type(other) in _INT_TYPES: # date-int - return _num2date(self.ord - other) - else: - return self.ord - other.ord # date-date - - # complain about int-date - def __rsub__(self, other): - raise TypeError('Can\'t subtract date from integer') - - def weekday(self): - return _num2day(self.ord) - -def today(): - import time - local = time.localtime(time.time()) - return Date(local[1], local[2], local[0]) - -class DateTestError(Exception): - pass - -def test(firstyear, lastyear): - a = Date(9,30,1913) - b = Date(9,30,1914) - if repr(a) != 'Tue 30 Sep 1913': - raise DateTestError('__repr__ failure') - if (not a < b) or a == b or a > b or b != b: - raise DateTestError('__cmp__ failure') - if a+365 != b or 365+a != b: - raise DateTestError('__add__ failure') - if b-a != 365 or b-365 != a: - raise DateTestError('__sub__ failure') - try: - x = 1 - a - raise DateTestError('int-date should have failed') - except TypeError: - pass - try: - x = a + b - raise DateTestError('date+date should have failed') - except TypeError: - pass - if a.weekday() != 'Tuesday': - raise DateTestError('weekday() failure') - if max(a,b) is not b or min(a,b) is not a: - raise DateTestError('min/max failure') - d = {a-1:b, b:a+1} - if d[b-366] != b or d[a+(b-a)] != Date(10,1,1913): - raise DateTestError('dictionary failure') - - # verify date<->number conversions for first and last days for - # all years in firstyear .. lastyear - - lord = _days_before_year(firstyear) - y = firstyear - while y <= lastyear: - ford = lord + 1 - lord = ford + _days_in_year(y) - 1 - fd, ld = Date(1,1,y), Date(12,31,y) - if (fd.ord,ld.ord) != (ford,lord): - raise DateTestError('date->num failed', y) - fd, ld = _num2date(ford), _num2date(lord) - if (1,1,y,12,31,y) != \ - (fd.month,fd.day,fd.year,ld.month,ld.day,ld.year): - raise DateTestError('num->date failed', y) - y = y + 1 - -if __name__ == '__main__': - test(1850, 2150) diff --git a/Demo/classes/Dbm.py b/Demo/classes/Dbm.py deleted file mode 100755 index f931e93..0000000 --- a/Demo/classes/Dbm.py +++ /dev/null @@ -1,66 +0,0 @@ -# A wrapper around the (optional) built-in class dbm, supporting keys -# and values of almost any type instead of just string. -# (Actually, this works only for keys and values that can be read back -# correctly after being converted to a string.) - - -class Dbm: - - def __init__(self, filename, mode, perm): - import dbm.ndbm - self.db = dbm.ndbm.open(filename, mode, perm) - - def __repr__(self): - s = '' - for key in self.keys(): - t = repr(key) + ': ' + repr(self[key]) - if s: t = ', ' + t - s = s + t - return '{' + s + '}' - - def __len__(self): - return len(self.db) - - def __getitem__(self, key): - return eval(self.db[repr(key)]) - - def __setitem__(self, key, value): - self.db[repr(key)] = repr(value) - - def __delitem__(self, key): - del self.db[repr(key)] - - def keys(self): - res = [] - for key in self.db.keys(): - res.append(eval(key)) - return res - - def has_key(self, key): - return repr(key) in self.db - - -def test(): - d = Dbm('@dbm', 'rw', 0o600) - print(d) - while 1: - try: - key = eval(input('key: ')) - if key in d: - value = d[key] - print('currently:', value) - value = eval(input('value: ')) - if value is None: - del d[key] - else: - d[key] = value - except KeyboardInterrupt: - print('') - print(d) - except EOFError: - print('[eof]') - break - print(d) - - -test() diff --git a/Demo/classes/README b/Demo/classes/README deleted file mode 100644 index e5bc289..0000000 --- a/Demo/classes/README +++ /dev/null @@ -1,12 +0,0 @@ -Examples of classes that implement special operators (see reference manual): - -Complex.py Complex numbers -Dates.py Date manipulation package by Tim Peters -Dbm.py Wrapper around built-in dbm, supporting arbitrary values -Range.py Example of a generator: re-implement built-in range() -Rev.py Yield the reverse of a sequence -Vec.py A simple vector class -bitvec.py A bit-vector class by Jan-Hein B\"uhrman - -(For straightforward examples of basic class features, such as use of -methods and inheritance, see the library code.) diff --git a/Demo/classes/Range.py b/Demo/classes/Range.py deleted file mode 100755 index a0cef74..0000000 --- a/Demo/classes/Range.py +++ /dev/null @@ -1,93 +0,0 @@ -"""Example of a generator: re-implement the built-in range function -without actually constructing the list of values. - -OldStyleRange is coded in the way required to work in a 'for' loop before -iterators were introduced into the language; using __getitem__ and __len__ . - -""" -def handleargs(arglist): - """Take list of arguments and extract/create proper start, stop, and step - values and return in a tuple""" - try: - if len(arglist) == 1: - return 0, int(arglist[0]), 1 - elif len(arglist) == 2: - return int(arglist[0]), int(arglist[1]), 1 - elif len(arglist) == 3: - if arglist[2] == 0: - raise ValueError("step argument must not be zero") - return tuple(int(x) for x in arglist) - else: - raise TypeError("range() accepts 1-3 arguments, given", len(arglist)) - except TypeError: - raise TypeError("range() arguments must be numbers or strings " - "representing numbers") - -def genrange(*a): - """Function to implement 'range' as a generator""" - start, stop, step = handleargs(a) - value = start - while value < stop: - yield value - value += step - -class oldrange: - """Class implementing a range object. - To the user the instances feel like immutable sequences - (and you can't concatenate or slice them) - - Done using the old way (pre-iterators; __len__ and __getitem__) to have an - object be used by a 'for' loop. - - """ - - def __init__(self, *a): - """ Initialize start, stop, and step values along with calculating the - nubmer of values (what __len__ will return) in the range""" - self.start, self.stop, self.step = handleargs(a) - self.len = max(0, (self.stop - self.start) // self.step) - - def __repr__(self): - """implement repr(x) which is also used by print""" - return 'range(%r, %r, %r)' % (self.start, self.stop, self.step) - - def __len__(self): - """implement len(x)""" - return self.len - - def __getitem__(self, i): - """implement x[i]""" - if 0 <= i <= self.len: - return self.start + self.step * i - else: - raise IndexError('range[i] index out of range') - - -def test(): - import time, builtins - #Just a quick sanity check - correct_result = builtins.range(5, 100, 3) - oldrange_result = list(oldrange(5, 100, 3)) - genrange_result = list(genrange(5, 100, 3)) - if genrange_result != correct_result or oldrange_result != correct_result: - raise Exception("error in implementation:\ncorrect = %s" - "\nold-style = %s\ngenerator = %s" % - (correct_result, oldrange_result, genrange_result)) - print("Timings for range(1000):") - t1 = time.time() - for i in oldrange(1000): - pass - t2 = time.time() - for i in genrange(1000): - pass - t3 = time.time() - for i in builtins.range(1000): - pass - t4 = time.time() - print(t2-t1, 'sec (old-style class)') - print(t3-t2, 'sec (generator)') - print(t4-t3, 'sec (built-in)') - - -if __name__ == '__main__': - test() diff --git a/Demo/classes/Rev.py b/Demo/classes/Rev.py deleted file mode 100755 index 7fd78e0..0000000 --- a/Demo/classes/Rev.py +++ /dev/null @@ -1,95 +0,0 @@ -''' -A class which presents the reverse of a sequence without duplicating it. -From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> - -It works on mutable or inmutable sequences. - ->>> chars = list(Rev('Hello World!')) ->>> print ''.join(chars) -!dlroW olleH - -The .forw is so you can use anonymous sequences in __init__, and still -keep a reference the forward sequence. ) -If you give it a non-anonymous mutable sequence, the reverse sequence -will track the updated values. ( but not reassignment! - another -good reason to use anonymous values in creating the sequence to avoid -confusion. Maybe it should be change to copy input sequence to break -the connection completely ? ) - ->>> nnn = range(3) ->>> rnn = Rev(nnn) ->>> for n in rnn: print n -... -2 -1 -0 ->>> for n in range(4, 6): nnn.append(n) # update nnn -... ->>> for n in rnn: print n # prints reversed updated values -... -5 -4 -2 -1 -0 ->>> nnn = nnn[1:-1] ->>> nnn -[1, 2, 4] ->>> for n in rnn: print n # prints reversed values of old nnn -... -5 -4 -2 -1 -0 - -# ->>> WH = Rev('Hello World!') ->>> print WH.forw, WH.back -Hello World! !dlroW olleH ->>> nnn = Rev(range(1, 10)) ->>> print nnn.forw -[1, 2, 3, 4, 5, 6, 7, 8, 9] ->>> print nnn.back -[9, 8, 7, 6, 5, 4, 3, 2, 1] - ->>> rrr = Rev(nnn) ->>> rrr -<1, 2, 3, 4, 5, 6, 7, 8, 9> - -''' - -class Rev: - def __init__(self, seq): - self.forw = seq - self.back = self - - def __len__(self): - return len(self.forw) - - def __getitem__(self, j): - return self.forw[-(j + 1)] - - def __repr__(self): - seq = self.forw - if isinstance(seq, list): - wrap = '[]' - sep = ', ' - elif isinstance(seq, tuple): - wrap = '()' - sep = ', ' - elif isinstance(seq, str): - wrap = '' - sep = '' - else: - wrap = '<>' - sep = ', ' - outstrs = [str(item) for item in self.back] - return wrap[:1] + sep.join(outstrs) + wrap[-1:] - -def _test(): - import doctest, Rev - return doctest.testmod(Rev) - -if __name__ == "__main__": - _test() diff --git a/Demo/classes/Vec.py b/Demo/classes/Vec.py deleted file mode 100755 index 787af69..0000000 --- a/Demo/classes/Vec.py +++ /dev/null @@ -1,68 +0,0 @@ -class Vec: - """ A simple vector class - - Instances of the Vec class can be constructed from numbers - - >>> a = Vec(1, 2, 3) - >>> b = Vec(3, 2, 1) - - added - >>> a + b - Vec(4, 4, 4) - - subtracted - >>> a - b - Vec(-2, 0, 2) - - and multiplied by a scalar on the left - >>> 3.0 * a - Vec(3.0, 6.0, 9.0) - - or on the right - >>> a * 3.0 - Vec(3.0, 6.0, 9.0) - """ - def __init__(self, *v): - self.v = list(v) - - @classmethod - def fromlist(cls, v): - if not isinstance(v, list): - raise TypeError - inst = cls() - inst.v = v - return inst - - def __repr__(self): - args = ', '.join(repr(x) for x in self.v) - return 'Vec({})'.format(args) - - def __len__(self): - return len(self.v) - - def __getitem__(self, i): - return self.v[i] - - def __add__(self, other): - # Element-wise addition - v = [x + y for x, y in zip(self.v, other.v)] - return Vec.fromlist(v) - - def __sub__(self, other): - # Element-wise subtraction - v = [x - y for x, y in zip(self.v, other.v)] - return Vec.fromlist(v) - - def __mul__(self, scalar): - # Multiply by scalar - v = [x * scalar for x in self.v] - return Vec.fromlist(v) - - __rmul__ = __mul__ - - -def test(): - import doctest - doctest.testmod() - -test() diff --git a/Demo/classes/bitvec.py b/Demo/classes/bitvec.py deleted file mode 100755 index 62b26cc..0000000 --- a/Demo/classes/bitvec.py +++ /dev/null @@ -1,322 +0,0 @@ -# -# this is a rather strict implementation of a bit vector class -# it is accessed the same way as an array of python-ints, except -# the value must be 0 or 1 -# - -import sys; rprt = sys.stderr.write #for debugging - -class error(Exception): - pass - - -def _check_value(value): - if type(value) != type(0) or not 0 <= value < 2: - raise error('bitvec() items must have int value 0 or 1') - - -import math - -def _compute_len(param): - mant, l = math.frexp(float(param)) - bitmask = 1 << l - if bitmask <= param: - raise ValueError('(param, l) = %r' % ((param, l),)) - while l: - bitmask = bitmask >> 1 - if param & bitmask: - break - l = l - 1 - return l - - -def _check_key(len, key): - if type(key) != type(0): - raise TypeError('sequence subscript not int') - if key < 0: - key = key + len - if not 0 <= key < len: - raise IndexError('list index out of range') - return key - -def _check_slice(len, i, j): - #the type is ok, Python already checked that - i, j = max(i, 0), min(len, j) - if i > j: - i = j - return i, j - - -class BitVec: - - def __init__(self, *params): - self._data = 0 - self._len = 0 - if not len(params): - pass - elif len(params) == 1: - param, = params - if type(param) == type([]): - value = 0 - bit_mask = 1 - for item in param: - # strict check - #_check_value(item) - if item: - value = value | bit_mask - bit_mask = bit_mask << 1 - self._data = value - self._len = len(param) - elif type(param) == type(0): - if param < 0: - raise error('bitvec() can\'t handle negative longs') - self._data = param - self._len = _compute_len(param) - else: - raise error('bitvec() requires array or long parameter') - elif len(params) == 2: - param, length = params - if type(param) == type(0): - if param < 0: - raise error('can\'t handle negative longs') - self._data = param - if type(length) != type(0): - raise error('bitvec()\'s 2nd parameter must be int') - computed_length = _compute_len(param) - if computed_length > length: - print('warning: bitvec() value is longer than the length indicates, truncating value') - self._data = self._data & \ - ((1 << length) - 1) - self._len = length - else: - raise error('bitvec() requires array or long parameter') - else: - raise error('bitvec() requires 0 -- 2 parameter(s)') - - - def append(self, item): - #_check_value(item) - #self[self._len:self._len] = [item] - self[self._len:self._len] = \ - BitVec(int(not not item), 1) - - - def count(self, value): - #_check_value(value) - if value: - data = self._data - else: - data = (~self)._data - count = 0 - while data: - data, count = data >> 1, count + (data & 1 != 0) - return count - - - def index(self, value): - #_check_value(value): - if value: - data = self._data - else: - data = (~self)._data - index = 0 - if not data: - raise ValueError('list.index(x): x not in list') - while not (data & 1): - data, index = data >> 1, index + 1 - return index - - - def insert(self, index, item): - #_check_value(item) - #self[index:index] = [item] - self[index:index] = BitVec(int(not not item), 1) - - - def remove(self, value): - del self[self.index(value)] - - - def reverse(self): - #ouch, this one is expensive! - #for i in self._len>>1: self[i], self[l-i] = self[l-i], self[i] - data, result = self._data, 0 - for i in range(self._len): - if not data: - result = result << (self._len - i) - break - result, data = (result << 1) | (data & 1), data >> 1 - self._data = result - - - def sort(self): - c = self.count(1) - self._data = ((1 << c) - 1) << (self._len - c) - - - def copy(self): - return BitVec(self._data, self._len) - - - def seq(self): - result = [] - for i in self: - result.append(i) - return result - - - def __repr__(self): - ##rprt('<bitvec class instance object>.' + '__repr__()\n') - return 'bitvec(%r, %r)' % (self._data, self._len) - - def __cmp__(self, other, *rest): - #rprt('%r.__cmp__%r\n' % (self, (other,) + rest)) - if type(other) != type(self): - other = bitvec(other, *rest) - #expensive solution... recursive binary, with slicing - length = self._len - if length == 0 or other._len == 0: - return cmp(length, other._len) - if length != other._len: - min_length = min(length, other._len) - return cmp(self[:min_length], other[:min_length]) or \ - cmp(self[min_length:], other[min_length:]) - #the lengths are the same now... - if self._data == other._data: - return 0 - if length == 1: - return cmp(self[0], other[0]) - else: - length = length >> 1 - return cmp(self[:length], other[:length]) or \ - cmp(self[length:], other[length:]) - - - def __len__(self): - #rprt('%r.__len__()\n' % (self,)) - return self._len - - def __getitem__(self, key): - #rprt('%r.__getitem__(%r)\n' % (self, key)) - key = _check_key(self._len, key) - return self._data & (1 << key) != 0 - - def __setitem__(self, key, value): - #rprt('%r.__setitem__(%r, %r)\n' % (self, key, value)) - key = _check_key(self._len, key) - #_check_value(value) - if value: - self._data = self._data | (1 << key) - else: - self._data = self._data & ~(1 << key) - - def __delitem__(self, key): - #rprt('%r.__delitem__(%r)\n' % (self, key)) - key = _check_key(self._len, key) - #el cheapo solution... - self._data = self[:key]._data | self[key+1:]._data >> key - self._len = self._len - 1 - - def __getslice__(self, i, j): - #rprt('%r.__getslice__(%r, %r)\n' % (self, i, j)) - i, j = _check_slice(self._len, i, j) - if i >= j: - return BitVec(0, 0) - if i: - ndata = self._data >> i - else: - ndata = self._data - nlength = j - i - if j != self._len: - #we'll have to invent faster variants here - #e.g. mod_2exp - ndata = ndata & ((1 << nlength) - 1) - return BitVec(ndata, nlength) - - def __setslice__(self, i, j, sequence, *rest): - #rprt('%s.__setslice__%r\n' % (self, (i, j, sequence) + rest)) - i, j = _check_slice(self._len, i, j) - if type(sequence) != type(self): - sequence = bitvec(sequence, *rest) - #sequence is now of our own type - ls_part = self[:i] - ms_part = self[j:] - self._data = ls_part._data | \ - ((sequence._data | \ - (ms_part._data << sequence._len)) << ls_part._len) - self._len = self._len - j + i + sequence._len - - def __delslice__(self, i, j): - #rprt('%r.__delslice__(%r, %r)\n' % (self, i, j)) - i, j = _check_slice(self._len, i, j) - if i == 0 and j == self._len: - self._data, self._len = 0, 0 - elif i < j: - self._data = self[:i]._data | (self[j:]._data >> i) - self._len = self._len - j + i - - def __add__(self, other): - #rprt('%r.__add__(%r)\n' % (self, other)) - retval = self.copy() - retval[self._len:self._len] = other - return retval - - def __mul__(self, multiplier): - #rprt('%r.__mul__(%r)\n' % (self, multiplier)) - if type(multiplier) != type(0): - raise TypeError('sequence subscript not int') - if multiplier <= 0: - return BitVec(0, 0) - elif multiplier == 1: - return self.copy() - #handle special cases all 0 or all 1... - if self._data == 0: - return BitVec(0, self._len * multiplier) - elif (~self)._data == 0: - return ~BitVec(0, self._len * multiplier) - #otherwise el cheapo again... - retval = BitVec(0, 0) - while multiplier: - retval, multiplier = retval + self, multiplier - 1 - return retval - - def __and__(self, otherseq, *rest): - #rprt('%r.__and__%r\n' % (self, (otherseq,) + rest)) - if type(otherseq) != type(self): - otherseq = bitvec(otherseq, *rest) - #sequence is now of our own type - return BitVec(self._data & otherseq._data, \ - min(self._len, otherseq._len)) - - - def __xor__(self, otherseq, *rest): - #rprt('%r.__xor__%r\n' % (self, (otherseq,) + rest)) - if type(otherseq) != type(self): - otherseq = bitvec(otherseq, *rest) - #sequence is now of our own type - return BitVec(self._data ^ otherseq._data, \ - max(self._len, otherseq._len)) - - - def __or__(self, otherseq, *rest): - #rprt('%r.__or__%r\n' % (self, (otherseq,) + rest)) - if type(otherseq) != type(self): - otherseq = bitvec(otherseq, *rest) - #sequence is now of our own type - return BitVec(self._data | otherseq._data, \ - max(self._len, otherseq._len)) - - - def __invert__(self): - #rprt('%r.__invert__()\n' % (self,)) - return BitVec(~self._data & ((1 << self._len) - 1), \ - self._len) - - def __int__(self): - return int(self._data) - - def __float__(self): - return float(self._data) - - -bitvec = BitVec diff --git a/Demo/comparisons/README b/Demo/comparisons/README deleted file mode 100644 index 111667c..0000000 --- a/Demo/comparisons/README +++ /dev/null @@ -1,60 +0,0 @@ -Subject: Re: What language would you use? -From: Tom Christiansen <tchrist@mox.perl.com> -Date: 6 Nov 1994 15:14:51 GMT -Newsgroups: comp.lang.python,comp.lang.tcl,comp.lang.scheme,comp.lang.misc,comp.lang.perl -Message-Id: <39irtb$3t4@csnews.cs.Colorado.EDU> -References: <39b7ha$j9v@zeno.nscf.org> <39hhjp$lgn@csnews.cs.Colorado.EDU> <39hvsu$dus@mathserv.mps.ohio-state.edu> - -[...] -If you're really into benchmarks, I'd love it if someone were to code up -the following problems in tcl, python, and scheme (and whatever else you'd -like). Separate versions (one optimized for speed, one for beauty :-) are -ok. Post your code so we can time it on our own systems. - -0) Factorial Test (numerics and function calls) - - (we did this already) - -1) Regular Expressions Test - - Read a file of (extended per egrep) regular expressions (one per line), - and apply those to all files whose names are listed on the command line. - Basically, an 'egrep -f' simulator. Test it with 20 "vt100" patterns - against a five /etc/termcap files. Tests using more elaborate patters - would also be interesting. Your code should not break if given hundreds - of regular expressions or binary files to scan. - -2) Sorting Test - - Sort an input file that consists of lines like this - - var1=23 other=14 ditto=23 fred=2 - - such that each output line is sorted WRT to the number. Order - of output lines does not change. Resolve collisions using the - variable name. e.g. - - fred=2 other=14 ditto=23 var1=23 - - Lines may be up to several kilobytes in length and contain - zillions of variables. - -3) System Test - - Given a list of directories, report any bogus symbolic links contained - anywhere in those subtrees. A bogus symbolic link is one that cannot - be resolved because it points to a nonexistent or otherwise - unresolvable file. Do *not* use an external find executable. - Directories may be very very deep. Print a warning immediately if the - system you're running on doesn't support symbolic links. - - -I'll post perl solutions if people post the others. - - ---tom --- -Tom Christiansen Perl Consultant, Gamer, Hiker tchrist@mox.perl.com - - "But Billy! A *small* allowance prepares you for a lifetime of small - salaries and for your Social Security payments." --Family Circus diff --git a/Demo/comparisons/patterns b/Demo/comparisons/patterns deleted file mode 100755 index f4da846..0000000 --- a/Demo/comparisons/patterns +++ /dev/null @@ -1,4 +0,0 @@ -^def -^class -^import -^from diff --git a/Demo/comparisons/regextest.py b/Demo/comparisons/regextest.py deleted file mode 100755 index d2c534d..0000000 --- a/Demo/comparisons/regextest.py +++ /dev/null @@ -1,47 +0,0 @@ -#! /usr/bin/env python - -# 1) Regular Expressions Test -# -# Read a file of (extended per egrep) regular expressions (one per line), -# and apply those to all files whose names are listed on the command line. -# Basically, an 'egrep -f' simulator. Test it with 20 "vt100" patterns -# against a five /etc/termcap files. Tests using more elaborate patters -# would also be interesting. Your code should not break if given hundreds -# of regular expressions or binary files to scan. - -# This implementation: -# - combines all patterns into a single one using ( ... | ... | ... ) -# - reads patterns from stdin, scans files given as command line arguments -# - produces output in the format <file>:<lineno>:<line> -# - is only about 2.5 times as slow as egrep (though I couldn't run -# Tom's test -- this system, a vanilla SGI, only has /etc/terminfo) - -import string -import sys -import re - -def main(): - pats = list(map(chomp, sys.stdin.readlines())) - bigpat = '(' + '|'.join(pats) + ')' - prog = re.compile(bigpat) - - for file in sys.argv[1:]: - try: - fp = open(file, 'r') - except IOError as msg: - print("%s: %s" % (file, msg)) - continue - lineno = 0 - while 1: - line = fp.readline() - if not line: - break - lineno = lineno + 1 - if prog.search(line): - print("%s:%s:%s" % (file, lineno, line), end=' ') - -def chomp(s): - return s.rstrip('\n') - -if __name__ == '__main__': - main() diff --git a/Demo/comparisons/sortingtest.py b/Demo/comparisons/sortingtest.py deleted file mode 100755 index f9ed854..0000000 --- a/Demo/comparisons/sortingtest.py +++ /dev/null @@ -1,45 +0,0 @@ -#! /usr/bin/env python - -# 2) Sorting Test -# -# Sort an input file that consists of lines like this -# -# var1=23 other=14 ditto=23 fred=2 -# -# such that each output line is sorted WRT to the number. Order -# of output lines does not change. Resolve collisions using the -# variable name. e.g. -# -# fred=2 other=14 ditto=23 var1=23 -# -# Lines may be up to several kilobytes in length and contain -# zillions of variables. - -# This implementation: -# - Reads stdin, writes stdout -# - Uses any amount of whitespace to separate fields -# - Allows signed numbers -# - Treats illegally formatted fields as field=0 -# - Outputs the sorted fields with exactly one space between them -# - Handles blank input lines correctly - -import re -import sys - -def main(): - prog = re.compile('^(.*)=([-+]?[0-9]+)') - def makekey(item, prog=prog): - match = prog.match(item) - if match: - var, num = match.groups() - return int(num), var - else: - # Bad input -- pretend it's a var with value 0 - return 0, item - for line in sys.stdin: - items = sorted(makekey(item) for item in line.split()) - for num, var in items: - print("%s=%s" % (var, num), end=' ') - print() - -main() diff --git a/Demo/comparisons/systemtest.py b/Demo/comparisons/systemtest.py deleted file mode 100755 index e3d840e..0000000 --- a/Demo/comparisons/systemtest.py +++ /dev/null @@ -1,74 +0,0 @@ -#! /usr/bin/env python - -# 3) System Test -# -# Given a list of directories, report any bogus symbolic links contained -# anywhere in those subtrees. A bogus symbolic link is one that cannot -# be resolved because it points to a nonexistent or otherwise -# unresolvable file. Do *not* use an external find executable. -# Directories may be very very deep. Print a warning immediately if the -# system you're running on doesn't support symbolic links. - -# This implementation: -# - takes one optional argument, using the current directory as default -# - uses chdir to increase performance -# - sorts the names per directory -# - prints output lines of the form "path1 -> path2" as it goes -# - prints error messages about directories it can't list or chdir into - -import os -import sys -from stat import * - -def main(): - try: - # Note: can't test for presence of lstat -- it's always there - dummy = os.readlink - except AttributeError: - print("This system doesn't have symbolic links") - sys.exit(0) - if sys.argv[1:]: - prefix = sys.argv[1] - else: - prefix = '' - if prefix: - os.chdir(prefix) - if prefix[-1:] != '/': prefix = prefix + '/' - reportboguslinks(prefix) - else: - reportboguslinks('') - -def reportboguslinks(prefix): - try: - names = os.listdir('.') - except os.error as msg: - print("%s%s: can't list: %s" % (prefix, '.', msg)) - return - names.sort() - for name in names: - if name == os.curdir or name == os.pardir: - continue - try: - mode = os.lstat(name)[ST_MODE] - except os.error: - print("%s%s: can't stat: %s" % (prefix, name, msg)) - continue - if S_ISLNK(mode): - try: - os.stat(name) - except os.error: - print("%s%s -> %s" % \ - (prefix, name, os.readlink(name))) - elif S_ISDIR(mode): - try: - os.chdir(name) - except os.error as msg: - print("%s%s: can't chdir: %s" % \ - (prefix, name, msg)) - continue - try: - reportboguslinks(prefix + name + '/') - finally: - os.chdir('..') - -main() diff --git a/Demo/curses/README b/Demo/curses/README deleted file mode 100644 index 2d1c4b1..0000000 --- a/Demo/curses/README +++ /dev/null @@ -1,25 +0,0 @@ -This is a collection of demos and tests for the curses module. - -ncurses demos -============= - -These demos are converted from the C versions in the ncurses -distribution, and were contributed by Thomas Gellekum <tg@FreeBSD.org> -I didn't strive for a `pythonic' style, but bluntly copied the -originals. I won't attempt to `beautify' the program anytime soon, but -I wouldn't mind someone else making an effort in that direction, of -course. - -ncurses.py -- currently only a panels demo -rain.py -- raindrops keep falling on my desktop -tclock.py -- ASCII clock, by Howard Jones -xmas.py -- I'm dreaming of an ASCII christmas - -Please submit bugfixes and new contributions to the Python bug tracker. - - -Other demos -=========== - -life.py -- Simple game of Life -repeat.py -- Repeatedly execute a shell command (like watch(1)) diff --git a/Demo/curses/life.py b/Demo/curses/life.py deleted file mode 100755 index ddff8fa..0000000 --- a/Demo/curses/life.py +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/env python -# life.py -- A curses-based version of Conway's Game of Life. -# Contributed by AMK -# -# An empty board will be displayed, and the following commands are available: -# E : Erase the board -# R : Fill the board randomly -# S : Step for a single generation -# C : Update continuously until a key is struck -# Q : Quit -# Cursor keys : Move the cursor around the board -# Space or Enter : Toggle the contents of the cursor's position -# -# TODO : -# Support the mouse -# Use colour if available -# Make board updates faster -# - -import random, string, traceback -import curses - -class LifeBoard: - """Encapsulates a Life board - - Attributes: - X,Y : horizontal and vertical size of the board - state : dictionary mapping (x,y) to 0 or 1 - - Methods: - display(update_board) -- If update_board is true, compute the - next generation. Then display the state - of the board and refresh the screen. - erase() -- clear the entire board - makeRandom() -- fill the board randomly - set(y,x) -- set the given cell to Live; doesn't refresh the screen - toggle(y,x) -- change the given cell from live to dead, or vice - versa, and refresh the screen display - - """ - def __init__(self, scr, char=ord('*')): - """Create a new LifeBoard instance. - - scr -- curses screen object to use for display - char -- character used to render live cells (default: '*') - """ - self.state = {} - self.scr = scr - Y, X = self.scr.getmaxyx() - self.X, self.Y = X-2, Y-2-1 - self.char = char - self.scr.clear() - - # Draw a border around the board - border_line = '+'+(self.X*'-')+'+' - self.scr.addstr(0, 0, border_line) - self.scr.addstr(self.Y+1,0, border_line) - for y in range(0, self.Y): - self.scr.addstr(1+y, 0, '|') - self.scr.addstr(1+y, self.X+1, '|') - self.scr.refresh() - - def set(self, y, x): - """Set a cell to the live state""" - if x<0 or self.X<=x or y<0 or self.Y<=y: - raise ValueError("Coordinates out of range %i,%i"% (y,x)) - self.state[x,y] = 1 - - def toggle(self, y, x): - """Toggle a cell's state between live and dead""" - if x<0 or self.X<=x or y<0 or self.Y<=y: - raise ValueError("Coordinates out of range %i,%i"% (y,x)) - if (x,y) in self.state: - del self.state[x,y] - self.scr.addch(y+1, x+1, ' ') - else: - self.state[x,y] = 1 - self.scr.addch(y+1, x+1, self.char) - self.scr.refresh() - - def erase(self): - """Clear the entire board and update the board display""" - self.state = {} - self.display(update_board=False) - - def display(self, update_board=True): - """Display the whole board, optionally computing one generation""" - M,N = self.X, self.Y - if not update_board: - for i in range(0, M): - for j in range(0, N): - if (i,j) in self.state: - self.scr.addch(j+1, i+1, self.char) - else: - self.scr.addch(j+1, i+1, ' ') - self.scr.refresh() - return - - d = {} - self.boring = 1 - for i in range(0, M): - L = range( max(0, i-1), min(M, i+2) ) - for j in range(0, N): - s = 0 - live = (i,j) in self.state - for k in range( max(0, j-1), min(N, j+2) ): - for l in L: - if (l,k) in self.state: - s += 1 - s -= live - if s == 3: - # Birth - d[i,j] = 1 - self.scr.addch(j+1, i+1, self.char) - if not live: self.boring = 0 - elif s == 2 and live: d[i,j] = 1 # Survival - elif live: - # Death - self.scr.addch(j+1, i+1, ' ') - self.boring = 0 - self.state = d - self.scr.refresh() - - def makeRandom(self): - "Fill the board with a random pattern" - self.state = {} - for i in range(0, self.X): - for j in range(0, self.Y): - if random.random() > 0.5: - self.set(j,i) - - -def erase_menu(stdscr, menu_y): - "Clear the space where the menu resides" - stdscr.move(menu_y, 0) - stdscr.clrtoeol() - stdscr.move(menu_y+1, 0) - stdscr.clrtoeol() - -def display_menu(stdscr, menu_y): - "Display the menu of possible keystroke commands" - erase_menu(stdscr, menu_y) - stdscr.addstr(menu_y, 4, - 'Use the cursor keys to move, and space or Enter to toggle a cell.') - stdscr.addstr(menu_y+1, 4, - 'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit') - -def keyloop(stdscr): - # Clear the screen and display the menu of keys - stdscr.clear() - stdscr_y, stdscr_x = stdscr.getmaxyx() - menu_y = (stdscr_y-3)-1 - display_menu(stdscr, menu_y) - - # Allocate a subwindow for the Life board and create the board object - subwin = stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0) - board = LifeBoard(subwin, char=ord('*')) - board.display(update_board=False) - - # xpos, ypos are the cursor's position - xpos, ypos = board.X//2, board.Y//2 - - # Main loop: - while (1): - stdscr.move(1+ypos, 1+xpos) # Move the cursor - c = stdscr.getch() # Get a keystroke - if 0<c<256: - c = chr(c) - if c in ' \n': - board.toggle(ypos, xpos) - elif c in 'Cc': - erase_menu(stdscr, menu_y) - stdscr.addstr(menu_y, 6, ' Hit any key to stop continuously ' - 'updating the screen.') - stdscr.refresh() - # Activate nodelay mode; getch() will return -1 - # if no keystroke is available, instead of waiting. - stdscr.nodelay(1) - while (1): - c = stdscr.getch() - if c != -1: - break - stdscr.addstr(0,0, '/') - stdscr.refresh() - board.display() - stdscr.addstr(0,0, '+') - stdscr.refresh() - - stdscr.nodelay(0) # Disable nodelay mode - display_menu(stdscr, menu_y) - - elif c in 'Ee': - board.erase() - elif c in 'Qq': - break - elif c in 'Rr': - board.makeRandom() - board.display(update_board=False) - elif c in 'Ss': - board.display() - else: pass # Ignore incorrect keys - elif c == curses.KEY_UP and ypos>0: ypos -= 1 - elif c == curses.KEY_DOWN and ypos<board.Y-1: ypos += 1 - elif c == curses.KEY_LEFT and xpos>0: xpos -= 1 - elif c == curses.KEY_RIGHT and xpos<board.X-1: xpos += 1 - else: - # Ignore incorrect keys - pass - - -def main(stdscr): - keyloop(stdscr) # Enter the main loop - - -if __name__ == '__main__': - curses.wrapper(main) diff --git a/Demo/curses/ncurses.py b/Demo/curses/ncurses.py deleted file mode 100644 index 0bdc1a9..0000000 --- a/Demo/curses/ncurses.py +++ /dev/null @@ -1,273 +0,0 @@ -#!/usr/bin/env python -# -# $Id$ -# -# (n)curses exerciser in Python, an interactive test for the curses -# module. Currently, only the panel demos are ported. - -import curses -from curses import panel - -def wGetchar(win = None): - if win is None: win = stdscr - return win.getch() - -def Getchar(): - wGetchar() - -# -# Panels tester -# -def wait_a_while(): - if nap_msec == 1: - Getchar() - else: - curses.napms(nap_msec) - -def saywhat(text): - stdscr.move(curses.LINES - 1, 0) - stdscr.clrtoeol() - stdscr.addstr(text) - -def mkpanel(color, rows, cols, tly, tlx): - win = curses.newwin(rows, cols, tly, tlx) - pan = panel.new_panel(win) - if curses.has_colors(): - if color == curses.COLOR_BLUE: - fg = curses.COLOR_WHITE - else: - fg = curses.COLOR_BLACK - bg = color - curses.init_pair(color, fg, bg) - win.bkgdset(ord(' '), curses.color_pair(color)) - else: - win.bkgdset(ord(' '), curses.A_BOLD) - - return pan - -def pflush(): - panel.update_panels() - curses.doupdate() - -def fill_panel(pan): - win = pan.window() - num = pan.userptr()[1] - - win.move(1, 1) - win.addstr("-pan%c-" % num) - win.clrtoeol() - win.box() - - maxy, maxx = win.getmaxyx() - for y in range(2, maxy - 1): - for x in range(1, maxx - 1): - win.move(y, x) - win.addch(num) - -def demo_panels(win): - global stdscr, nap_msec, mod - stdscr = win - nap_msec = 1 - mod = ["test", "TEST", "(**)", "*()*", "<-->", "LAST"] - - stdscr.refresh() - - for y in range(0, curses.LINES - 1): - for x in range(0, curses.COLS): - stdscr.addstr("%d" % ((y + x) % 10)) - for y in range(0, 1): - p1 = mkpanel(curses.COLOR_RED, - curses.LINES // 2 - 2, - curses.COLS // 8 + 1, - 0, - 0) - p1.set_userptr("p1") - - p2 = mkpanel(curses.COLOR_GREEN, - curses.LINES // 2 + 1, - curses.COLS // 7, - curses.LINES // 4, - curses.COLS // 10) - p2.set_userptr("p2") - - p3 = mkpanel(curses.COLOR_YELLOW, - curses.LINES // 4, - curses.COLS // 10, - curses.LINES // 2, - curses.COLS // 9) - p3.set_userptr("p3") - - p4 = mkpanel(curses.COLOR_BLUE, - curses.LINES // 2 - 2, - curses.COLS // 8, - curses.LINES // 2 - 2, - curses.COLS // 3) - p4.set_userptr("p4") - - p5 = mkpanel(curses.COLOR_MAGENTA, - curses.LINES // 2 - 2, - curses.COLS // 8, - curses.LINES // 2, - curses.COLS // 2 - 2) - p5.set_userptr("p5") - - fill_panel(p1) - fill_panel(p2) - fill_panel(p3) - fill_panel(p4) - fill_panel(p5) - p4.hide() - p5.hide() - pflush() - saywhat("press any key to continue") - wait_a_while() - - saywhat("h3 s1 s2 s4 s5;press any key to continue") - p1.move(0, 0) - p3.hide() - p1.show() - p2.show() - p4.show() - p5.show() - pflush() - wait_a_while() - - saywhat("s1; press any key to continue") - p1.show() - pflush() - wait_a_while() - - saywhat("s2; press any key to continue") - p2.show() - pflush() - wait_a_while() - - saywhat("m2; press any key to continue") - p2.move(curses.LINES // 3 + 1, curses.COLS // 8) - pflush() - wait_a_while() - - saywhat("s3; press any key to continue") - p3.show() - pflush() - wait_a_while() - - saywhat("m3; press any key to continue") - p3.move(curses.LINES // 4 + 1, curses.COLS // 15) - pflush() - wait_a_while() - - saywhat("b3; press any key to continue") - p3.bottom() - pflush() - wait_a_while() - - saywhat("s4; press any key to continue") - p4.show() - pflush() - wait_a_while() - - saywhat("s5; press any key to continue") - p5.show() - pflush() - wait_a_while() - - saywhat("t3; press any key to continue") - p3.top() - pflush() - wait_a_while() - - saywhat("t1; press any key to continue") - p1.show() - pflush() - wait_a_while() - - saywhat("t2; press any key to continue") - p2.show() - pflush() - wait_a_while() - - saywhat("t3; press any key to continue") - p3.show() - pflush() - wait_a_while() - - saywhat("t4; press any key to continue") - p4.show() - pflush() - wait_a_while() - - for itmp in range(0, 6): - w4 = p4.window() - w5 = p5.window() - - saywhat("m4; press any key to continue") - w4.move(curses.LINES // 8, 1) - w4.addstr(mod[itmp]) - p4.move(curses.LINES // 6, itmp * curses.COLS // 8) - w5.move(curses.LINES // 6, 1) - w5.addstr(mod[itmp]) - pflush() - wait_a_while() - - saywhat("m5; press any key to continue") - w4.move(curses.LINES // 6, 1) - w4.addstr(mod[itmp]) - p5.move(curses.LINES // 3 - 1, itmp * 10 + 6) - w5.move(curses.LINES // 8, 1) - w5.addstr(mod[itmp]) - pflush() - wait_a_while() - - saywhat("m4; press any key to continue") - p4.move(curses.LINES // 6, (itmp + 1) * curses.COLS // 8) - pflush() - wait_a_while() - - saywhat("t5; press any key to continue") - p5.top() - pflush() - wait_a_while() - - saywhat("t2; press any key to continue") - p2.top() - pflush() - wait_a_while() - - saywhat("t1; press any key to continue") - p1.top() - pflush() - wait_a_while() - - saywhat("d2; press any key to continue") - del p2 - pflush() - wait_a_while() - - saywhat("h3; press any key to continue") - p3.hide() - pflush() - wait_a_while() - - saywhat("d1; press any key to continue") - del p1 - pflush() - wait_a_while() - - saywhat("d4; press any key to continue") - del p4 - pflush() - wait_a_while() - - saywhat("d5; press any key to continue") - del p5 - pflush() - wait_a_while() - if nap_msec == 1: - break - nap_msec = 100 - -# -# one fine day there'll be the menu at this place -# -curses.wrapper(demo_panels) diff --git a/Demo/curses/rain.py b/Demo/curses/rain.py deleted file mode 100644 index 9d46e6e..0000000 --- a/Demo/curses/rain.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python -# -# $Id$ -# -# somebody should probably check the randrange()s... - -import curses -from random import randrange - -def next_j(j): - if j == 0: - j = 4 - else: - j -= 1 - - if curses.has_colors(): - z = randrange(0, 3) - color = curses.color_pair(z) - if z: - color = color | curses.A_BOLD - stdscr.attrset(color) - - return j - -def main(win): - # we know that the first argument from curses.wrapper() is stdscr. - # Initialize it globally for convenience. - global stdscr - stdscr = win - - if curses.has_colors(): - bg = curses.COLOR_BLACK - curses.init_pair(1, curses.COLOR_BLUE, bg) - curses.init_pair(2, curses.COLOR_CYAN, bg) - - curses.nl() - curses.noecho() - # XXX curs_set() always returns ERR - # curses.curs_set(0) - stdscr.timeout(0) - - c = curses.COLS - 4 - r = curses.LINES - 4 - xpos = [0] * c - ypos = [0] * r - for j in range(4, -1, -1): - xpos[j] = randrange(0, c) + 2 - ypos[j] = randrange(0, r) + 2 - - j = 0 - while True: - x = randrange(0, c) + 2 - y = randrange(0, r) + 2 - - stdscr.addch(y, x, ord('.')) - - stdscr.addch(ypos[j], xpos[j], ord('o')) - - j = next_j(j) - stdscr.addch(ypos[j], xpos[j], ord('O')) - - j = next_j(j) - stdscr.addch( ypos[j] - 1, xpos[j], ord('-')) - stdscr.addstr(ypos[j], xpos[j] - 1, "|.|") - stdscr.addch( ypos[j] + 1, xpos[j], ord('-')) - - j = next_j(j) - stdscr.addch( ypos[j] - 2, xpos[j], ord('-')) - stdscr.addstr(ypos[j] - 1, xpos[j] - 1, "/ \\") - stdscr.addstr(ypos[j], xpos[j] - 2, "| O |") - stdscr.addstr(ypos[j] + 1, xpos[j] - 1, "\\ /") - stdscr.addch( ypos[j] + 2, xpos[j], ord('-')) - - j = next_j(j) - stdscr.addch( ypos[j] - 2, xpos[j], ord(' ')) - stdscr.addstr(ypos[j] - 1, xpos[j] - 1, " ") - stdscr.addstr(ypos[j], xpos[j] - 2, " ") - stdscr.addstr(ypos[j] + 1, xpos[j] - 1, " ") - stdscr.addch( ypos[j] + 2, xpos[j], ord(' ')) - - xpos[j] = x - ypos[j] = y - - ch = stdscr.getch() - if ch == ord('q') or ch == ord('Q'): - return - elif ch == ord('s'): - stdscr.nodelay(0) - elif ch == ord(' '): - stdscr.nodelay(1) - - curses.napms(50) - -curses.wrapper(main) diff --git a/Demo/curses/repeat.py b/Demo/curses/repeat.py deleted file mode 100755 index 93372c5..0000000 --- a/Demo/curses/repeat.py +++ /dev/null @@ -1,80 +0,0 @@ -#! /usr/bin/env python - -"""repeat [-i SECONDS] <shell-command> - -This simple program repeatedly (at 1-second intervals) executes the -shell command given on the command line and displays the output (or as -much of it as fits on the screen). It uses curses to paint each new -output on top of the old output, so that if nothing changes, the -screen doesn't change. This is handy to watch for changes in e.g. a -directory or process listing. - -The -i option lets you override the sleep time between executions. - -To end, hit Control-C. -""" - -# Author: Guido van Rossum - -# Disclaimer: there's a Linux program named 'watch' that does the same -# thing. Honestly, I didn't know of its existence when I wrote this! - -# To do: add features until it has the same functionality as watch(1); -# then compare code size and development time. - -import os -import sys -import time -import curses -import getopt - -def main(): - interval = 1.0 - try: - opts, args = getopt.getopt(sys.argv[1:], "hi:") - except getopt.error as err: - print(err, file=sys.stderr) - sys.exit(2) - if not args: - print(__doc__) - sys.exit(0) - for opt, arg in opts: - if opt == "-i": - interval = float(arg) - if opt == "-h": - print(__doc__) - sys.exit(0) - cmd = " ".join(args) - cmd_really = cmd + " 2>&1" - p = os.popen(cmd_really, "r") - text = p.read() - sts = p.close() - text = addsts(interval, cmd, text, sts) - w = curses.initscr() - try: - while True: - w.erase() - try: - w.addstr(text) - except curses.error: - pass - w.refresh() - time.sleep(interval) - p = os.popen(cmd_really, "r") - text = p.read() - sts = p.close() - text = addsts(interval, cmd, text, sts) - finally: - curses.endwin() - -def addsts(interval, cmd, text, sts): - now = time.strftime("%H:%M:%S") - text = "%s, every %g sec: %s\n%s" % (now, interval, cmd, text) - if sts: - msg = "Exit status: %d; signal: %d" % (sts>>8, sts&0xFF) - if text and not text.endswith("\n"): - msg = "\n" + msg - text += msg - return text - -main() diff --git a/Demo/curses/tclock.py b/Demo/curses/tclock.py deleted file mode 100644 index 8058d9a..0000000 --- a/Demo/curses/tclock.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env python -# -# $Id$ -# -# From tclock.c, Copyright Howard Jones <ha.jones@ic.ac.uk>, September 1994. - -from math import * -import curses, time - -ASPECT = 2.2 - -def sign(_x): - if _x < 0: return -1 - return 1 - -def A2XY(angle, radius): - return (int(round(ASPECT * radius * sin(angle))), - int(round(radius * cos(angle)))) - -def plot(x, y, col): - stdscr.addch(y, x, col) - -# draw a diagonal line using Bresenham's algorithm -def dline(pair, from_x, from_y, x2, y2, ch): - if curses.has_colors(): - stdscr.attrset(curses.color_pair(pair)) - - dx = x2 - from_x - dy = y2 - from_y - - ax = abs(dx * 2) - ay = abs(dy * 2) - - sx = sign(dx) - sy = sign(dy) - - x = from_x - y = from_y - - if ax > ay: - d = ay - ax // 2 - - while True: - plot(x, y, ch) - if x == x2: - return - - if d >= 0: - y += sy - d -= ax - x += sx - d += ay - else: - d = ax - ay // 2 - - while True: - plot(x, y, ch) - if y == y2: - return - - if d >= 0: - x += sx - d -= ay - y += sy - d += ax - -def main(win): - global stdscr - stdscr = win - - lastbeep = -1 - my_bg = curses.COLOR_BLACK - - stdscr.nodelay(1) - stdscr.timeout(0) -# curses.curs_set(0) - if curses.has_colors(): - curses.init_pair(1, curses.COLOR_RED, my_bg) - curses.init_pair(2, curses.COLOR_MAGENTA, my_bg) - curses.init_pair(3, curses.COLOR_GREEN, my_bg) - - cx = (curses.COLS - 1) // 2 - cy = curses.LINES // 2 - ch = min( cy-1, int(cx // ASPECT) - 1) - mradius = (3 * ch) // 4 - hradius = ch // 2 - sradius = 5 * ch // 6 - - for i in range(0, 12): - sangle = (i + 1) * 2.0 * pi / 12.0 - sdx, sdy = A2XY(sangle, sradius) - - stdscr.addstr(cy - sdy, cx + sdx, "%d" % (i + 1)) - - stdscr.addstr(0, 0, - "ASCII Clock by Howard Jones <ha.jones@ic.ac.uk>, 1994") - - sradius = max(sradius-4, 8) - - while True: - curses.napms(1000) - - tim = time.time() - t = time.localtime(tim) - - hours = t[3] + t[4] / 60.0 - if hours > 12.0: - hours -= 12.0 - - mangle = t[4] * 2 * pi / 60.0 - mdx, mdy = A2XY(mangle, mradius) - - hangle = hours * 2 * pi / 12.0 - hdx, hdy = A2XY(hangle, hradius) - - sangle = t[5] * 2 * pi / 60.0 - sdx, sdy = A2XY(sangle, sradius) - - dline(3, cx, cy, cx + mdx, cy - mdy, ord('#')) - - stdscr.attrset(curses.A_REVERSE) - dline(2, cx, cy, cx + hdx, cy - hdy, ord('.')) - stdscr.attroff(curses.A_REVERSE) - - if curses.has_colors(): - stdscr.attrset(curses.color_pair(1)) - - plot(cx + sdx, cy - sdy, ord('O')) - - if curses.has_colors(): - stdscr.attrset(curses.color_pair(0)) - - stdscr.addstr(curses.LINES - 2, 0, time.ctime(tim)) - stdscr.refresh() - if (t[5] % 5) == 0 and t[5] != lastbeep: - lastbeep = t[5] - curses.beep() - - ch = stdscr.getch() - if ch == ord('q'): - return 0 - - plot(cx + sdx, cy - sdy, ord(' ')) - dline(0, cx, cy, cx + hdx, cy - hdy, ord(' ')) - dline(0, cx, cy, cx + mdx, cy - mdy, ord(' ')) - -curses.wrapper(main) diff --git a/Demo/curses/xmas.py b/Demo/curses/xmas.py deleted file mode 100644 index 349b3a8..0000000 --- a/Demo/curses/xmas.py +++ /dev/null @@ -1,906 +0,0 @@ -# asciixmas -# December 1989 Larry Bartz Indianapolis, IN -# -# $Id$ -# -# I'm dreaming of an ascii character-based monochrome Christmas, -# Just like the ones I used to know! -# Via a full duplex communications channel, -# At 9600 bits per second, -# Even though it's kinda slow. -# -# I'm dreaming of an ascii character-based monochrome Christmas, -# With ev'ry C program I write! -# May your screen be merry and bright! -# And may all your Christmases be amber or green, -# (for reduced eyestrain and improved visibility)! -# -# -# Notes on the Python version: -# I used a couple of `try...except curses.error' to get around some functions -# returning ERR. The errors come from using wrapping functions to fill -# windows to the last character cell. The C version doesn't have this problem, -# it simply ignores any return values. -# - -import curses -import sys - -FROMWHO = "Thomas Gellekum <tg@FreeBSD.org>" - -def set_color(win, color): - if curses.has_colors(): - n = color + 1 - curses.init_pair(n, color, my_bg) - win.attroff(curses.A_COLOR) - win.attron(curses.color_pair(n)) - -def unset_color(win): - if curses.has_colors(): - win.attrset(curses.color_pair(0)) - -def look_out(msecs): - curses.napms(msecs) - if stdscr.getch() != -1: - curses.beep() - sys.exit(0) - -def boxit(): - for y in range(0, 20): - stdscr.addch(y, 7, ord('|')) - - for x in range(8, 80): - stdscr.addch(19, x, ord('_')) - - for x in range(0, 80): - stdscr.addch(22, x, ord('_')) - - return - -def seas(): - stdscr.addch(4, 1, ord('S')) - stdscr.addch(6, 1, ord('E')) - stdscr.addch(8, 1, ord('A')) - stdscr.addch(10, 1, ord('S')) - stdscr.addch(12, 1, ord('O')) - stdscr.addch(14, 1, ord('N')) - stdscr.addch(16, 1, ord("'")) - stdscr.addch(18, 1, ord('S')) - - return - -def greet(): - stdscr.addch(3, 5, ord('G')) - stdscr.addch(5, 5, ord('R')) - stdscr.addch(7, 5, ord('E')) - stdscr.addch(9, 5, ord('E')) - stdscr.addch(11, 5, ord('T')) - stdscr.addch(13, 5, ord('I')) - stdscr.addch(15, 5, ord('N')) - stdscr.addch(17, 5, ord('G')) - stdscr.addch(19, 5, ord('S')) - - return - -def fromwho(): - stdscr.addstr(21, 13, FROMWHO) - return - -def tree(): - set_color(treescrn, curses.COLOR_GREEN) - treescrn.addch(1, 11, ord('/')) - treescrn.addch(2, 11, ord('/')) - treescrn.addch(3, 10, ord('/')) - treescrn.addch(4, 9, ord('/')) - treescrn.addch(5, 9, ord('/')) - treescrn.addch(6, 8, ord('/')) - treescrn.addch(7, 7, ord('/')) - treescrn.addch(8, 6, ord('/')) - treescrn.addch(9, 6, ord('/')) - treescrn.addch(10, 5, ord('/')) - treescrn.addch(11, 3, ord('/')) - treescrn.addch(12, 2, ord('/')) - - treescrn.addch(1, 13, ord('\\')) - treescrn.addch(2, 13, ord('\\')) - treescrn.addch(3, 14, ord('\\')) - treescrn.addch(4, 15, ord('\\')) - treescrn.addch(5, 15, ord('\\')) - treescrn.addch(6, 16, ord('\\')) - treescrn.addch(7, 17, ord('\\')) - treescrn.addch(8, 18, ord('\\')) - treescrn.addch(9, 18, ord('\\')) - treescrn.addch(10, 19, ord('\\')) - treescrn.addch(11, 21, ord('\\')) - treescrn.addch(12, 22, ord('\\')) - - treescrn.addch(4, 10, ord('_')) - treescrn.addch(4, 14, ord('_')) - treescrn.addch(8, 7, ord('_')) - treescrn.addch(8, 17, ord('_')) - - treescrn.addstr(13, 0, "//////////// \\\\\\\\\\\\\\\\\\\\\\\\") - - treescrn.addstr(14, 11, "| |") - treescrn.addstr(15, 11, "|_|") - - unset_color(treescrn) - treescrn.refresh() - w_del_msg.refresh() - - return - -def balls(): - treescrn.overlay(treescrn2) - - set_color(treescrn2, curses.COLOR_BLUE) - treescrn2.addch(3, 9, ord('@')) - treescrn2.addch(3, 15, ord('@')) - treescrn2.addch(4, 8, ord('@')) - treescrn2.addch(4, 16, ord('@')) - treescrn2.addch(5, 7, ord('@')) - treescrn2.addch(5, 17, ord('@')) - treescrn2.addch(7, 6, ord('@')) - treescrn2.addch(7, 18, ord('@')) - treescrn2.addch(8, 5, ord('@')) - treescrn2.addch(8, 19, ord('@')) - treescrn2.addch(10, 4, ord('@')) - treescrn2.addch(10, 20, ord('@')) - treescrn2.addch(11, 2, ord('@')) - treescrn2.addch(11, 22, ord('@')) - treescrn2.addch(12, 1, ord('@')) - treescrn2.addch(12, 23, ord('@')) - - unset_color(treescrn2) - treescrn2.refresh() - w_del_msg.refresh() - return - -def star(): - treescrn2.attrset(curses.A_BOLD | curses.A_BLINK) - set_color(treescrn2, curses.COLOR_YELLOW) - - treescrn2.addch(0, 12, ord('*')) - treescrn2.standend() - - unset_color(treescrn2) - treescrn2.refresh() - w_del_msg.refresh() - return - -def strng1(): - treescrn2.attrset(curses.A_BOLD | curses.A_BLINK) - set_color(treescrn2, curses.COLOR_WHITE) - - treescrn2.addch(3, 13, ord('\'')) - treescrn2.addch(3, 12, ord(':')) - treescrn2.addch(3, 11, ord('.')) - - treescrn2.attroff(curses.A_BOLD | curses.A_BLINK) - unset_color(treescrn2) - - treescrn2.refresh() - w_del_msg.refresh() - return - -def strng2(): - treescrn2.attrset(curses.A_BOLD | curses.A_BLINK) - set_color(treescrn2, curses.COLOR_WHITE) - - treescrn2.addch(5, 14, ord('\'')) - treescrn2.addch(5, 13, ord(':')) - treescrn2.addch(5, 12, ord('.')) - treescrn2.addch(5, 11, ord(',')) - treescrn2.addch(6, 10, ord('\'')) - treescrn2.addch(6, 9, ord(':')) - - treescrn2.attroff(curses.A_BOLD | curses.A_BLINK) - unset_color(treescrn2) - - treescrn2.refresh() - w_del_msg.refresh() - return - -def strng3(): - treescrn2.attrset(curses.A_BOLD | curses.A_BLINK) - set_color(treescrn2, curses.COLOR_WHITE) - - treescrn2.addch(7, 16, ord('\'')) - treescrn2.addch(7, 15, ord(':')) - treescrn2.addch(7, 14, ord('.')) - treescrn2.addch(7, 13, ord(',')) - treescrn2.addch(8, 12, ord('\'')) - treescrn2.addch(8, 11, ord(':')) - treescrn2.addch(8, 10, ord('.')) - treescrn2.addch(8, 9, ord(',')) - - treescrn2.attroff(curses.A_BOLD | curses.A_BLINK) - unset_color(treescrn2) - - treescrn2.refresh() - w_del_msg.refresh() - return - -def strng4(): - treescrn2.attrset(curses.A_BOLD | curses.A_BLINK) - set_color(treescrn2, curses.COLOR_WHITE) - - treescrn2.addch(9, 17, ord('\'')) - treescrn2.addch(9, 16, ord(':')) - treescrn2.addch(9, 15, ord('.')) - treescrn2.addch(9, 14, ord(',')) - treescrn2.addch(10, 13, ord('\'')) - treescrn2.addch(10, 12, ord(':')) - treescrn2.addch(10, 11, ord('.')) - treescrn2.addch(10, 10, ord(',')) - treescrn2.addch(11, 9, ord('\'')) - treescrn2.addch(11, 8, ord(':')) - treescrn2.addch(11, 7, ord('.')) - treescrn2.addch(11, 6, ord(',')) - treescrn2.addch(12, 5, ord('\'')) - - treescrn2.attroff(curses.A_BOLD | curses.A_BLINK) - unset_color(treescrn2) - - treescrn2.refresh() - w_del_msg.refresh() - return - -def strng5(): - treescrn2.attrset(curses.A_BOLD | curses.A_BLINK) - set_color(treescrn2, curses.COLOR_WHITE) - - treescrn2.addch(11, 19, ord('\'')) - treescrn2.addch(11, 18, ord(':')) - treescrn2.addch(11, 17, ord('.')) - treescrn2.addch(11, 16, ord(',')) - treescrn2.addch(12, 15, ord('\'')) - treescrn2.addch(12, 14, ord(':')) - treescrn2.addch(12, 13, ord('.')) - treescrn2.addch(12, 12, ord(',')) - - treescrn2.attroff(curses.A_BOLD | curses.A_BLINK) - unset_color(treescrn2) - - # save a fully lit tree - treescrn2.overlay(treescrn) - - treescrn2.refresh() - w_del_msg.refresh() - return - -def blinkit(): - treescrn8.touchwin() - - for cycle in range(5): - if cycle == 0: - treescrn3.overlay(treescrn8) - treescrn8.refresh() - w_del_msg.refresh() - break - elif cycle == 1: - treescrn4.overlay(treescrn8) - treescrn8.refresh() - w_del_msg.refresh() - break - elif cycle == 2: - treescrn5.overlay(treescrn8) - treescrn8.refresh() - w_del_msg.refresh() - break - elif cycle == 3: - treescrn6.overlay(treescrn8) - treescrn8.refresh() - w_del_msg.refresh() - break - elif cycle == 4: - treescrn7.overlay(treescrn8) - treescrn8.refresh() - w_del_msg.refresh() - break - - treescrn8.touchwin() - - # ALL ON - treescrn.overlay(treescrn8) - treescrn8.refresh() - w_del_msg.refresh() - - return - -def deer_step(win, y, x): - win.mvwin(y, x) - win.refresh() - w_del_msg.refresh() - look_out(5) - -def reindeer(): - y_pos = 0 - - for x_pos in range(70, 62, -1): - if x_pos < 66: y_pos = 1 - for looper in range(0, 4): - dotdeer0.addch(y_pos, x_pos, ord('.')) - dotdeer0.refresh() - w_del_msg.refresh() - dotdeer0.erase() - dotdeer0.refresh() - w_del_msg.refresh() - look_out(50) - - y_pos = 2 - - for x_pos in range(x_pos - 1, 50, -1): - for looper in range(0, 4): - if x_pos < 56: - y_pos = 3 - - try: - stardeer0.addch(y_pos, x_pos, ord('*')) - except curses.error: - pass - stardeer0.refresh() - w_del_msg.refresh() - stardeer0.erase() - stardeer0.refresh() - w_del_msg.refresh() - else: - dotdeer0.addch(y_pos, x_pos, ord('*')) - dotdeer0.refresh() - w_del_msg.refresh() - dotdeer0.erase() - dotdeer0.refresh() - w_del_msg.refresh() - - x_pos = 58 - - for y_pos in range(2, 5): - lildeer0.touchwin() - lildeer0.refresh() - w_del_msg.refresh() - - for looper in range(0, 4): - deer_step(lildeer3, y_pos, x_pos) - deer_step(lildeer2, y_pos, x_pos) - deer_step(lildeer1, y_pos, x_pos) - deer_step(lildeer2, y_pos, x_pos) - deer_step(lildeer3, y_pos, x_pos) - - lildeer0.touchwin() - lildeer0.refresh() - w_del_msg.refresh() - - x_pos -= 2 - - x_pos = 35 - - for y_pos in range(5, 10): - - middeer0.touchwin() - middeer0.refresh() - w_del_msg.refresh() - - for looper in range(2): - deer_step(middeer3, y_pos, x_pos) - deer_step(middeer2, y_pos, x_pos) - deer_step(middeer1, y_pos, x_pos) - deer_step(middeer2, y_pos, x_pos) - deer_step(middeer3, y_pos, x_pos) - - middeer0.touchwin() - middeer0.refresh() - w_del_msg.refresh() - - x_pos -= 3 - - look_out(300) - - y_pos = 1 - - for x_pos in range(8, 16): - deer_step(bigdeer4, y_pos, x_pos) - deer_step(bigdeer3, y_pos, x_pos) - deer_step(bigdeer2, y_pos, x_pos) - deer_step(bigdeer1, y_pos, x_pos) - deer_step(bigdeer2, y_pos, x_pos) - deer_step(bigdeer3, y_pos, x_pos) - deer_step(bigdeer4, y_pos, x_pos) - deer_step(bigdeer0, y_pos, x_pos) - - x_pos -= 1 - - for looper in range(0, 6): - deer_step(lookdeer4, y_pos, x_pos) - deer_step(lookdeer3, y_pos, x_pos) - deer_step(lookdeer2, y_pos, x_pos) - deer_step(lookdeer1, y_pos, x_pos) - deer_step(lookdeer2, y_pos, x_pos) - deer_step(lookdeer3, y_pos, x_pos) - deer_step(lookdeer4, y_pos, x_pos) - - deer_step(lookdeer0, y_pos, x_pos) - - for y_pos in range(y_pos, 10): - for looper in range(0, 2): - deer_step(bigdeer4, y_pos, x_pos) - deer_step(bigdeer3, y_pos, x_pos) - deer_step(bigdeer2, y_pos, x_pos) - deer_step(bigdeer1, y_pos, x_pos) - deer_step(bigdeer2, y_pos, x_pos) - deer_step(bigdeer3, y_pos, x_pos) - deer_step(bigdeer4, y_pos, x_pos) - deer_step(bigdeer0, y_pos, x_pos) - - y_pos -= 1 - - deer_step(lookdeer3, y_pos, x_pos) - return - -def main(win): - global stdscr - stdscr = win - - global my_bg, y_pos, x_pos - global treescrn, treescrn2, treescrn3, treescrn4 - global treescrn5, treescrn6, treescrn7, treescrn8 - global dotdeer0, stardeer0 - global lildeer0, lildeer1, lildeer2, lildeer3 - global middeer0, middeer1, middeer2, middeer3 - global bigdeer0, bigdeer1, bigdeer2, bigdeer3, bigdeer4 - global lookdeer0, lookdeer1, lookdeer2, lookdeer3, lookdeer4 - global w_holiday, w_del_msg - - my_bg = curses.COLOR_BLACK - # curses.curs_set(0) - - treescrn = curses.newwin(16, 27, 3, 53) - treescrn2 = curses.newwin(16, 27, 3, 53) - treescrn3 = curses.newwin(16, 27, 3, 53) - treescrn4 = curses.newwin(16, 27, 3, 53) - treescrn5 = curses.newwin(16, 27, 3, 53) - treescrn6 = curses.newwin(16, 27, 3, 53) - treescrn7 = curses.newwin(16, 27, 3, 53) - treescrn8 = curses.newwin(16, 27, 3, 53) - - dotdeer0 = curses.newwin(3, 71, 0, 8) - - stardeer0 = curses.newwin(4, 56, 0, 8) - - lildeer0 = curses.newwin(7, 53, 0, 8) - lildeer1 = curses.newwin(2, 4, 0, 0) - lildeer2 = curses.newwin(2, 4, 0, 0) - lildeer3 = curses.newwin(2, 4, 0, 0) - - middeer0 = curses.newwin(15, 42, 0, 8) - middeer1 = curses.newwin(3, 7, 0, 0) - middeer2 = curses.newwin(3, 7, 0, 0) - middeer3 = curses.newwin(3, 7, 0, 0) - - bigdeer0 = curses.newwin(10, 23, 0, 0) - bigdeer1 = curses.newwin(10, 23, 0, 0) - bigdeer2 = curses.newwin(10, 23, 0, 0) - bigdeer3 = curses.newwin(10, 23, 0, 0) - bigdeer4 = curses.newwin(10, 23, 0, 0) - - lookdeer0 = curses.newwin(10, 25, 0, 0) - lookdeer1 = curses.newwin(10, 25, 0, 0) - lookdeer2 = curses.newwin(10, 25, 0, 0) - lookdeer3 = curses.newwin(10, 25, 0, 0) - lookdeer4 = curses.newwin(10, 25, 0, 0) - - w_holiday = curses.newwin(1, 27, 3, 27) - - w_del_msg = curses.newwin(1, 20, 23, 60) - - try: - w_del_msg.addstr(0, 0, "Hit any key to quit") - except curses.error: - pass - - try: - w_holiday.addstr(0, 0, "H A P P Y H O L I D A Y S") - except curses.error: - pass - - # set up the windows for our various reindeer - lildeer1.addch(0, 0, ord('V')) - lildeer1.addch(1, 0, ord('@')) - lildeer1.addch(1, 1, ord('<')) - lildeer1.addch(1, 2, ord('>')) - try: - lildeer1.addch(1, 3, ord('~')) - except curses.error: - pass - - lildeer2.addch(0, 0, ord('V')) - lildeer2.addch(1, 0, ord('@')) - lildeer2.addch(1, 1, ord('|')) - lildeer2.addch(1, 2, ord('|')) - try: - lildeer2.addch(1, 3, ord('~')) - except curses.error: - pass - - lildeer3.addch(0, 0, ord('V')) - lildeer3.addch(1, 0, ord('@')) - lildeer3.addch(1, 1, ord('>')) - lildeer3.addch(1, 2, ord('<')) - try: - lildeer2.addch(1, 3, ord('~')) # XXX - except curses.error: - pass - - middeer1.addch(0, 2, ord('y')) - middeer1.addch(0, 3, ord('y')) - middeer1.addch(1, 2, ord('0')) - middeer1.addch(1, 3, ord('(')) - middeer1.addch(1, 4, ord('=')) - middeer1.addch(1, 5, ord(')')) - middeer1.addch(1, 6, ord('~')) - middeer1.addch(2, 3, ord('\\')) - middeer1.addch(2, 5, ord('/')) - - middeer2.addch(0, 2, ord('y')) - middeer2.addch(0, 3, ord('y')) - middeer2.addch(1, 2, ord('0')) - middeer2.addch(1, 3, ord('(')) - middeer2.addch(1, 4, ord('=')) - middeer2.addch(1, 5, ord(')')) - middeer2.addch(1, 6, ord('~')) - middeer2.addch(2, 3, ord('|')) - middeer2.addch(2, 5, ord('|')) - - middeer3.addch(0, 2, ord('y')) - middeer3.addch(0, 3, ord('y')) - middeer3.addch(1, 2, ord('0')) - middeer3.addch(1, 3, ord('(')) - middeer3.addch(1, 4, ord('=')) - middeer3.addch(1, 5, ord(')')) - middeer3.addch(1, 6, ord('~')) - middeer3.addch(2, 3, ord('/')) - middeer3.addch(2, 5, ord('\\')) - - bigdeer1.addch(0, 17, ord('\\')) - bigdeer1.addch(0, 18, ord('/')) - bigdeer1.addch(0, 19, ord('\\')) - bigdeer1.addch(0, 20, ord('/')) - bigdeer1.addch(1, 18, ord('\\')) - bigdeer1.addch(1, 20, ord('/')) - bigdeer1.addch(2, 19, ord('|')) - bigdeer1.addch(2, 20, ord('_')) - bigdeer1.addch(3, 18, ord('/')) - bigdeer1.addch(3, 19, ord('^')) - bigdeer1.addch(3, 20, ord('0')) - bigdeer1.addch(3, 21, ord('\\')) - bigdeer1.addch(4, 17, ord('/')) - bigdeer1.addch(4, 18, ord('/')) - bigdeer1.addch(4, 19, ord('\\')) - bigdeer1.addch(4, 22, ord('\\')) - bigdeer1.addstr(5, 7, "^~~~~~~~~// ~~U") - bigdeer1.addstr(6, 7, "( \\_____( /") # )) - bigdeer1.addstr(7, 8, "( ) /") - bigdeer1.addstr(8, 9, "\\\\ /") - bigdeer1.addstr(9, 11, "\\>/>") - - bigdeer2.addch(0, 17, ord('\\')) - bigdeer2.addch(0, 18, ord('/')) - bigdeer2.addch(0, 19, ord('\\')) - bigdeer2.addch(0, 20, ord('/')) - bigdeer2.addch(1, 18, ord('\\')) - bigdeer2.addch(1, 20, ord('/')) - bigdeer2.addch(2, 19, ord('|')) - bigdeer2.addch(2, 20, ord('_')) - bigdeer2.addch(3, 18, ord('/')) - bigdeer2.addch(3, 19, ord('^')) - bigdeer2.addch(3, 20, ord('0')) - bigdeer2.addch(3, 21, ord('\\')) - bigdeer2.addch(4, 17, ord('/')) - bigdeer2.addch(4, 18, ord('/')) - bigdeer2.addch(4, 19, ord('\\')) - bigdeer2.addch(4, 22, ord('\\')) - bigdeer2.addstr(5, 7, "^~~~~~~~~// ~~U") - bigdeer2.addstr(6, 7, "(( )____( /") # )) - bigdeer2.addstr(7, 7, "( / |") - bigdeer2.addstr(8, 8, "\\/ |") - bigdeer2.addstr(9, 9, "|> |>") - - bigdeer3.addch(0, 17, ord('\\')) - bigdeer3.addch(0, 18, ord('/')) - bigdeer3.addch(0, 19, ord('\\')) - bigdeer3.addch(0, 20, ord('/')) - bigdeer3.addch(1, 18, ord('\\')) - bigdeer3.addch(1, 20, ord('/')) - bigdeer3.addch(2, 19, ord('|')) - bigdeer3.addch(2, 20, ord('_')) - bigdeer3.addch(3, 18, ord('/')) - bigdeer3.addch(3, 19, ord('^')) - bigdeer3.addch(3, 20, ord('0')) - bigdeer3.addch(3, 21, ord('\\')) - bigdeer3.addch(4, 17, ord('/')) - bigdeer3.addch(4, 18, ord('/')) - bigdeer3.addch(4, 19, ord('\\')) - bigdeer3.addch(4, 22, ord('\\')) - bigdeer3.addstr(5, 7, "^~~~~~~~~// ~~U") - bigdeer3.addstr(6, 6, "( ()_____( /") # )) - bigdeer3.addstr(7, 6, "/ / /") - bigdeer3.addstr(8, 5, "|/ \\") - bigdeer3.addstr(9, 5, "/> \\>") - - bigdeer4.addch(0, 17, ord('\\')) - bigdeer4.addch(0, 18, ord('/')) - bigdeer4.addch(0, 19, ord('\\')) - bigdeer4.addch(0, 20, ord('/')) - bigdeer4.addch(1, 18, ord('\\')) - bigdeer4.addch(1, 20, ord('/')) - bigdeer4.addch(2, 19, ord('|')) - bigdeer4.addch(2, 20, ord('_')) - bigdeer4.addch(3, 18, ord('/')) - bigdeer4.addch(3, 19, ord('^')) - bigdeer4.addch(3, 20, ord('0')) - bigdeer4.addch(3, 21, ord('\\')) - bigdeer4.addch(4, 17, ord('/')) - bigdeer4.addch(4, 18, ord('/')) - bigdeer4.addch(4, 19, ord('\\')) - bigdeer4.addch(4, 22, ord('\\')) - bigdeer4.addstr(5, 7, "^~~~~~~~~// ~~U") - bigdeer4.addstr(6, 6, "( )______( /") # ) - bigdeer4.addstr(7, 5, "(/ \\") # ) - bigdeer4.addstr(8, 0, "v___= ----^") - - lookdeer1.addstr(0, 16, "\\/ \\/") - lookdeer1.addstr(1, 17, "\\Y/ \\Y/") - lookdeer1.addstr(2, 19, "\\=/") - lookdeer1.addstr(3, 17, "^\\o o/^") - lookdeer1.addstr(4, 17, "//( )") - lookdeer1.addstr(5, 7, "^~~~~~~~~// \\O/") - lookdeer1.addstr(6, 7, "( \\_____( /") # )) - lookdeer1.addstr(7, 8, "( ) /") - lookdeer1.addstr(8, 9, "\\\\ /") - lookdeer1.addstr(9, 11, "\\>/>") - - lookdeer2.addstr(0, 16, "\\/ \\/") - lookdeer2.addstr(1, 17, "\\Y/ \\Y/") - lookdeer2.addstr(2, 19, "\\=/") - lookdeer2.addstr(3, 17, "^\\o o/^") - lookdeer2.addstr(4, 17, "//( )") - lookdeer2.addstr(5, 7, "^~~~~~~~~// \\O/") - lookdeer2.addstr(6, 7, "(( )____( /") # )) - lookdeer2.addstr(7, 7, "( / |") - lookdeer2.addstr(8, 8, "\\/ |") - lookdeer2.addstr(9, 9, "|> |>") - - lookdeer3.addstr(0, 16, "\\/ \\/") - lookdeer3.addstr(1, 17, "\\Y/ \\Y/") - lookdeer3.addstr(2, 19, "\\=/") - lookdeer3.addstr(3, 17, "^\\o o/^") - lookdeer3.addstr(4, 17, "//( )") - lookdeer3.addstr(5, 7, "^~~~~~~~~// \\O/") - lookdeer3.addstr(6, 6, "( ()_____( /") # )) - lookdeer3.addstr(7, 6, "/ / /") - lookdeer3.addstr(8, 5, "|/ \\") - lookdeer3.addstr(9, 5, "/> \\>") - - lookdeer4.addstr(0, 16, "\\/ \\/") - lookdeer4.addstr(1, 17, "\\Y/ \\Y/") - lookdeer4.addstr(2, 19, "\\=/") - lookdeer4.addstr(3, 17, "^\\o o/^") - lookdeer4.addstr(4, 17, "//( )") - lookdeer4.addstr(5, 7, "^~~~~~~~~// \\O/") - lookdeer4.addstr(6, 6, "( )______( /") # ) - lookdeer4.addstr(7, 5, "(/ \\") # ) - lookdeer4.addstr(8, 0, "v___= ----^") - - ############################################### - curses.cbreak() - stdscr.nodelay(1) - - while 1: - stdscr.clear() - treescrn.erase() - w_del_msg.touchwin() - treescrn.touchwin() - treescrn2.erase() - treescrn2.touchwin() - treescrn8.erase() - treescrn8.touchwin() - stdscr.refresh() - look_out(150) - boxit() - stdscr.refresh() - look_out(150) - seas() - stdscr.refresh() - greet() - stdscr.refresh() - look_out(150) - fromwho() - stdscr.refresh() - look_out(150) - tree() - look_out(150) - balls() - look_out(150) - star() - look_out(150) - strng1() - strng2() - strng3() - strng4() - strng5() - - # set up the windows for our blinking trees - # - # treescrn3 - treescrn.overlay(treescrn3) - - # balls - treescrn3.addch(4, 18, ord(' ')) - treescrn3.addch(7, 6, ord(' ')) - treescrn3.addch(8, 19, ord(' ')) - treescrn3.addch(11, 22, ord(' ')) - - # star - treescrn3.addch(0, 12, ord('*')) - - # strng1 - treescrn3.addch(3, 11, ord(' ')) - - # strng2 - treescrn3.addch(5, 13, ord(' ')) - treescrn3.addch(6, 10, ord(' ')) - - # strng3 - treescrn3.addch(7, 16, ord(' ')) - treescrn3.addch(7, 14, ord(' ')) - - # strng4 - treescrn3.addch(10, 13, ord(' ')) - treescrn3.addch(10, 10, ord(' ')) - treescrn3.addch(11, 8, ord(' ')) - - # strng5 - treescrn3.addch(11, 18, ord(' ')) - treescrn3.addch(12, 13, ord(' ')) - - # treescrn4 - treescrn.overlay(treescrn4) - - # balls - treescrn4.addch(3, 9, ord(' ')) - treescrn4.addch(4, 16, ord(' ')) - treescrn4.addch(7, 6, ord(' ')) - treescrn4.addch(8, 19, ord(' ')) - treescrn4.addch(11, 2, ord(' ')) - treescrn4.addch(12, 23, ord(' ')) - - # star - treescrn4.standout() - treescrn4.addch(0, 12, ord('*')) - treescrn4.standend() - - # strng1 - treescrn4.addch(3, 13, ord(' ')) - - # strng2 - - # strng3 - treescrn4.addch(7, 15, ord(' ')) - treescrn4.addch(8, 11, ord(' ')) - - # strng4 - treescrn4.addch(9, 16, ord(' ')) - treescrn4.addch(10, 12, ord(' ')) - treescrn4.addch(11, 8, ord(' ')) - - # strng5 - treescrn4.addch(11, 18, ord(' ')) - treescrn4.addch(12, 14, ord(' ')) - - # treescrn5 - treescrn.overlay(treescrn5) - - # balls - treescrn5.addch(3, 15, ord(' ')) - treescrn5.addch(10, 20, ord(' ')) - treescrn5.addch(12, 1, ord(' ')) - - # star - treescrn5.addch(0, 12, ord(' ')) - - # strng1 - treescrn5.addch(3, 11, ord(' ')) - - # strng2 - treescrn5.addch(5, 12, ord(' ')) - - # strng3 - treescrn5.addch(7, 14, ord(' ')) - treescrn5.addch(8, 10, ord(' ')) - - # strng4 - treescrn5.addch(9, 15, ord(' ')) - treescrn5.addch(10, 11, ord(' ')) - treescrn5.addch(11, 7, ord(' ')) - - # strng5 - treescrn5.addch(11, 17, ord(' ')) - treescrn5.addch(12, 13, ord(' ')) - - # treescrn6 - treescrn.overlay(treescrn6) - - # balls - treescrn6.addch(6, 7, ord(' ')) - treescrn6.addch(7, 18, ord(' ')) - treescrn6.addch(10, 4, ord(' ')) - treescrn6.addch(11, 23, ord(' ')) - - # star - treescrn6.standout() - treescrn6.addch(0, 12, ord('*')) - treescrn6.standend() - - # strng1 - - # strng2 - treescrn6.addch(5, 11, ord(' ')) - - # strng3 - treescrn6.addch(7, 13, ord(' ')) - treescrn6.addch(8, 9, ord(' ')) - - # strng4 - treescrn6.addch(9, 14, ord(' ')) - treescrn6.addch(10, 10, ord(' ')) - treescrn6.addch(11, 6, ord(' ')) - - # strng5 - treescrn6.addch(11, 16, ord(' ')) - treescrn6.addch(12, 12, ord(' ')) - - # treescrn7 - - treescrn.overlay(treescrn7) - - # balls - treescrn7.addch(3, 15, ord(' ')) - treescrn7.addch(6, 7, ord(' ')) - treescrn7.addch(7, 18, ord(' ')) - treescrn7.addch(10, 4, ord(' ')) - treescrn7.addch(11, 22, ord(' ')) - - # star - treescrn7.addch(0, 12, ord('*')) - - # strng1 - treescrn7.addch(3, 12, ord(' ')) - - # strng2 - treescrn7.addch(5, 13, ord(' ')) - treescrn7.addch(6, 9, ord(' ')) - - # strng3 - treescrn7.addch(7, 15, ord(' ')) - treescrn7.addch(8, 11, ord(' ')) - - # strng4 - treescrn7.addch(9, 16, ord(' ')) - treescrn7.addch(10, 12, ord(' ')) - treescrn7.addch(11, 8, ord(' ')) - - # strng5 - treescrn7.addch(11, 18, ord(' ')) - treescrn7.addch(12, 14, ord(' ')) - - look_out(150) - reindeer() - - w_holiday.touchwin() - w_holiday.refresh() - w_del_msg.refresh() - - look_out(500) - for i in range(0, 20): - blinkit() - -curses.wrapper(main) diff --git a/Demo/distutils/test2to3/README b/Demo/distutils/test2to3/README deleted file mode 100644 index 9365593..0000000 --- a/Demo/distutils/test2to3/README +++ /dev/null @@ -1,3 +0,0 @@ -This project demonstrates how a distutils package -can support Python 2.x and Python 3.x from a single -source, using lib2to3.
\ No newline at end of file diff --git a/Demo/distutils/test2to3/maintest.py b/Demo/distutils/test2to3/maintest.py deleted file mode 100644 index 72a26dd..0000000 --- a/Demo/distutils/test2to3/maintest.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python - -# The above line should get replaced with the path to the Python -# interpreter; the block below should get 2to3-converted. - -try: - from test2to3.hello import hello -except ImportError, e: - print "Import failed", e -hello() diff --git a/Demo/distutils/test2to3/setup.py b/Demo/distutils/test2to3/setup.py deleted file mode 100644 index a0f9024..0000000 --- a/Demo/distutils/test2to3/setup.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: iso-8859-1 -*- -from distutils.core import setup - -try: - from distutils.command.build_py import build_py_2to3 as build_py -except ImportError: - from distutils.command.build_py import build_py - -try: - from distutils.command.build_scripts import build_scripts_2to3 as build_scripts -except ImportError: - from distutils.command.build_scripts import build_scripts - -setup( - name = "test2to3", - version = "1.0", - description = "2to3 distutils test package", - author = "Martin v. Löwis", - author_email = "python-dev@python.org", - license = "PSF license", - packages = ["test2to3"], - scripts = ["maintest.py"], - cmdclass = {'build_py': build_py, - 'build_scripts': build_scripts, - } -) diff --git a/Demo/distutils/test2to3/test/runtests.py b/Demo/distutils/test2to3/test/runtests.py deleted file mode 100644 index 1730f0d..0000000 --- a/Demo/distutils/test2to3/test/runtests.py +++ /dev/null @@ -1,19 +0,0 @@ -# Fictitious test runner for the project - -import sys, os - -if sys.version_info > (3,): - # copy test suite over to "build/lib" and convert it - from distutils.util import copydir_run_2to3 - testroot = os.path.dirname(__file__) - newroot = os.path.join(testroot, '..', 'build/lib/test') - copydir_run_2to3(testroot, newroot) - # in the following imports, pick up the converted modules - sys.path[0] = newroot - -# run the tests here... - -from test_foo import FooTest - -import unittest -unittest.main() diff --git a/Demo/distutils/test2to3/test/test_foo.py b/Demo/distutils/test2to3/test/test_foo.py deleted file mode 100644 index ec8f26a..0000000 --- a/Demo/distutils/test2to3/test/test_foo.py +++ /dev/null @@ -1,8 +0,0 @@ -import sys -import unittest - -class FooTest(unittest.TestCase): - def test_foo(self): - # use 2.6 syntax to demonstrate conversion - print 'In test_foo, using Python %s...' % (sys.version_info,) - self.assertTrue(False) diff --git a/Demo/distutils/test2to3/test2to3/__init__.py b/Demo/distutils/test2to3/test2to3/__init__.py deleted file mode 100644 index 1bb8bf6..0000000 --- a/Demo/distutils/test2to3/test2to3/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# empty diff --git a/Demo/distutils/test2to3/test2to3/hello.py b/Demo/distutils/test2to3/test2to3/hello.py deleted file mode 100644 index f52926b..0000000 --- a/Demo/distutils/test2to3/test2to3/hello.py +++ /dev/null @@ -1,5 +0,0 @@ -def hello(): - try: - print "Hello, world" - except IOError, e: - print e.errno diff --git a/Demo/embed/Makefile b/Demo/embed/Makefile deleted file mode 100644 index 711b95b..0000000 --- a/Demo/embed/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# Makefile for embedded Python use demo. -# (This version tailored for my Red Hat Linux 6.1 setup; -# edit lines marked with XXX.) - -# XXX The compiler you are using -CC= gcc - -# XXX Top of the build tree and source tree -blddir= ../.. -srcdir= ../.. - -# Python version -VERSION= 3.0 - -# Compiler flags -OPT= -g -INCLUDES= -I$(srcdir)/Include -I$(blddir) -CFLAGS= $(OPT) -CPPFLAGS= $(INCLUDES) - -# The Python library -LIBPYTHON= $(blddir)/libpython$(VERSION).a - -# XXX edit LIBS (in particular) to match $(blddir)/Modules/Makefile -LIBS= -lnsl -ldl -lreadline -lieee -lpthread -lutil -LDFLAGS= -Xlinker -export-dynamic -SYSLIBS= -lm -MODLIBS= -ALLLIBS= $(LIBPYTHON) $(MODLIBS) $(LIBS) $(SYSLIBS) - -# Build the demo applications -all: demo loop importexc -demo: demo.o - $(CC) $(LDFLAGS) demo.o $(ALLLIBS) -o demo - -loop: loop.o - $(CC) $(LDFLAGS) loop.o $(ALLLIBS) -o loop - -importexc: importexc.o - $(CC) $(LDFLAGS) importexc.o $(ALLLIBS) -o importexc - -# Administrative targets - -test: demo - ./demo - -COMMAND="print 'hello world'" -looptest: loop - ./loop $(COMMAND) - -clean: - -rm -f *.o core - -clobber: clean - -rm -f *~ @* '#'* demo loop importexc - -realclean: clobber diff --git a/Demo/embed/README b/Demo/embed/README deleted file mode 100644 index a0f7af8..0000000 --- a/Demo/embed/README +++ /dev/null @@ -1,19 +0,0 @@ -This directory show how to embed the Python interpreter in your own -application. The file demo.c shows you all that is needed in your C -code. - -To build it, you may have to edit the Makefile: - -1) set blddir to the directory where you built Python, if it isn't in -the source directory (../..) - -2) change the variables that together define the list of libraries -(MODLIBS, LIBS, SYSLIBS) to link with, to match their definitions in -$(blddir)/Modules/Makefile - -An additional test program, loop.c, is used to experiment with memory -leakage caused by repeated initialization and finalization of the -interpreter. It can be build by saying "make loop" and tested with -"make looptest". Command line usage is "./loop <python-command>", -e.g. "./loop 'print 2+2'" should spit out an endless number of lines -containing the number 4. diff --git a/Demo/embed/demo.c b/Demo/embed/demo.c deleted file mode 100644 index 99d39ca..0000000 --- a/Demo/embed/demo.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Example of embedding Python in another program */ - -#include "Python.h" - -PyObject* PyInit_xyzzy(void); /* Forward */ - -main(int argc, char **argv) -{ - /* Ignore passed-in argc/argv. If desired, conversion - should use mbstowcs to convert them. */ - wchar_t *args[] = {L"embed", L"hello", 0}; - - /* Pass argv[0] to the Python interpreter */ - Py_SetProgramName(args[0]); - - /* Add a static module */ - PyImport_AppendInittab("xyzzy", PyInit_xyzzy); - - /* Initialize the Python interpreter. Required. */ - Py_Initialize(); - - /* Define sys.argv. It is up to the application if you - want this; you can also let it undefined (since the Python - code is generally not a main program it has no business - touching sys.argv...) - - If the third argument is true, sys.path is modified to include - either the directory containing the script named by argv[0], or - the current working directory. This can be risky; if you run - an application embedding Python in a directory controlled by - someone else, attackers could put a Trojan-horse module in the - directory (say, a file named os.py) that your application would - then import and run. - */ - PySys_SetArgvEx(2, args, 0); - - /* Do some application specific code */ - printf("Hello, brave new world\n\n"); - - /* Execute some Python statements (in module __main__) */ - PyRun_SimpleString("import sys\n"); - PyRun_SimpleString("print(sys.builtin_module_names)\n"); - PyRun_SimpleString("print(sys.modules.keys())\n"); - PyRun_SimpleString("print(sys.executable)\n"); - PyRun_SimpleString("print(sys.argv)\n"); - - /* Note that you can call any public function of the Python - interpreter here, e.g. call_object(). */ - - /* Some more application specific code */ - printf("\nGoodbye, cruel world\n"); - - /* Exit, cleaning up the interpreter */ - Py_Exit(0); - /*NOTREACHED*/ -} - -/* A static module */ - -/* 'self' is not used */ -static PyObject * -xyzzy_foo(PyObject *self, PyObject* args) -{ - return PyLong_FromLong(42L); -} - -static PyMethodDef xyzzy_methods[] = { - {"foo", xyzzy_foo, METH_NOARGS, - "Return the meaning of everything."}, - {NULL, NULL} /* sentinel */ -}; - -static struct PyModuleDef xyzzymodule = { - {}, /* m_base */ - "xyzzy", /* m_name */ - 0, /* m_doc */ - 0, /* m_size */ - xyzzy_methods, /* m_methods */ - 0, /* m_reload */ - 0, /* m_traverse */ - 0, /* m_clear */ - 0, /* m_free */ -}; - -PyObject* -PyInit_xyzzy(void) -{ - return PyModule_Create(&xyzzymodule); -} diff --git a/Demo/embed/importexc.c b/Demo/embed/importexc.c deleted file mode 100644 index 59b1d01..0000000 --- a/Demo/embed/importexc.c +++ /dev/null @@ -1,23 +0,0 @@ -#include <Python.h> - -#if 0 -char* cmd = "import codecs, encodings.utf_8, types; print(types)"; -#else -char* cmd = "import types; print(types)"; -#endif - -int main() -{ - printf("Initialize interpreter\n"); - Py_Initialize(); - PyEval_InitThreads(); - PyRun_SimpleString(cmd); - Py_EndInterpreter(PyThreadState_Get()); - - printf("\nInitialize subinterpreter\n"); - Py_NewInterpreter(); - PyRun_SimpleString(cmd); - Py_Finalize(); - - return 0; -} diff --git a/Demo/embed/loop.c b/Demo/embed/loop.c deleted file mode 100644 index 4a341fd..0000000 --- a/Demo/embed/loop.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Simple program that repeatedly calls Py_Initialize(), does something, and - then calls Py_Finalize(). This should help finding leaks related to - initialization. */ - -#include "Python.h" - -main(int argc, char **argv) -{ - int count = -1; - char *command; - - if (argc < 2 || argc > 3) { - fprintf(stderr, "usage: loop <python-command> [count]\n"); - exit(2); - } - command = argv[1]; - - if (argc == 3) { - count = atoi(argv[2]); - } - - Py_SetProgramName(L"loop"); - - /* uncomment this if you don't want to load site.py */ - /* Py_NoSiteFlag = 1; */ - - while (count == -1 || --count >= 0 ) { - Py_Initialize(); - PyRun_SimpleString(command); - Py_Finalize(); - } - return 0; -} diff --git a/Demo/md5test/README b/Demo/md5test/README deleted file mode 100644 index be7621e..0000000 --- a/Demo/md5test/README +++ /dev/null @@ -1,10 +0,0 @@ -This is the Python version of the MD5 test program from the MD5 -Internet Draft (Rivest and Dusse, The MD5 Message-Digest Algorithm, 10 -July 1991). The file "foo" contains the string "abc" with no trailing -newline. - -When called without arguments, it acts as a filter. When called with -"-x", it executes a self-test, and the output should literally match -the output given in the RFC. - -Code by Jan-Hein B\"uhrman after the original in C. diff --git a/Demo/md5test/foo b/Demo/md5test/foo deleted file mode 100755 index f2ba8f8..0000000 --- a/Demo/md5test/foo +++ /dev/null @@ -1 +0,0 @@ -abc
\ No newline at end of file diff --git a/Demo/md5test/md5driver.py b/Demo/md5test/md5driver.py deleted file mode 100755 index 7f561ab..0000000 --- a/Demo/md5test/md5driver.py +++ /dev/null @@ -1,122 +0,0 @@ -from hashlib import md5 -import string -from sys import argv - -def MDPrint(str): - outstr = '' - for o in str: - outstr = (outstr - + string.hexdigits[(o >> 4) & 0xF] - + string.hexdigits[o & 0xF]) - print(outstr, end=' ') - - -from time import time - -def makestr(start, end): - result = '' - for i in range(start, end + 1): - result = result + chr(i) - - return result - - -def MDTimeTrial(): - TEST_BLOCK_SIZE = 1000 - TEST_BLOCKS = 10000 - - TEST_BYTES = TEST_BLOCK_SIZE * TEST_BLOCKS - - # initialize test data, need temporary string filler - - filsiz = 1 << 8 - filler = makestr(0, filsiz-1) - data = filler * (TEST_BLOCK_SIZE // filsiz) - data = data + filler[:(TEST_BLOCK_SIZE % filsiz)] - - del filsiz, filler - - - # start timer - print('MD5 time trial. Processing', TEST_BYTES, 'characters...') - t1 = time() - - mdContext = md5() - - for i in range(TEST_BLOCKS): - mdContext.update(data) - - str = mdContext.digest() - t2 = time() - - MDPrint(str) - print('is digest of test input.') - print('Seconds to process test input:', t2 - t1) - print('Characters processed per second:', TEST_BYTES / (t2 - t1)) - - -def MDString(str): - MDPrint(md5(str.encode("utf-8")).digest()) - print('"' + str + '"') - - -def MDFile(filename): - f = open(filename, 'rb') - mdContext = md5() - - while 1: - data = f.read(1024) - if not data: - break - mdContext.update(data) - - MDPrint(mdContext.digest()) - print(filename) - - -import sys - -def MDFilter(): - mdContext = md5() - - while 1: - data = sys.stdin.read(16).encode() - if not data: - break - mdContext.update(data) - - MDPrint(mdContext.digest()) - print() - - -def MDTestSuite(): - print('MD5 test suite results:') - MDString('') - MDString('a') - MDString('abc') - MDString('message digest') - MDString(makestr(ord('a'), ord('z'))) - MDString(makestr(ord('A'), ord('Z')) - + makestr(ord('a'), ord('z')) - + makestr(ord('0'), ord('9'))) - MDString((makestr(ord('1'), ord('9')) + '0') * 8) - - # Contents of file foo are "abc" - MDFile('foo') - - -# I don't wanna use getopt(), since I want to use the same i/f... -def main(): - if len(argv) == 1: - MDFilter() - for arg in argv[1:]: - if arg[:2] == '-s': - MDString(arg[2:]) - elif arg == '-t': - MDTimeTrial() - elif arg == '-x': - MDTestSuite() - else: - MDFile(arg) - -main() diff --git a/Demo/newmetaclasses/Eiffel.py b/Demo/newmetaclasses/Eiffel.py deleted file mode 100644 index 15fa58a..0000000 --- a/Demo/newmetaclasses/Eiffel.py +++ /dev/null @@ -1,141 +0,0 @@ -"""Support Eiffel-style preconditions and postconditions.""" - -from types import FunctionType as function - -class EiffelBaseMetaClass(type): - - def __new__(meta, name, bases, dict): - meta.convert_methods(dict) - return super(EiffelBaseMetaClass, meta).__new__(meta, name, bases, - dict) - - @classmethod - def convert_methods(cls, dict): - """Replace functions in dict with EiffelMethod wrappers. - - The dict is modified in place. - - If a method ends in _pre or _post, it is removed from the dict - regardless of whether there is a corresponding method. - """ - # find methods with pre or post conditions - methods = [] - for k, v in dict.items(): - if k.endswith('_pre') or k.endswith('_post'): - assert isinstance(v, function) - elif isinstance(v, function): - methods.append(k) - for m in methods: - pre = dict.get("%s_pre" % m) - post = dict.get("%s_post" % m) - if pre or post: - dict[k] = cls.make_eiffel_method(dict[m], pre, post) - -class EiffelMetaClass1(EiffelBaseMetaClass): - # an implementation of the "eiffel" meta class that uses nested functions - - @staticmethod - def make_eiffel_method(func, pre, post): - def method(self, *args, **kwargs): - if pre: - pre(self, *args, **kwargs) - x = func(self, *args, **kwargs) - if post: - post(self, x, *args, **kwargs) - return x - - if func.__doc__: - method.__doc__ = func.__doc__ - - return method - -class EiffelMethodWrapper: - - def __init__(self, inst, descr): - self._inst = inst - self._descr = descr - - def __call__(self, *args, **kwargs): - return self._descr.callmethod(self._inst, args, kwargs) - -class EiffelDescriptor(object): - - def __init__(self, func, pre, post): - self._func = func - self._pre = pre - self._post = post - - self.__name__ = func.__name__ - self.__doc__ = func.__doc__ - - def __get__(self, obj, cls): - return EiffelMethodWrapper(obj, self) - - def callmethod(self, inst, args, kwargs): - if self._pre: - self._pre(inst, *args, **kwargs) - x = self._func(inst, *args, **kwargs) - if self._post: - self._post(inst, x, *args, **kwargs) - return x - -class EiffelMetaClass2(EiffelBaseMetaClass): - # an implementation of the "eiffel" meta class that uses descriptors - - make_eiffel_method = EiffelDescriptor - -def _test(metaclass): - class Eiffel(metaclass=metaclass): - pass - - class Test(Eiffel): - - def m(self, arg): - """Make it a little larger""" - return arg + 1 - - def m2(self, arg): - """Make it a little larger""" - return arg + 1 - - def m2_pre(self, arg): - assert arg > 0 - - def m2_post(self, result, arg): - assert result > arg - - class Sub(Test): - def m2(self, arg): - return arg**2 - def m2_post(self, Result, arg): - super(Sub, self).m2_post(Result, arg) - assert Result < 100 - - t = Test() - t.m(1) - t.m2(1) - try: - t.m2(0) - except AssertionError: - pass - else: - assert False - - s = Sub() - try: - s.m2(1) - except AssertionError: - pass # result == arg - else: - assert False - try: - s.m2(10) - except AssertionError: - pass # result == 100 - else: - assert False - s.m2(5) - -if __name__ == "__main__": - _test(EiffelMetaClass1) - _test(EiffelMetaClass2) diff --git a/Demo/newmetaclasses/Enum.py b/Demo/newmetaclasses/Enum.py deleted file mode 100644 index 3ff8ddd..0000000 --- a/Demo/newmetaclasses/Enum.py +++ /dev/null @@ -1,177 +0,0 @@ -"""Enumeration metaclass.""" - -class EnumMetaclass(type): - """Metaclass for enumeration. - - To define your own enumeration, do something like - - class Color(Enum): - red = 1 - green = 2 - blue = 3 - - Now, Color.red, Color.green and Color.blue behave totally - different: they are enumerated values, not integers. - - Enumerations cannot be instantiated; however they can be - subclassed. - """ - - def __init__(cls, name, bases, dict): - super(EnumMetaclass, cls).__init__(name, bases, dict) - cls._members = [] - for attr in dict.keys(): - if not (attr.startswith('__') and attr.endswith('__')): - enumval = EnumInstance(name, attr, dict[attr]) - setattr(cls, attr, enumval) - cls._members.append(attr) - - def __getattr__(cls, name): - if name == "__members__": - return cls._members - raise AttributeError(name) - - def __repr__(cls): - s1 = s2 = "" - enumbases = [base.__name__ for base in cls.__bases__ - if isinstance(base, EnumMetaclass) and not base is Enum] - if enumbases: - s1 = "(%s)" % ", ".join(enumbases) - enumvalues = ["%s: %d" % (val, getattr(cls, val)) - for val in cls._members] - if enumvalues: - s2 = ": {%s}" % ", ".join(enumvalues) - return "%s%s%s" % (cls.__name__, s1, s2) - -class FullEnumMetaclass(EnumMetaclass): - """Metaclass for full enumerations. - - A full enumeration displays all the values defined in base classes. - """ - - def __init__(cls, name, bases, dict): - super(FullEnumMetaclass, cls).__init__(name, bases, dict) - for obj in cls.__mro__: - if isinstance(obj, EnumMetaclass): - for attr in obj._members: - # XXX inefficient - if not attr in cls._members: - cls._members.append(attr) - -class EnumInstance(int): - """Class to represent an enumeration value. - - EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves - like the integer 12 when compared, but doesn't support arithmetic. - - XXX Should it record the actual enumeration rather than just its - name? - """ - - def __new__(cls, classname, enumname, value): - return int.__new__(cls, value) - - def __init__(self, classname, enumname, value): - self.__classname = classname - self.__enumname = enumname - - def __repr__(self): - return "EnumInstance(%s, %s, %d)" % (self.__classname, self.__enumname, - self) - - def __str__(self): - return "%s.%s" % (self.__classname, self.__enumname) - -class Enum(metaclass=EnumMetaclass): - pass - -class FullEnum(metaclass=FullEnumMetaclass): - pass - -def _test(): - - class Color(Enum): - red = 1 - green = 2 - blue = 3 - - print(Color.red) - - print(repr(Color.red)) - print(Color.red == Color.red) - print(Color.red == Color.blue) - print(Color.red == 1) - print(Color.red == 2) - - class ExtendedColor(Color): - white = 0 - orange = 4 - yellow = 5 - purple = 6 - black = 7 - - print(ExtendedColor.orange) - print(ExtendedColor.red) - - print(Color.red == ExtendedColor.red) - - class OtherColor(Enum): - white = 4 - blue = 5 - - class MergedColor(Color, OtherColor): - pass - - print(MergedColor.red) - print(MergedColor.white) - - print(Color) - print(ExtendedColor) - print(OtherColor) - print(MergedColor) - -def _test2(): - - class Color(FullEnum): - red = 1 - green = 2 - blue = 3 - - print(Color.red) - - print(repr(Color.red)) - print(Color.red == Color.red) - print(Color.red == Color.blue) - print(Color.red == 1) - print(Color.red == 2) - - class ExtendedColor(Color): - white = 0 - orange = 4 - yellow = 5 - purple = 6 - black = 7 - - print(ExtendedColor.orange) - print(ExtendedColor.red) - - print(Color.red == ExtendedColor.red) - - class OtherColor(FullEnum): - white = 4 - blue = 5 - - class MergedColor(Color, OtherColor): - pass - - print(MergedColor.red) - print(MergedColor.white) - - print(Color) - print(ExtendedColor) - print(OtherColor) - print(MergedColor) - -if __name__ == '__main__': - _test() - _test2() diff --git a/Demo/parser/FILES b/Demo/parser/FILES deleted file mode 100644 index 1ff59a3..0000000 --- a/Demo/parser/FILES +++ /dev/null @@ -1,6 +0,0 @@ -Demo/parser -Doc/libparser.tex -Lib/AST.py -Lib/symbol.py -Lib/token.py -Modules/parsermodule.c diff --git a/Demo/parser/README b/Demo/parser/README deleted file mode 100644 index a576d33..0000000 --- a/Demo/parser/README +++ /dev/null @@ -1,31 +0,0 @@ -These files are from the large example of using the `parser' module. Refer -to the Python Library Reference for more information. - -It also contains examples for the AST parser. - -Files: ------- - - FILES -- list of files associated with the parser module. - - README -- this file. - - example.py -- module that uses the `parser' module to extract - information from the parse tree of Python source - code. - - docstring.py -- sample source file containing only a module docstring. - - simple.py -- sample source containing a "short form" definition. - - source.py -- sample source code used to demonstrate ability to - handle nested constructs easily using the functions - and classes in example.py. - - test_parser.py program to put the parser module through its paces. - - unparse.py AST (2.5) based example to recreate source code - from an AST. This is incomplete; contributions - are welcome. - -Enjoy! diff --git a/Demo/parser/docstring.py b/Demo/parser/docstring.py deleted file mode 100644 index 45a261b..0000000 --- a/Demo/parser/docstring.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Some documentation. -""" diff --git a/Demo/parser/example.py b/Demo/parser/example.py deleted file mode 100644 index c2f0883..0000000 --- a/Demo/parser/example.py +++ /dev/null @@ -1,190 +0,0 @@ -"""Simple code to extract class & function docstrings from a module. - -This code is used as an example in the library reference manual in the -section on using the parser module. Refer to the manual for a thorough -discussion of the operation of this code. -""" - -import os -import parser -import symbol -import token -import types - -from types import ListType, TupleType - - -def get_docs(fileName): - """Retrieve information from the parse tree of a source file. - - fileName - Name of the file to read Python source code from. - """ - source = open(fileName).read() - basename = os.path.basename(os.path.splitext(fileName)[0]) - ast = parser.suite(source) - return ModuleInfo(ast.totuple(), basename) - - -class SuiteInfoBase: - _docstring = '' - _name = '' - - def __init__(self, tree = None): - self._class_info = {} - self._function_info = {} - if tree: - self._extract_info(tree) - - def _extract_info(self, tree): - # extract docstring - if len(tree) == 2: - found, vars = match(DOCSTRING_STMT_PATTERN[1], tree[1]) - else: - found, vars = match(DOCSTRING_STMT_PATTERN, tree[3]) - if found: - self._docstring = eval(vars['docstring']) - # discover inner definitions - for node in tree[1:]: - found, vars = match(COMPOUND_STMT_PATTERN, node) - if found: - cstmt = vars['compound'] - if cstmt[0] == symbol.funcdef: - name = cstmt[2][1] - self._function_info[name] = FunctionInfo(cstmt) - elif cstmt[0] == symbol.classdef: - name = cstmt[2][1] - self._class_info[name] = ClassInfo(cstmt) - - def get_docstring(self): - return self._docstring - - def get_name(self): - return self._name - - def get_class_names(self): - return list(self._class_info.keys()) - - def get_class_info(self, name): - return self._class_info[name] - - def __getitem__(self, name): - try: - return self._class_info[name] - except KeyError: - return self._function_info[name] - - -class SuiteFuncInfo: - # Mixin class providing access to function names and info. - - def get_function_names(self): - return list(self._function_info.keys()) - - def get_function_info(self, name): - return self._function_info[name] - - -class FunctionInfo(SuiteInfoBase, SuiteFuncInfo): - def __init__(self, tree = None): - self._name = tree[2][1] - SuiteInfoBase.__init__(self, tree and tree[-1] or None) - - -class ClassInfo(SuiteInfoBase): - def __init__(self, tree = None): - self._name = tree[2][1] - SuiteInfoBase.__init__(self, tree and tree[-1] or None) - - def get_method_names(self): - return list(self._function_info.keys()) - - def get_method_info(self, name): - return self._function_info[name] - - -class ModuleInfo(SuiteInfoBase, SuiteFuncInfo): - def __init__(self, tree = None, name = "<string>"): - self._name = name - SuiteInfoBase.__init__(self, tree) - if tree: - found, vars = match(DOCSTRING_STMT_PATTERN, tree[1]) - if found: - self._docstring = vars["docstring"] - - -def match(pattern, data, vars=None): - """Match `data' to `pattern', with variable extraction. - - pattern - Pattern to match against, possibly containing variables. - - data - Data to be checked and against which variables are extracted. - - vars - Dictionary of variables which have already been found. If not - provided, an empty dictionary is created. - - The `pattern' value may contain variables of the form ['varname'] which - are allowed to match anything. The value that is matched is returned as - part of a dictionary which maps 'varname' to the matched value. 'varname' - is not required to be a string object, but using strings makes patterns - and the code which uses them more readable. - - This function returns two values: a boolean indicating whether a match - was found and a dictionary mapping variable names to their associated - values. - """ - if vars is None: - vars = {} - if type(pattern) is ListType: # 'variables' are ['varname'] - vars[pattern[0]] = data - return 1, vars - if type(pattern) is not TupleType: - return (pattern == data), vars - if len(data) != len(pattern): - return 0, vars - for pattern, data in map(None, pattern, data): - same, vars = match(pattern, data, vars) - if not same: - break - return same, vars - - -# This pattern identifies compound statements, allowing them to be readily -# differentiated from simple statements. -# -COMPOUND_STMT_PATTERN = ( - symbol.stmt, - (symbol.compound_stmt, ['compound']) - ) - - -# This pattern will match a 'stmt' node which *might* represent a docstring; -# docstrings require that the statement which provides the docstring be the -# first statement in the class or function, which this pattern does not check. -# -DOCSTRING_STMT_PATTERN = ( - symbol.stmt, - (symbol.simple_stmt, - (symbol.small_stmt, - (symbol.expr_stmt, - (symbol.testlist, - (symbol.test, - (symbol.and_test, - (symbol.not_test, - (symbol.comparison, - (symbol.expr, - (symbol.xor_expr, - (symbol.and_expr, - (symbol.shift_expr, - (symbol.arith_expr, - (symbol.term, - (symbol.factor, - (symbol.power, - (symbol.atom, - (token.STRING, ['docstring']) - )))))))))))))))), - (token.NEWLINE, '') - )) diff --git a/Demo/parser/simple.py b/Demo/parser/simple.py deleted file mode 100644 index 184e2fe..0000000 --- a/Demo/parser/simple.py +++ /dev/null @@ -1 +0,0 @@ -def f(): "maybe a docstring" diff --git a/Demo/parser/source.py b/Demo/parser/source.py deleted file mode 100644 index b900628..0000000 --- a/Demo/parser/source.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Exmaple file to be parsed for the parsermodule example. - -The classes and functions in this module exist only to exhibit the ability -of the handling information extraction from nested definitions using parse -trees. They shouldn't interest you otherwise! -""" - -class Simple: - "This class does very little." - - def method(self): - "This method does almost nothing." - return 1 - - class Nested: - "This is a nested class." - - def nested_method(self): - "Method of Nested class." - def nested_function(): - "Function in method of Nested class." - pass - return nested_function - -def function(): - "This function lives at the module level." - return 0 diff --git a/Demo/parser/test_parser.py b/Demo/parser/test_parser.py deleted file mode 100755 index e4d5571..0000000 --- a/Demo/parser/test_parser.py +++ /dev/null @@ -1,48 +0,0 @@ -#! /usr/bin/env python -# (Force the script to use the latest build.) -# -# test_parser.py - -import parser, traceback - -_numFailed = 0 - -def testChunk(t, fileName): - global _numFailed - print('----', fileName, end=' ') - try: - ast = parser.suite(t) - tup = parser.ast2tuple(ast) - # this discards the first AST; a huge memory savings when running - # against a large source file like Tkinter.py. - ast = None - new = parser.tuple2ast(tup) - except parser.ParserError as err: - print() - print('parser module raised exception on input file', fileName + ':') - traceback.print_exc() - _numFailed = _numFailed + 1 - else: - if tup != parser.ast2tuple(new): - print() - print('parser module failed on input file', fileName) - _numFailed = _numFailed + 1 - else: - print('o.k.') - -def testFile(fileName): - t = open(fileName).read() - testChunk(t, fileName) - -def test(): - import sys - args = sys.argv[1:] - if not args: - import glob - args = glob.glob("*.py") - args.sort() - list(map(testFile, args)) - sys.exit(_numFailed != 0) - -if __name__ == '__main__': - test() diff --git a/Demo/parser/texipre.dat b/Demo/parser/texipre.dat deleted file mode 100644 index 8ad03a6..0000000 --- a/Demo/parser/texipre.dat +++ /dev/null @@ -1,100 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename parser.info -@settitle Python Parser Module Reference -@setchapternewpage odd -@footnotestyle end -@c %**end of header - -@ifinfo -This file describes the interfaces -published by the optional @code{parser} module and gives examples of -how they may be used. It contains the same text as the chapter on the -@code{parser} module in the @cite{Python Library Reference}, but is -presented as a separate document. - -Copyright 1995-1996 by Fred L. Drake, Jr., Reston, Virginia, USA, and -Virginia Polytechnic Institute and State University, Blacksburg, -Virginia, USA. Portions of the software copyright 1991-1995 by -Stichting Mathematisch Centrum, Amsterdam, The Netherlands. Copying is -permitted under the terms associated with the main Python distribution, -with the additional restriction that this additional notice be included -and maintained on all distributed copies. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Fred L. Drake, Jr. and -Virginia Polytechnic Institute and State University not be used in -advertising or publicity pertaining to distribution of the software -without specific, written prior permission. - -FRED L. DRAKE, JR. AND VIRGINIA POLYTECHNIC INSTITUTE AND STATE -UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FRED L. DRAKE, JR. OR VIRGINIA POLYTECHNIC INSTITUTE AND -STATE UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -@end ifinfo - -@titlepage -@title Python Parser Module Reference -@author Fred L. Drake, Jr. - -@c The following two commands start the copyright page. -@page -@vskip 0pt plus 1filll -Copyright 1995-1996 by Fred L. Drake, Jr., Reston, Virginia, USA, and -Virginia Polytechnic Institute and State University, Blacksburg, -Virginia, USA. Portions of the software copyright 1991-1995 by -Stichting Mathematisch Centrum, Amsterdam, The Netherlands. Copying is -permitted under the terms associated with the main Python distribution, -with the additional restriction that this additional notice be included -and maintained on all distributed copies. - -@center All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Fred L. Drake, Jr. and -Virginia Polytechnic Institute and State University not be used in -advertising or publicity pertaining to distribution of the software -without specific, written prior permission. - -FRED L. DRAKE, JR. AND VIRGINIA POLYTECHNIC INSTITUTE AND STATE -UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FRED L. DRAKE, JR. OR VIRGINIA POLYTECHNIC INSTITUTE AND -STATE UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -@end titlepage - - -@node Top, Overview, (dir), (dir) -@top The Python Parser Module - -@ifinfo -This file describes the interfaces -published by the optional @code{parser} module and gives examples of -how they may be used. It contains the same text as the chapter on the -@code{parser} module in the @cite{Python Library Reference}, but is -presented as a separate document. - -This version corresponds to Python version 1.4 (1 Sept. 1996). - -@end ifinfo - -@c placeholder for the master menu -- patched by texinfo-all-menus-update -@menu -@end menu diff --git a/Demo/parser/unparse.py b/Demo/parser/unparse.py deleted file mode 100644 index d53a6c4..0000000 --- a/Demo/parser/unparse.py +++ /dev/null @@ -1,509 +0,0 @@ -"Usage: unparse.py <path to source file>" -import sys -import _ast -import io -import os - -def interleave(inter, f, seq): - """Call f on each item in seq, calling inter() in between. - """ - seq = iter(seq) - try: - f(next(seq)) - except StopIteration: - pass - else: - for x in seq: - inter() - f(x) - -class Unparser: - """Methods in this class recursively traverse an AST and - output source code for the abstract syntax; original formatting - is disregarged. """ - - def __init__(self, tree, file = sys.stdout): - """Unparser(tree, file=sys.stdout) -> None. - Print the source for tree to file.""" - self.f = file - self._indent = 0 - self.dispatch(tree) - print("", file=self.f) - self.f.flush() - - def fill(self, text = ""): - "Indent a piece of text, according to the current indentation level" - self.f.write("\n"+" "*self._indent + text) - - def write(self, text): - "Append a piece of text to the current line." - self.f.write(text) - - def enter(self): - "Print ':', and increase the indentation." - self.write(":") - self._indent += 1 - - def leave(self): - "Decrease the indentation level." - self._indent -= 1 - - def dispatch(self, tree): - "Dispatcher function, dispatching tree type T to method _T." - if isinstance(tree, list): - for t in tree: - self.dispatch(t) - return - meth = getattr(self, "_"+tree.__class__.__name__) - meth(tree) - - - ############### Unparsing methods ###################### - # There should be one method per concrete grammar type # - # Constructors should be grouped by sum type. Ideally, # - # this would follow the order in the grammar, but # - # currently doesn't. # - ######################################################## - - def _Module(self, tree): - for stmt in tree.body: - self.dispatch(stmt) - - # stmt - def _Expr(self, tree): - self.fill() - self.dispatch(tree.value) - - def _Import(self, t): - self.fill("import ") - interleave(lambda: self.write(", "), self.dispatch, t.names) - - def _ImportFrom(self, t): - self.fill("from ") - self.write(t.module) - self.write(" import ") - interleave(lambda: self.write(", "), self.dispatch, t.names) - # XXX(jpe) what is level for? - - def _Assign(self, t): - self.fill() - for target in t.targets: - self.dispatch(target) - self.write(" = ") - self.dispatch(t.value) - - def _AugAssign(self, t): - self.fill() - self.dispatch(t.target) - self.write(" "+self.binop[t.op.__class__.__name__]+"= ") - self.dispatch(t.value) - - def _Return(self, t): - self.fill("return") - if t.value: - self.write(" ") - self.dispatch(t.value) - - def _Pass(self, t): - self.fill("pass") - - def _Break(self, t): - self.fill("break") - - def _Continue(self, t): - self.fill("continue") - - def _Delete(self, t): - self.fill("del ") - self.dispatch(t.targets) - - def _Assert(self, t): - self.fill("assert ") - self.dispatch(t.test) - if t.msg: - self.write(", ") - self.dispatch(t.msg) - - def _Print(self, t): - self.fill("print ") - do_comma = False - if t.dest: - self.write(">>") - self.dispatch(t.dest) - do_comma = True - for e in t.values: - if do_comma:self.write(", ") - else:do_comma=True - self.dispatch(e) - if not t.nl: - self.write(",") - - def _Global(self, t): - self.fill("global ") - interleave(lambda: self.write(", "), self.write, t.names) - - def _Yield(self, t): - self.write("(") - self.write("yield") - if t.value: - self.write(" ") - self.dispatch(t.value) - self.write(")") - - def _Raise(self, t): - self.fill('raise ') - if t.type: - self.dispatch(t.type) - if t.inst: - self.write(", ") - self.dispatch(t.inst) - if t.tback: - self.write(", ") - self.dispatch(t.tback) - - def _TryExcept(self, t): - self.fill("try") - self.enter() - self.dispatch(t.body) - self.leave() - - for ex in t.handlers: - self.dispatch(ex) - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave() - - def _TryFinally(self, t): - self.fill("try") - self.enter() - self.dispatch(t.body) - self.leave() - - self.fill("finally") - self.enter() - self.dispatch(t.finalbody) - self.leave() - - def _ExceptHandler(self, t): - self.fill("except") - if t.type: - self.write(" ") - self.dispatch(t.type) - if t.name: - self.write(", ") - self.dispatch(t.name) - self.enter() - self.dispatch(t.body) - self.leave() - - def _ClassDef(self, t): - self.write("\n") - self.fill("class "+t.name) - if t.bases: - self.write("(") - for a in t.bases: - self.dispatch(a) - self.write(", ") - self.write(")") - self.enter() - self.dispatch(t.body) - self.leave() - - def _FunctionDef(self, t): - self.write("\n") - for deco in t.decorator_list: - self.fill("@") - self.dispatch(deco) - self.fill("def "+t.name + "(") - self.dispatch(t.args) - self.write(")") - self.enter() - self.dispatch(t.body) - self.leave() - - def _For(self, t): - self.fill("for ") - self.dispatch(t.target) - self.write(" in ") - self.dispatch(t.iter) - self.enter() - self.dispatch(t.body) - self.leave() - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave - - def _If(self, t): - self.fill("if ") - self.dispatch(t.test) - self.enter() - # XXX elif? - self.dispatch(t.body) - self.leave() - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave() - - def _While(self, t): - self.fill("while ") - self.dispatch(t.test) - self.enter() - self.dispatch(t.body) - self.leave() - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave - - def _With(self, t): - self.fill("with ") - self.dispatch(t.context_expr) - if t.optional_vars: - self.write(" as ") - self.dispatch(t.optional_vars) - self.enter() - self.dispatch(t.body) - self.leave() - - # expr - def _Str(self, tree): - self.write(repr(tree.s)) - - def _Name(self, t): - self.write(t.id) - - def _Repr(self, t): - self.write("`") - self.dispatch(t.value) - self.write("`") - - def _Num(self, t): - self.write(repr(t.n)) - - def _List(self, t): - self.write("[") - interleave(lambda: self.write(", "), self.dispatch, t.elts) - self.write("]") - - def _ListComp(self, t): - self.write("[") - self.dispatch(t.elt) - for gen in t.generators: - self.dispatch(gen) - self.write("]") - - def _GeneratorExp(self, t): - self.write("(") - self.dispatch(t.elt) - for gen in t.generators: - self.dispatch(gen) - self.write(")") - - def _comprehension(self, t): - self.write(" for ") - self.dispatch(t.target) - self.write(" in ") - self.dispatch(t.iter) - for if_clause in t.ifs: - self.write(" if ") - self.dispatch(if_clause) - - def _IfExp(self, t): - self.write("(") - self.dispatch(t.body) - self.write(" if ") - self.dispatch(t.test) - self.write(" else ") - self.dispatch(t.orelse) - self.write(")") - - def _Dict(self, t): - self.write("{") - def writem(xxx_todo_changeme): - (k, v) = xxx_todo_changeme - self.dispatch(k) - self.write(": ") - self.dispatch(v) - interleave(lambda: self.write(", "), writem, zip(t.keys, t.values)) - self.write("}") - - def _Tuple(self, t): - self.write("(") - if len(t.elts) == 1: - (elt,) = t.elts - self.dispatch(elt) - self.write(",") - else: - interleave(lambda: self.write(", "), self.dispatch, t.elts) - self.write(")") - - unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"} - def _UnaryOp(self, t): - self.write(self.unop[t.op.__class__.__name__]) - self.write("(") - self.dispatch(t.operand) - self.write(")") - - binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%", - "LShift":">>", "RShift":"<<", "BitOr":"|", "BitXor":"^", "BitAnd":"&", - "FloorDiv":"//", "Pow": "**"} - def _BinOp(self, t): - self.write("(") - self.dispatch(t.left) - self.write(" " + self.binop[t.op.__class__.__name__] + " ") - self.dispatch(t.right) - self.write(")") - - cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=", - "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"} - def _Compare(self, t): - self.write("(") - self.dispatch(t.left) - for o, e in zip(t.ops, t.comparators): - self.write(" " + self.cmpops[o.__class__.__name__] + " ") - self.dispatch(e) - self.write(")") - - boolops = {_ast.And: 'and', _ast.Or: 'or'} - def _BoolOp(self, t): - self.write("(") - s = " %s " % self.boolops[t.op.__class__] - interleave(lambda: self.write(s), self.dispatch, t.values) - self.write(")") - - def _Attribute(self,t): - self.dispatch(t.value) - self.write(".") - self.write(t.attr) - - def _Call(self, t): - self.dispatch(t.func) - self.write("(") - comma = False - for e in t.args: - if comma: self.write(", ") - else: comma = True - self.dispatch(e) - for e in t.keywords: - if comma: self.write(", ") - else: comma = True - self.dispatch(e) - if t.starargs: - if comma: self.write(", ") - else: comma = True - self.write("*") - self.dispatch(t.starargs) - if t.kwargs: - if comma: self.write(", ") - else: comma = True - self.write("**") - self.dispatch(t.kwargs) - self.write(")") - - def _Subscript(self, t): - self.dispatch(t.value) - self.write("[") - self.dispatch(t.slice) - self.write("]") - - # slice - def _Ellipsis(self, t): - self.write("...") - - def _Index(self, t): - self.dispatch(t.value) - - def _Slice(self, t): - if t.lower: - self.dispatch(t.lower) - self.write(":") - if t.upper: - self.dispatch(t.upper) - if t.step: - self.write(":") - self.dispatch(t.step) - - def _ExtSlice(self, t): - interleave(lambda: self.write(', '), self.dispatch, t.dims) - - # others - def _arguments(self, t): - first = True - nonDef = len(t.args)-len(t.defaults) - for a in t.args[0:nonDef]: - if first:first = False - else: self.write(", ") - self.dispatch(a) - for a,d in zip(t.args[nonDef:], t.defaults): - if first:first = False - else: self.write(", ") - self.dispatch(a), - self.write("=") - self.dispatch(d) - if t.vararg: - if first:first = False - else: self.write(", ") - self.write("*"+t.vararg) - if t.kwarg: - if first:first = False - else: self.write(", ") - self.write("**"+t.kwarg) - - def _keyword(self, t): - self.write(t.arg) - self.write("=") - self.dispatch(t.value) - - def _Lambda(self, t): - self.write("lambda ") - self.dispatch(t.args) - self.write(": ") - self.dispatch(t.body) - - def _alias(self, t): - self.write(t.name) - if t.asname: - self.write(" as "+t.asname) - -def roundtrip(filename, output=sys.stdout): - source = open(filename).read() - tree = compile(source, filename, "exec", _ast.PyCF_ONLY_AST) - Unparser(tree, output) - - - -def testdir(a): - try: - names = [n for n in os.listdir(a) if n.endswith('.py')] - except OSError: - print("Directory not readable: %s" % a, file=sys.stderr) - else: - for n in names: - fullname = os.path.join(a, n) - if os.path.isfile(fullname): - output = io.StringIO() - print('Testing %s' % fullname) - try: - roundtrip(fullname, output) - except Exception as e: - print(' Failed to compile, exception is %s' % repr(e)) - elif os.path.isdir(fullname): - testdir(fullname) - -def main(args): - if args[0] == '--testdir': - for a in args[1:]: - testdir(a) - else: - for a in args: - roundtrip(a) - -if __name__=='__main__': - main(sys.argv[1:]) diff --git a/Demo/pdist/FSProxy.py b/Demo/pdist/FSProxy.py deleted file mode 100755 index 510ac76..0000000 --- a/Demo/pdist/FSProxy.py +++ /dev/null @@ -1,322 +0,0 @@ -"""File System Proxy. - -Provide an OS-neutral view on a file system, locally or remotely. -The functionality is geared towards implementing some sort of -rdist-like utility between a Mac and a UNIX system. - -The module defines three classes: - -FSProxyLocal -- used for local access -FSProxyServer -- used on the server side of remote access -FSProxyClient -- used on the client side of remote access - -The remote classes are instantiated with an IP address and an optional -verbosity flag. -""" - -import server -import client -import md5 -import os -import fnmatch -from stat import * -import time -import fnmatch - -if os.name == 'mac': - import macfs - maxnamelen = 31 -else: - macfs = None - maxnamelen = 255 - -skipnames = (os.curdir, os.pardir) - - -class FSProxyLocal: - - def __init__(self): - self._dirstack = [] - self._ignore = ['*.pyc'] + self._readignore() - - def _close(self): - while self._dirstack: - self.back() - - def _readignore(self): - file = self._hide('ignore') - try: - f = open(file) - except IOError: - file = self._hide('synctree.ignorefiles') - try: - f = open(file) - except IOError: - return [] - ignore = [] - while 1: - line = f.readline() - if not line: break - if line[-1] == '\n': line = line[:-1] - ignore.append(line) - f.close() - return ignore - - def _hidden(self, name): - if os.name == 'mac': - return name[0] == '(' and name[-1] == ')' - else: - return name[0] == '.' - - def _hide(self, name): - if os.name == 'mac': - return '(%s)' % name - else: - return '.%s' % name - - def visible(self, name): - if len(name) > maxnamelen: return 0 - if name[-1] == '~': return 0 - if name in skipnames: return 0 - if self._hidden(name): return 0 - head, tail = os.path.split(name) - if head or not tail: return 0 - if macfs: - if os.path.exists(name) and not os.path.isdir(name): - try: - fs = macfs.FSSpec(name) - c, t = fs.GetCreatorType() - if t != 'TEXT': return 0 - except macfs.error as msg: - print("***", name, msg) - return 0 - else: - if os.path.islink(name): return 0 - if '\0' in open(name, 'rb').read(512): return 0 - for ign in self._ignore: - if fnmatch.fnmatch(name, ign): return 0 - return 1 - - def check(self, name): - if not self.visible(name): - raise os.error("protected name %s" % repr(name)) - - def checkfile(self, name): - self.check(name) - if not os.path.isfile(name): - raise os.error("not a plain file %s" % repr(name)) - - def pwd(self): - return os.getcwd() - - def cd(self, name): - self.check(name) - save = os.getcwd(), self._ignore - os.chdir(name) - self._dirstack.append(save) - self._ignore = self._ignore + self._readignore() - - def back(self): - if not self._dirstack: - raise os.error("empty directory stack") - dir, ignore = self._dirstack[-1] - os.chdir(dir) - del self._dirstack[-1] - self._ignore = ignore - - def _filter(self, files, pat = None): - if pat: - def keep(name, pat = pat): - return fnmatch.fnmatch(name, pat) - files = list(filter(keep, files)) - files = list(filter(self.visible, files)) - files.sort() - return files - - def list(self, pat = None): - files = os.listdir(os.curdir) - return self._filter(files, pat) - - def listfiles(self, pat = None): - files = os.listdir(os.curdir) - files = list(filter(os.path.isfile, files)) - return self._filter(files, pat) - - def listsubdirs(self, pat = None): - files = os.listdir(os.curdir) - files = list(filter(os.path.isdir, files)) - return self._filter(files, pat) - - def exists(self, name): - return self.visible(name) and os.path.exists(name) - - def isdir(self, name): - return self.visible(name) and os.path.isdir(name) - - def islink(self, name): - return self.visible(name) and os.path.islink(name) - - def isfile(self, name): - return self.visible(name) and os.path.isfile(name) - - def sum(self, name): - self.checkfile(name) - BUFFERSIZE = 1024*8 - f = open(name) - sum = md5.new() - while 1: - buffer = f.read(BUFFERSIZE) - if not buffer: - break - sum.update(buffer) - return sum.digest() - - def size(self, name): - self.checkfile(name) - return os.stat(name)[ST_SIZE] - - def mtime(self, name): - self.checkfile(name) - return time.localtime(os.stat(name)[ST_MTIME]) - - def stat(self, name): - self.checkfile(name) - size = os.stat(name)[ST_SIZE] - mtime = time.localtime(os.stat(name)[ST_MTIME]) - return size, mtime - - def info(self, name): - sum = self.sum(name) - size = os.stat(name)[ST_SIZE] - mtime = time.localtime(os.stat(name)[ST_MTIME]) - return sum, size, mtime - - def _list(self, function, list): - if list is None: - list = self.listfiles() - res = [] - for name in list: - try: - res.append((name, function(name))) - except (os.error, IOError): - res.append((name, None)) - return res - - def sumlist(self, list = None): - return self._list(self.sum, list) - - def statlist(self, list = None): - return self._list(self.stat, list) - - def mtimelist(self, list = None): - return self._list(self.mtime, list) - - def sizelist(self, list = None): - return self._list(self.size, list) - - def infolist(self, list = None): - return self._list(self.info, list) - - def _dict(self, function, list): - if list is None: - list = self.listfiles() - dict = {} - for name in list: - try: - dict[name] = function(name) - except (os.error, IOError): - pass - return dict - - def sumdict(self, list = None): - return self.dict(self.sum, list) - - def sizedict(self, list = None): - return self.dict(self.size, list) - - def mtimedict(self, list = None): - return self.dict(self.mtime, list) - - def statdict(self, list = None): - return self.dict(self.stat, list) - - def infodict(self, list = None): - return self._dict(self.info, list) - - def read(self, name, offset = 0, length = -1): - self.checkfile(name) - f = open(name) - f.seek(offset) - if length == 0: - data = '' - elif length < 0: - data = f.read() - else: - data = f.read(length) - f.close() - return data - - def create(self, name): - self.check(name) - if os.path.exists(name): - self.checkfile(name) - bname = name + '~' - try: - os.unlink(bname) - except os.error: - pass - os.rename(name, bname) - f = open(name, 'w') - f.close() - - def write(self, name, data, offset = 0): - self.checkfile(name) - f = open(name, 'r+') - f.seek(offset) - f.write(data) - f.close() - - def mkdir(self, name): - self.check(name) - os.mkdir(name, 0o777) - - def rmdir(self, name): - self.check(name) - os.rmdir(name) - - -class FSProxyServer(FSProxyLocal, server.Server): - - def __init__(self, address, verbose = server.VERBOSE): - FSProxyLocal.__init__(self) - server.Server.__init__(self, address, verbose) - - def _close(self): - server.Server._close(self) - FSProxyLocal._close(self) - - def _serve(self): - server.Server._serve(self) - # Retreat into start directory - while self._dirstack: self.back() - - -class FSProxyClient(client.Client): - - def __init__(self, address, verbose = client.VERBOSE): - client.Client.__init__(self, address, verbose) - - -def test(): - import string - import sys - if sys.argv[1:]: - port = string.atoi(sys.argv[1]) - else: - port = 4127 - proxy = FSProxyServer(('', port)) - proxy._serverloop() - - -if __name__ == '__main__': - test() diff --git a/Demo/pdist/RCSProxy.py b/Demo/pdist/RCSProxy.py deleted file mode 100755 index 7c3b24f..0000000 --- a/Demo/pdist/RCSProxy.py +++ /dev/null @@ -1,198 +0,0 @@ -#! /usr/bin/env python - -"""RCS Proxy. - -Provide a simplified interface on RCS files, locally or remotely. -The functionality is geared towards implementing some sort of -remote CVS like utility. It is modeled after the similar module -FSProxy. - -The module defines two classes: - -RCSProxyLocal -- used for local access -RCSProxyServer -- used on the server side of remote access - -The corresponding client class, RCSProxyClient, is defined in module -rcsclient. - -The remote classes are instantiated with an IP address and an optional -verbosity flag. -""" - -import server -import md5 -import os -import fnmatch -import string -import tempfile -import rcslib - - -class DirSupport: - - def __init__(self): - self._dirstack = [] - - def __del__(self): - self._close() - - def _close(self): - while self._dirstack: - self.back() - - def pwd(self): - return os.getcwd() - - def cd(self, name): - save = os.getcwd() - os.chdir(name) - self._dirstack.append(save) - - def back(self): - if not self._dirstack: - raise os.error("empty directory stack") - dir = self._dirstack[-1] - os.chdir(dir) - del self._dirstack[-1] - - def listsubdirs(self, pat = None): - files = os.listdir(os.curdir) - files = list(filter(os.path.isdir, files)) - return self._filter(files, pat) - - def isdir(self, name): - return os.path.isdir(name) - - def mkdir(self, name): - os.mkdir(name, 0o777) - - def rmdir(self, name): - os.rmdir(name) - - -class RCSProxyLocal(rcslib.RCS, DirSupport): - - def __init__(self): - rcslib.RCS.__init__(self) - DirSupport.__init__(self) - - def __del__(self): - DirSupport.__del__(self) - rcslib.RCS.__del__(self) - - def sumlist(self, list = None): - return self._list(self.sum, list) - - def sumdict(self, list = None): - return self._dict(self.sum, list) - - def sum(self, name_rev): - f = self._open(name_rev) - BUFFERSIZE = 1024*8 - sum = md5.new() - while 1: - buffer = f.read(BUFFERSIZE) - if not buffer: - break - sum.update(buffer) - self._closepipe(f) - return sum.digest() - - def get(self, name_rev): - f = self._open(name_rev) - data = f.read() - self._closepipe(f) - return data - - def put(self, name_rev, data, message=None): - name, rev = self._unmangle(name_rev) - f = open(name, 'w') - f.write(data) - f.close() - self.checkin(name_rev, message) - self._remove(name) - - def _list(self, function, list = None): - """INTERNAL: apply FUNCTION to all files in LIST. - - Return a list of the results. - - The list defaults to all files in the directory if None. - - """ - if list is None: - list = self.listfiles() - res = [] - for name in list: - try: - res.append((name, function(name))) - except (os.error, IOError): - res.append((name, None)) - return res - - def _dict(self, function, list = None): - """INTERNAL: apply FUNCTION to all files in LIST. - - Return a dictionary mapping files to results. - - The list defaults to all files in the directory if None. - - """ - if list is None: - list = self.listfiles() - dict = {} - for name in list: - try: - dict[name] = function(name) - except (os.error, IOError): - pass - return dict - - -class RCSProxyServer(RCSProxyLocal, server.SecureServer): - - def __init__(self, address, verbose = server.VERBOSE): - RCSProxyLocal.__init__(self) - server.SecureServer.__init__(self, address, verbose) - - def _close(self): - server.SecureServer._close(self) - RCSProxyLocal._close(self) - - def _serve(self): - server.SecureServer._serve(self) - # Retreat into start directory - while self._dirstack: self.back() - - -def test_server(): - import string - import sys - if sys.argv[1:]: - port = string.atoi(sys.argv[1]) - else: - port = 4127 - proxy = RCSProxyServer(('', port)) - proxy._serverloop() - - -def test(): - import sys - if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789': - test_server() - sys.exit(0) - proxy = RCSProxyLocal() - what = sys.argv[1] - if hasattr(proxy, what): - attr = getattr(proxy, what) - if hasattr(attr, '__call__'): - print(attr(*sys.argv[2:])) - else: - print(repr(attr)) - else: - print("%s: no such attribute" % what) - sys.exit(2) - - -if __name__ == '__main__': - test() diff --git a/Demo/pdist/README b/Demo/pdist/README deleted file mode 100644 index b3fac24..0000000 --- a/Demo/pdist/README +++ /dev/null @@ -1,121 +0,0 @@ -Filesystem, RCS and CVS client and server classes -================================================= - -*** See the security warning at the end of this file! *** - -This directory contains various modules and classes that support -remote file system operations. - -CVS stuff ---------- - -rcvs Script to put in your bin directory -rcvs.py Remote CVS client command line interface - -cvslib.py CVS admin files classes (used by rrcs) -cvslock.py CVS locking algorithms - -RCS stuff ---------- - -rrcs Script to put in your bin directory -rrcs.py Remote RCS client command line interface - -rcsclient.py Return an RCSProxyClient instance - (has reasonable default server/port/directory) - -RCSProxy.py RCS proxy and server classes (on top of rcslib.py) - -rcslib.py Local-only RCS base class (affects stdout & - local work files) - -FSProxy stuff -------------- - -sumtree.py Old demo for FSProxy -cmptree.py First FSProxy client (used to sync from the Mac) -FSProxy.py Filesystem interface classes - -Generic client/server stuff ---------------------------- - -client.py Client class -server.py Server class - -security.py Security mix-in class (not very secure I think) - -Other generic stuff -------------------- - -cmdfw.py CommandFrameWork class - (used by rcvs, should be used by rrcs as well) - - -Client/Server operation ------------------------ - -The Client and Server classes implement a simple-minded RPC protocol, -using Python's pickle module to transfer arguments, return values and -exceptions with the most generality. The Server class is instantiated -with a port number on which it should listen for requests; the Client -class is instantiated with a host name and a port number where it -should connect to. Once a client is connected, a TCP connection is -maintained between client and server. - -The Server class currently handles only one connection at a time; -however it could be rewritten to allow various modes of operations, -using multiple threads or processes or the select() system call as -desired to serve multiple clients simultaneously (when using select(), -still handling one request at a time). This would not require -rewriting of the Client class. It may also be possible to adapt the -code to use UDP instead of TCP, but then both classes will have to be -rewritten (and unless extensive acknowlegements and request serial -numbers are used, the server should handle duplicate requests, so its -semantics should be idempotent -- shrudder). - -Even though the FSProxy and RCSProxy modules define client classes, -the client class is fully generic -- what methods it supports is -determined entirely by the server. The server class, however, must be -derived from. This is generally done as follows: - - from server import Server - from client import Client - - # Define a class that performs the operations locally - class MyClassLocal: - def __init__(self): ... - def _close(self): ... - - # Derive a server class using multiple inheritance - class MyClassServer(MyClassLocal, Server): - def __init__(self, address): - # Must initialize MyClassLocal as well as Server - MyClassLocal.__init__(self) - Server.__init__(self, address) - def _close(self): - Server._close() - MyClassLocal._close() - - # A dummy client class - class MyClassClient(Client): pass - -Note that because MyClassLocal isn't used in the definition of -MyClassClient, it would actually be better to place it in a separate -module so the definition of MyClassLocal isn't executed when we only -instantiate a client. - -The modules client and server should probably be renamed to Client and -Server in order to match the class names. - - -*** Security warning: this version requires that you have a file -$HOME/.python_keyfile at the server and client side containing two -comma- separated numbers. The security system at the moment makes no -guarantees of actuallng being secure -- however it requires that the -key file exists and contains the same numbers at both ends for this to -work. (You can specify an alternative keyfile in $PYTHON_KEYFILE). -Have a look at the Security class in security.py for details; -basically, if the key file contains (x, y), then the security server -class chooses a random number z (the challenge) in the range -10..100000 and the client must be able to produce pow(z, x, y) -(i.e. z**x mod y). diff --git a/Demo/pdist/client.py b/Demo/pdist/client.py deleted file mode 100755 index c9fe369..0000000 --- a/Demo/pdist/client.py +++ /dev/null @@ -1,156 +0,0 @@ -"""RPC Client module.""" - -import sys -import socket -import pickle -import builtins -import os - - -# Default verbosity (0 = silent, 1 = print connections, 2 = print requests too) -VERBOSE = 1 - - -class Client: - - """RPC Client class. No need to derive a class -- it's fully generic.""" - - def __init__(self, address, verbose = VERBOSE): - self._pre_init(address, verbose) - self._post_init() - - def _pre_init(self, address, verbose = VERBOSE): - if type(address) == type(0): - address = ('', address) - self._address = address - self._verbose = verbose - if self._verbose: print("Connecting to %s ..." % repr(address)) - self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._socket.connect(address) - if self._verbose: print("Connected.") - self._lastid = 0 # Last id for which a reply has been received - self._nextid = 1 # Id of next request - self._replies = {} # Unprocessed replies - self._rf = self._socket.makefile('r') - self._wf = self._socket.makefile('w') - - def _post_init(self): - self._methods = self._call('.methods') - - def __del__(self): - self._close() - - def _close(self): - if self._rf: self._rf.close() - self._rf = None - if self._wf: self._wf.close() - self._wf = None - if self._socket: self._socket.close() - self._socket = None - - def __getattr__(self, name): - if name in self._methods: - method = _stub(self, name) - setattr(self, name, method) # XXX circular reference - return method - raise AttributeError(name) - - def _setverbose(self, verbose): - self._verbose = verbose - - def _call(self, name, *args): - return self._vcall(name, args) - - def _vcall(self, name, args): - return self._recv(self._vsend(name, args)) - - def _send(self, name, *args): - return self._vsend(name, args) - - def _send_noreply(self, name, *args): - return self._vsend(name, args, 0) - - def _vsend_noreply(self, name, args): - return self._vsend(name, args, 0) - - def _vsend(self, name, args, wantreply = 1): - id = self._nextid - self._nextid = id+1 - if not wantreply: id = -id - request = (name, args, id) - if self._verbose > 1: print("sending request: %s" % repr(request)) - wp = pickle.Pickler(self._wf) - wp.dump(request) - return id - - def _recv(self, id): - exception, value, rid = self._vrecv(id) - if rid != id: - raise RuntimeError("request/reply id mismatch: %d/%d" % (id, rid)) - if exception is None: - return value - x = exception - if hasattr(builtins, exception): - x = getattr(builtins, exception) - elif exception in ('posix.error', 'mac.error'): - x = os.error - if x == exception: - exception = x - raise exception(value) - - def _vrecv(self, id): - self._flush() - if id in self._replies: - if self._verbose > 1: print("retrieving previous reply, id = %d" % id) - reply = self._replies[id] - del self._replies[id] - return reply - aid = abs(id) - while 1: - if self._verbose > 1: print("waiting for reply, id = %d" % id) - rp = pickle.Unpickler(self._rf) - reply = rp.load() - del rp - if self._verbose > 1: print("got reply: %s" % repr(reply)) - rid = reply[2] - arid = abs(rid) - if arid == aid: - if self._verbose > 1: print("got it") - return reply - self._replies[rid] = reply - if arid > aid: - if self._verbose > 1: print("got higher id, assume all ok") - return (None, None, id) - - def _flush(self): - self._wf.flush() - - -from security import Security - - -class SecureClient(Client, Security): - - def __init__(self, *args): - self._pre_init(*args) - Security.__init__(self) - self._wf.flush() - line = self._rf.readline() - challenge = int(line.strip()) - response = self._encode_challenge(challenge) - line = repr(int(response)) - if line[-1] in 'Ll': line = line[:-1] - self._wf.write(line + '\n') - self._wf.flush() - self._post_init() - -class _stub: - - """Helper class for Client -- each instance serves as a method of the client.""" - - def __init__(self, client, name): - self._client = client - self._name = name - - def __call__(self, *args): - return self._client._vcall(self._name, args) diff --git a/Demo/pdist/cmdfw.py b/Demo/pdist/cmdfw.py deleted file mode 100755 index ec854b1..0000000 --- a/Demo/pdist/cmdfw.py +++ /dev/null @@ -1,142 +0,0 @@ -"Framework for command line interfaces like CVS. See class CmdFrameWork." - - -class CommandFrameWork: - - """Framework class for command line interfaces like CVS. - - The general command line structure is - - command [flags] subcommand [subflags] [argument] ... - - There's a class variable GlobalFlags which specifies the - global flags options. Subcommands are defined by defining - methods named do_<subcommand>. Flags for the subcommand are - defined by defining class or instance variables named - flags_<subcommand>. If there's no command, method default() - is called. The __doc__ strings for the do_ methods are used - for the usage message, printed after the general usage message - which is the class variable UsageMessage. The class variable - PostUsageMessage is printed after all the do_ methods' __doc__ - strings. The method's return value can be a suggested exit - status. [XXX Need to rewrite this to clarify it.] - - Common usage is to derive a class, instantiate it, and then call its - run() method; by default this takes its arguments from sys.argv[1:]. - """ - - UsageMessage = \ - "usage: (name)s [flags] subcommand [subflags] [argument] ..." - - PostUsageMessage = None - - GlobalFlags = '' - - def __init__(self): - """Constructor, present for completeness.""" - pass - - def run(self, args = None): - """Process flags, subcommand and options, then run it.""" - import getopt, sys - if args is None: args = sys.argv[1:] - try: - opts, args = getopt.getopt(args, self.GlobalFlags) - except getopt.error as msg: - return self.usage(msg) - self.options(opts) - if not args: - self.ready() - return self.default() - else: - cmd = args[0] - mname = 'do_' + cmd - fname = 'flags_' + cmd - try: - method = getattr(self, mname) - except AttributeError: - return self.usage("command %r unknown" % (cmd,)) - try: - flags = getattr(self, fname) - except AttributeError: - flags = '' - try: - opts, args = getopt.getopt(args[1:], flags) - except getopt.error as msg: - return self.usage( - "subcommand %s: " % cmd + str(msg)) - self.ready() - return method(opts, args) - - def options(self, opts): - """Process the options retrieved by getopt. - Override this if you have any options.""" - if opts: - print("-"*40) - print("Options:") - for o, a in opts: - print('option', o, 'value', repr(a)) - print("-"*40) - - def ready(self): - """Called just before calling the subcommand.""" - pass - - def usage(self, msg = None): - """Print usage message. Return suitable exit code (2).""" - if msg: print(msg) - print(self.UsageMessage % {'name': self.__class__.__name__}) - docstrings = {} - c = self.__class__ - while 1: - for name in dir(c): - if name[:3] == 'do_': - if name in docstrings: - continue - try: - doc = getattr(c, name).__doc__ - except: - doc = None - if doc: - docstrings[name] = doc - if not c.__bases__: - break - c = c.__bases__[0] - if docstrings: - print("where subcommand can be:") - for name in sorted(docstrings.keys()): - print(docstrings[name]) - if self.PostUsageMessage: - print(self.PostUsageMessage) - return 2 - - def default(self): - """Default method, called when no subcommand is given. - You should always override this.""" - print("Nobody expects the Spanish Inquisition!") - - -def test(): - """Test script -- called when this module is run as a script.""" - import sys - class Hello(CommandFrameWork): - def do_hello(self, opts, args): - "hello -- print 'hello world', needs no arguments" - print("Hello, world") - x = Hello() - tests = [ - [], - ['hello'], - ['spam'], - ['-x'], - ['hello', '-x'], - None, - ] - for t in tests: - print('-'*10, t, '-'*10) - sts = x.run(t) - print("Exit status:", repr(sts)) - - -if __name__ == '__main__': - test() diff --git a/Demo/pdist/cmptree.py b/Demo/pdist/cmptree.py deleted file mode 100755 index c1bbf1a..0000000 --- a/Demo/pdist/cmptree.py +++ /dev/null @@ -1,213 +0,0 @@ -"""Compare local and remote dictionaries and transfer differing files -- like rdist.""" - -import sys -from reprlib import repr -import FSProxy -import time -import os - -def raw_input(prompt): - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() - -def main(): - pwd = os.getcwd() - s = input("chdir [%s] " % pwd) - if s: - os.chdir(s) - pwd = os.getcwd() - host = ask("host", 'voorn.cwi.nl') - port = 4127 - verbose = 1 - mode = '' - print("""\ -Mode should be a string of characters, indicating what to do with differences. -r - read different files to local file system -w - write different files to remote file system -c - create new files, either remote or local -d - delete disappearing files, either remote or local -""") - s = input("mode [%s] " % mode) - if s: mode = s - address = (host, port) - t1 = time.time() - local = FSProxy.FSProxyLocal() - remote = FSProxy.FSProxyClient(address, verbose) - compare(local, remote, mode) - remote._close() - local._close() - t2 = time.time() - dt = t2-t1 - mins, secs = divmod(dt, 60) - print(mins, "minutes and", round(secs), "seconds") - input("[Return to exit] ") - -def ask(prompt, default): - s = input("%s [%s] " % (prompt, default)) - return s or default - -def askint(prompt, default): - s = input("%s [%s] " % (prompt, str(default))) - if s: return string.atoi(s) - return default - -def compare(local, remote, mode): - print() - print("PWD =", repr(os.getcwd())) - sums_id = remote._send('sumlist') - subdirs_id = remote._send('listsubdirs') - remote._flush() - print("calculating local sums ...") - lsumdict = {} - for name, info in local.sumlist(): - lsumdict[name] = info - print("getting remote sums ...") - sums = remote._recv(sums_id) - print("got", len(sums)) - rsumdict = {} - for name, rsum in sums: - rsumdict[name] = rsum - if name not in lsumdict: - print(repr(name), "only remote") - if 'r' in mode and 'c' in mode: - recvfile(local, remote, name) - else: - lsum = lsumdict[name] - if lsum != rsum: - print(repr(name), end=' ') - rmtime = remote.mtime(name) - lmtime = local.mtime(name) - if rmtime > lmtime: - print("remote newer", end=' ') - if 'r' in mode: - recvfile(local, remote, name) - elif lmtime > rmtime: - print("local newer", end=' ') - if 'w' in mode: - sendfile(local, remote, name) - else: - print("same mtime but different sum?!?!", end=' ') - print() - for name in lsumdict.keys(): - if not list(rsumdict.keys()): - print(repr(name), "only locally", end=' ') - fl() - if 'w' in mode and 'c' in mode: - sendfile(local, remote, name) - elif 'r' in mode and 'd' in mode: - os.unlink(name) - print("removed.") - print() - print("gettin subdirs ...") - subdirs = remote._recv(subdirs_id) - common = [] - for name in subdirs: - if local.isdir(name): - print("Common subdirectory", repr(name)) - common.append(name) - else: - print("Remote subdirectory", repr(name), "not found locally") - if 'r' in mode and 'c' in mode: - pr = "Create local subdirectory %s? [y] " % \ - repr(name) - if 'y' in mode: - ok = 'y' - else: - ok = ask(pr, "y") - if ok[:1] in ('y', 'Y'): - local.mkdir(name) - print("Subdirectory %s made" % \ - repr(name)) - common.append(name) - lsubdirs = local.listsubdirs() - for name in lsubdirs: - if name not in subdirs: - print("Local subdirectory", repr(name), "not found remotely") - for name in common: - print("Entering subdirectory", repr(name)) - local.cd(name) - remote.cd(name) - compare(local, remote, mode) - remote.back() - local.back() - -def sendfile(local, remote, name): - try: - remote.create(name) - except (IOError, os.error) as msg: - print("cannot create:", msg) - return - - print("sending ...", end=' ') - fl() - - data = open(name).read() - - t1 = time.time() - - remote._send_noreply('write', name, data) - remote._flush() - - t2 = time.time() - - dt = t2-t1 - print(len(data), "bytes in", round(dt), "seconds", end=' ') - if dt: - print("i.e.", round(len(data)/dt), "bytes/sec", end=' ') - print() - -def recvfile(local, remote, name): - ok = 0 - try: - rv = recvfile_real(local, remote, name) - ok = 1 - return rv - finally: - if not ok: - print("*** recvfile of %r failed, deleting" % (name,)) - local.delete(name) - -def recvfile_real(local, remote, name): - try: - local.create(name) - except (IOError, os.error) as msg: - print("cannot create:", msg) - return - - print("receiving ...", end=' ') - fl() - - f = open(name, 'w') - t1 = time.time() - - length = 4*1024 - offset = 0 - id = remote._send('read', name, offset, length) - remote._flush() - while 1: - newoffset = offset + length - newid = remote._send('read', name, newoffset, length) - data = remote._recv(id) - id = newid - if not data: break - f.seek(offset) - f.write(data) - offset = newoffset - size = f.tell() - - t2 = time.time() - f.close() - - dt = t2-t1 - print(size, "bytes in", round(dt), "seconds", end=' ') - if dt: - print("i.e.", int(size//dt), "bytes/sec", end=' ') - print() - remote._recv(id) # ignored - -def fl(): - sys.stdout.flush() - -if __name__ == '__main__': - main() diff --git a/Demo/pdist/cvslib.py b/Demo/pdist/cvslib.py deleted file mode 100755 index 78e4fbb..0000000 --- a/Demo/pdist/cvslib.py +++ /dev/null @@ -1,359 +0,0 @@ -"""Utilities for CVS administration.""" - -import string -import os -import time -import md5 -import fnmatch - -if not hasattr(time, 'timezone'): - time.timezone = 0 - -class File: - - """Represent a file's status. - - Instance variables: - - file -- the filename (no slashes), None if uninitialized - lseen -- true if the data for the local file is up to date - eseen -- true if the data from the CVS/Entries entry is up to date - (this implies that the entry must be written back) - rseen -- true if the data for the remote file is up to date - proxy -- RCSProxy instance used to contact the server, or None - - Note that lseen and rseen don't necessary mean that a local - or remote file *exists* -- they indicate that we've checked it. - However, eseen means that this instance corresponds to an - entry in the CVS/Entries file. - - If lseen is true: - - lsum -- checksum of the local file, None if no local file - lctime -- ctime of the local file, None if no local file - lmtime -- mtime of the local file, None if no local file - - If eseen is true: - - erev -- revision, None if this is a no revision (not '0') - enew -- true if this is an uncommitted added file - edeleted -- true if this is an uncommitted removed file - ectime -- ctime of last local file corresponding to erev - emtime -- mtime of last local file corresponding to erev - extra -- 5th string from CVS/Entries file - - If rseen is true: - - rrev -- revision of head, None if non-existent - rsum -- checksum of that revision, Non if non-existent - - If eseen and rseen are both true: - - esum -- checksum of revision erev, None if no revision - - Note - """ - - def __init__(self, file = None): - if file and '/' in file: - raise ValueError("no slash allowed in file") - self.file = file - self.lseen = self.eseen = self.rseen = 0 - self.proxy = None - - def __cmp__(self, other): - return cmp(self.file, other.file) - - def getlocal(self): - try: - self.lmtime, self.lctime = os.stat(self.file)[-2:] - except os.error: - self.lmtime = self.lctime = self.lsum = None - else: - self.lsum = md5.new(open(self.file).read()).digest() - self.lseen = 1 - - def getentry(self, line): - words = string.splitfields(line, '/') - if self.file and words[1] != self.file: - raise ValueError("file name mismatch") - self.file = words[1] - self.erev = words[2] - self.edeleted = 0 - self.enew = 0 - self.ectime = self.emtime = None - if self.erev[:1] == '-': - self.edeleted = 1 - self.erev = self.erev[1:] - if self.erev == '0': - self.erev = None - self.enew = 1 - else: - dates = words[3] - self.ectime = unctime(dates[:24]) - self.emtime = unctime(dates[25:]) - self.extra = words[4] - if self.rseen: - self.getesum() - self.eseen = 1 - - def getremote(self, proxy = None): - if proxy: - self.proxy = proxy - try: - self.rrev = self.proxy.head(self.file) - except (os.error, IOError): - self.rrev = None - if self.rrev: - self.rsum = self.proxy.sum(self.file) - else: - self.rsum = None - if self.eseen: - self.getesum() - self.rseen = 1 - - def getesum(self): - if self.erev == self.rrev: - self.esum = self.rsum - elif self.erev: - name = (self.file, self.erev) - self.esum = self.proxy.sum(name) - else: - self.esum = None - - def putentry(self): - """Return a line suitable for inclusion in CVS/Entries. - - The returned line is terminated by a newline. - If no entry should be written for this file, - return "". - """ - if not self.eseen: - return "" - - rev = self.erev or '0' - if self.edeleted: - rev = '-' + rev - if self.enew: - dates = 'Initial ' + self.file - else: - dates = gmctime(self.ectime) + ' ' + \ - gmctime(self.emtime) - return "/%s/%s/%s/%s/\n" % ( - self.file, - rev, - dates, - self.extra) - - def report(self): - print('-'*50) - def r(key, repr=repr, self=self): - try: - value = repr(getattr(self, key)) - except AttributeError: - value = "?" - print("%-15s:" % key, value) - r("file") - if self.lseen: - r("lsum", hexify) - r("lctime", gmctime) - r("lmtime", gmctime) - if self.eseen: - r("erev") - r("enew") - r("edeleted") - r("ectime", gmctime) - r("emtime", gmctime) - if self.rseen: - r("rrev") - r("rsum", hexify) - if self.eseen: - r("esum", hexify) - - -class CVS: - - """Represent the contents of a CVS admin file (and more). - - Class variables: - - FileClass -- the class to be instantiated for entries - (this should be derived from class File above) - IgnoreList -- shell patterns for local files to be ignored - - Instance variables: - - entries -- a dictionary containing File instances keyed by - their file name - proxy -- an RCSProxy instance, or None - """ - - FileClass = File - - IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc'] - - def __init__(self): - self.entries = {} - self.proxy = None - - def setproxy(self, proxy): - if proxy is self.proxy: - return - self.proxy = proxy - for e in list(self.entries.values()): - e.rseen = 0 - - def getentries(self): - """Read the contents of CVS/Entries""" - self.entries = {} - f = self.cvsopen("Entries") - while 1: - line = f.readline() - if not line: break - e = self.FileClass() - e.getentry(line) - self.entries[e.file] = e - f.close() - - def putentries(self): - """Write CVS/Entries back""" - f = self.cvsopen("Entries", 'w') - for e in list(self.values()): - f.write(e.putentry()) - f.close() - - def getlocalfiles(self): - entries_keys = set(self.entries.keys()) - addlist = os.listdir(os.curdir) - for name in addlist: - if not self.ignored(name): - entries_keys.add(name) - for file in sorted(entries_keys): - try: - e = self.entries[file] - except KeyError: - e = self.entries[file] = self.FileClass(file) - e.getlocal() - - def getremotefiles(self, proxy = None): - if proxy: - self.proxy = proxy - if not self.proxy: - raise RuntimeError("no RCS proxy") - addlist = self.proxy.listfiles() - for file in addlist: - try: - e = self.entries[file] - except KeyError: - e = self.entries[file] = self.FileClass(file) - e.getremote(self.proxy) - - def report(self): - for e in list(self.values()): - e.report() - print('-'*50) - - def keys(self): - return sorted(self.entries.keys()) - - def values(self): - def value(key, self=self): - return self.entries[key] - return [value(k) for k in self.keys()] - - def items(self): - def item(key, self=self): - return (key, self.entries[key]) - return [item(k) for k in self.keys()] - - def cvsexists(self, file): - file = os.path.join("CVS", file) - return os.path.exists(file) - - def cvsopen(self, file, mode = 'r'): - file = os.path.join("CVS", file) - if 'r' not in mode: - self.backup(file) - return open(file, mode) - - def backup(self, file): - if os.path.isfile(file): - bfile = file + '~' - try: os.unlink(bfile) - except os.error: pass - os.rename(file, bfile) - - def ignored(self, file): - if os.path.isdir(file): return True - for pat in self.IgnoreList: - if fnmatch.fnmatch(file, pat): return True - return False - - -# hexify and unhexify are useful to print MD5 checksums in hex format - -hexify_format = '%02x' * 16 -def hexify(sum): - "Return a hex representation of a 16-byte string (e.g. an MD5 digest)" - if sum is None: - return "None" - return hexify_format % tuple(map(ord, sum)) - -def unhexify(hexsum): - "Return the original from a hexified string" - if hexsum == "None": - return None - sum = '' - for i in range(0, len(hexsum), 2): - sum = sum + chr(string.atoi(hexsum[i:i+2], 16)) - return sum - - -unctime_monthmap = {} -def unctime(date): - if date == "None": return None - if not unctime_monthmap: - months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - i = 0 - for m in months: - i = i+1 - unctime_monthmap[m] = i - words = string.split(date) # Day Mon DD HH:MM:SS YEAR - year = string.atoi(words[4]) - month = unctime_monthmap[words[1]] - day = string.atoi(words[2]) - [hh, mm, ss] = list(map(string.atoi, string.splitfields(words[3], ':'))) - ss = ss - time.timezone - return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0)) - -def gmctime(t): - if t is None: return "None" - return time.asctime(time.gmtime(t)) - -def test_unctime(): - now = int(time.time()) - t = time.gmtime(now) - at = time.asctime(t) - print('GMT', now, at) - print('timezone', time.timezone) - print('local', time.ctime(now)) - u = unctime(at) - print('unctime()', u) - gu = time.gmtime(u) - print('->', gu) - print(time.asctime(gu)) - -def test(): - x = CVS() - x.getentries() - x.getlocalfiles() -## x.report() - import rcsclient - proxy = rcsclient.openrcsclient() - x.getremotefiles(proxy) - x.report() - - -if __name__ == "__main__": - test() diff --git a/Demo/pdist/cvslock.py b/Demo/pdist/cvslock.py deleted file mode 100755 index ffaa15e..0000000 --- a/Demo/pdist/cvslock.py +++ /dev/null @@ -1,279 +0,0 @@ -"""CVS locking algorithm. - -CVS locking strategy -==================== - -As reverse engineered from the CVS 1.3 sources (file lock.c): - -- Locking is done on a per repository basis (but a process can hold -write locks for multiple directories); all lock files are placed in -the repository and have names beginning with "#cvs.". - -- Before even attempting to lock, a file "#cvs.tfl.<pid>" is created -(and removed again), to test that we can write the repository. [The -algorithm can still be fooled (1) if the repository's mode is changed -while attempting to lock; (2) if this file exists and is writable but -the directory is not.] - -- While creating the actual read/write lock files (which may exist for -a long time), a "meta-lock" is held. The meta-lock is a directory -named "#cvs.lock" in the repository. The meta-lock is also held while -a write lock is held. - -- To set a read lock: - - - acquire the meta-lock - - create the file "#cvs.rfl.<pid>" - - release the meta-lock - -- To set a write lock: - - - acquire the meta-lock - - check that there are no files called "#cvs.rfl.*" - - if there are, release the meta-lock, sleep, try again - - create the file "#cvs.wfl.<pid>" - -- To release a write lock: - - - remove the file "#cvs.wfl.<pid>" - - rmdir the meta-lock - -- To release a read lock: - - - remove the file "#cvs.rfl.<pid>" - - -Additional notes ----------------- - -- A process should read-lock at most one repository at a time. - -- A process may write-lock as many repositories as it wishes (to avoid -deadlocks, I presume it should always lock them top-down in the -directory hierarchy). - -- A process should make sure it removes all its lock files and -directories when it crashes. - -- Limitation: one user id should not be committing files into the same -repository at the same time. - - -Turn this into Python code --------------------------- - -rl = ReadLock(repository, waittime) - -wl = WriteLock(repository, waittime) - -list = MultipleWriteLock([repository1, repository2, ...], waittime) - -""" - - -import os -import time -import stat -import pwd - - -# Default wait time -DELAY = 10 - - -# XXX This should be the same on all Unix versions -EEXIST = 17 - - -# Files used for locking (must match cvs.h in the CVS sources) -CVSLCK = "#cvs.lck" -CVSRFL = "#cvs.rfl." -CVSWFL = "#cvs.wfl." - - -class Error: - - def __init__(self, msg): - self.msg = msg - - def __repr__(self): - return repr(self.msg) - - def __str__(self): - return str(self.msg) - - -class Locked(Error): - pass - - -class Lock: - - def __init__(self, repository = ".", delay = DELAY): - self.repository = repository - self.delay = delay - self.lockdir = None - self.lockfile = None - pid = repr(os.getpid()) - self.cvslck = self.join(CVSLCK) - self.cvsrfl = self.join(CVSRFL + pid) - self.cvswfl = self.join(CVSWFL + pid) - - def __del__(self): - print("__del__") - self.unlock() - - def setlockdir(self): - while 1: - try: - self.lockdir = self.cvslck - os.mkdir(self.cvslck, 0o777) - return - except os.error as msg: - self.lockdir = None - if msg.args[0] == EEXIST: - try: - st = os.stat(self.cvslck) - except os.error: - continue - self.sleep(st) - continue - raise Error("failed to lock %s: %s" % ( - self.repository, msg)) - - def unlock(self): - self.unlockfile() - self.unlockdir() - - def unlockfile(self): - if self.lockfile: - print("unlink", self.lockfile) - try: - os.unlink(self.lockfile) - except os.error: - pass - self.lockfile = None - - def unlockdir(self): - if self.lockdir: - print("rmdir", self.lockdir) - try: - os.rmdir(self.lockdir) - except os.error: - pass - self.lockdir = None - - def sleep(self, st): - sleep(st, self.repository, self.delay) - - def join(self, name): - return os.path.join(self.repository, name) - - -def sleep(st, repository, delay): - if delay <= 0: - raise Locked(st) - uid = st[stat.ST_UID] - try: - pwent = pwd.getpwuid(uid) - user = pwent[0] - except KeyError: - user = "uid %d" % uid - print("[%s]" % time.ctime(time.time())[11:19], end=' ') - print("Waiting for %s's lock in" % user, repository) - time.sleep(delay) - - -class ReadLock(Lock): - - def __init__(self, repository, delay = DELAY): - Lock.__init__(self, repository, delay) - ok = 0 - try: - self.setlockdir() - self.lockfile = self.cvsrfl - fp = open(self.lockfile, 'w') - fp.close() - ok = 1 - finally: - if not ok: - self.unlockfile() - self.unlockdir() - - -class WriteLock(Lock): - - def __init__(self, repository, delay = DELAY): - Lock.__init__(self, repository, delay) - self.setlockdir() - while 1: - uid = self.readers_exist() - if not uid: - break - self.unlockdir() - self.sleep(uid) - self.lockfile = self.cvswfl - fp = open(self.lockfile, 'w') - fp.close() - - def readers_exist(self): - n = len(CVSRFL) - for name in os.listdir(self.repository): - if name[:n] == CVSRFL: - try: - st = os.stat(self.join(name)) - except os.error: - continue - return st - return None - - -def MultipleWriteLock(repositories, delay = DELAY): - while 1: - locks = [] - for r in repositories: - try: - locks.append(WriteLock(r, 0)) - except Locked as instance: - del locks - break - else: - break - sleep(instance.msg, r, delay) - return list - - -def test(): - import sys - if sys.argv[1:]: - repository = sys.argv[1] - else: - repository = "." - rl = None - wl = None - try: - print("attempting write lock ...") - wl = WriteLock(repository) - print("got it.") - wl.unlock() - print("attempting read lock ...") - rl = ReadLock(repository) - print("got it.") - rl.unlock() - finally: - print([1]) - print([2]) - if rl: - rl.unlock() - print([3]) - if wl: - wl.unlock() - print([4]) - rl = None - print([5]) - wl = None - print([6]) - - -if __name__ == '__main__': - test() diff --git a/Demo/pdist/mac.py b/Demo/pdist/mac.py deleted file mode 100755 index beb77ec..0000000 --- a/Demo/pdist/mac.py +++ /dev/null @@ -1,24 +0,0 @@ -import sys -import rcvs - -def raw_input(prompt): - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() - -def main(): - while 1: - try: - line = input('$ ') - except EOFError: - break - words = line.split() - if not words: - continue - if words[0] != 'rcvs': - words.insert(0, 'rcvs') - sys.argv = words - rcvs.main() - -if __name__ == '__main__': - main() diff --git a/Demo/pdist/makechangelog.py b/Demo/pdist/makechangelog.py deleted file mode 100755 index db66e8f..0000000 --- a/Demo/pdist/makechangelog.py +++ /dev/null @@ -1,109 +0,0 @@ -#! /usr/bin/env python - -"""Turn a pile of RCS log output into ChangeLog file entries. - -""" - -import sys -import string -import re -import getopt -import time - -def main(): - args = sys.argv[1:] - opts, args = getopt.getopt(args, 'p:') - prefix = '' - for o, a in opts: - if p == '-p': prefix = a - - f = sys.stdin - allrevs = [] - while 1: - file = getnextfile(f) - if not file: break - revs = [] - while 1: - rev = getnextrev(f, file) - if not rev: - break - revs.append(rev) - if revs: - allrevs[len(allrevs):] = revs - allrevs.sort() - allrevs.reverse() - for rev in allrevs: - formatrev(rev, prefix) - -parsedateprog = re.compile( - '^date: ([0-9]+)/([0-9]+)/([0-9]+) ' + - '([0-9]+):([0-9]+):([0-9]+); author: ([^ ;]+)') - -authormap = { - 'guido': 'Guido van Rossum <guido@cnri.reston.va.us>', - 'jack': 'Jack Jansen <jack@cwi.nl>', - 'sjoerd': 'Sjoerd Mullender <sjoerd@cwi.nl>', - } - -def formatrev(rev, prefix): - dateline, file, revline, log = rev - if parsedateprog.match(dateline) >= 0: - fields = parsedateprog.group(1, 2, 3, 4, 5, 6) - author = parsedateprog.group(7) - if author in authormap: author = authormap[author] - tfields = list(map(string.atoi, fields)) + [0, 0, 0] - tfields[5] = tfields[5] - time.timezone - t = time.mktime(tuple(tfields)) - print(time.ctime(t), '', author) - words = string.split(log) - words[:0] = ['*', prefix + file + ':'] - maxcol = 72-8 - col = maxcol - for word in words: - if col > 0 and col + len(word) >= maxcol: - print() - print('\t' + word, end=' ') - col = -1 - else: - print(word, end=' ') - col = col + 1 + len(word) - print() - print() - -startprog = re.compile("^Working file: (.*)$") - -def getnextfile(f): - while 1: - line = f.readline() - if not line: return None - if startprog.match(line) >= 0: - file = startprog.group(1) - # Skip until first revision - while 1: - line = f.readline() - if not line: return None - if line[:10] == '='*10: return None - if line[:10] == '-'*10: break -## print "Skipped", line, - return file -## else: -## print "Ignored", line, - -def getnextrev(f, file): - # This is called when we are positioned just after a '---' separator - revline = f.readline() - dateline = f.readline() - log = '' - while 1: - line = f.readline() - if not line: break - if line[:10] == '='*10: - # Ignore the *last* log entry for each file since it - # is the revision since which we are logging. - return None - if line[:10] == '-'*10: break - log = log + line - return dateline, file, revline, log - -if __name__ == '__main__': - main() diff --git a/Demo/pdist/rcsbump b/Demo/pdist/rcsbump deleted file mode 100755 index 4fa078e..0000000 --- a/Demo/pdist/rcsbump +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -# -*- python -*- -# -# guido's version, from rcsbump,v 1.2 1995/06/22 21:27:27 bwarsaw Exp -# -# Python script for bumping up an RCS major revision number. - -import sys -import re -import rcslib -import string - -WITHLOCK = 1 -majorrev_re = re.compile('^[0-9]+') - -dir = rcslib.RCS() - -if sys.argv[1:]: - files = sys.argv[1:] -else: - files = dir.listfiles() - -for file in files: - # get the major revnumber of the file - headbranch = dir.info(file)['head'] - majorrev_re.match(headbranch) - majorrev = string.atoi(majorrev_re.group(0)) + 1 - - if not dir.islocked(file): - dir.checkout(file, WITHLOCK) - - msg = "Bumping major revision number (to %d)" % majorrev - dir.checkin((file, "%s.0" % majorrev), msg, "-f") diff --git a/Demo/pdist/rcsclient.py b/Demo/pdist/rcsclient.py deleted file mode 100755 index d8cb004..0000000 --- a/Demo/pdist/rcsclient.py +++ /dev/null @@ -1,71 +0,0 @@ -"""Customize this file to change the default client etc. - -(In general, it is probably be better to make local operation the -default and to require something like an RCSSERVER environment -variable to enable remote operation.) - -""" - -import string -import os - -# These defaults don't belong here -- they should be taken from the -# environment or from a hidden file in the current directory - -HOST = 'voorn.cwi.nl' -PORT = 4127 -VERBOSE = 1 -LOCAL = 0 - -import client - - -class RCSProxyClient(client.SecureClient): - - def __init__(self, address, verbose = client.VERBOSE): - client.SecureClient.__init__(self, address, verbose) - - -def openrcsclient(opts = []): - "open an RCSProxy client based on a list of options returned by getopt" - import RCSProxy - host = HOST - port = PORT - verbose = VERBOSE - local = LOCAL - directory = None - for o, a in opts: - if o == '-h': - host = a - if ':' in host: - i = string.find(host, ':') - host, p = host[:i], host[i+1:] - if p: - port = string.atoi(p) - if o == '-p': - port = string.atoi(a) - if o == '-d': - directory = a - if o == '-v': - verbose = verbose + 1 - if o == '-q': - verbose = 0 - if o == '-L': - local = 1 - if local: - import RCSProxy - x = RCSProxy.RCSProxyLocal() - else: - address = (host, port) - x = RCSProxyClient(address, verbose) - if not directory: - try: - directory = open(os.path.join("CVS", "Repository")).readline() - except IOError: - pass - else: - if directory[-1] == '\n': - directory = directory[:-1] - if directory: - x.cd(directory) - return x diff --git a/Demo/pdist/rcslib.py b/Demo/pdist/rcslib.py deleted file mode 100755 index 9690f3b..0000000 --- a/Demo/pdist/rcslib.py +++ /dev/null @@ -1,334 +0,0 @@ -"""RCS interface module. - -Defines the class RCS, which represents a directory with rcs version -files and (possibly) corresponding work files. - -""" - - -import fnmatch -import os -import re -import string -import tempfile - - -class RCS: - - """RCS interface class (local filesystem version). - - An instance of this class represents a directory with rcs version - files and (possible) corresponding work files. - - Methods provide access to most rcs operations such as - checkin/checkout, access to the rcs metadata (revisions, logs, - branches etc.) as well as some filesystem operations such as - listing all rcs version files. - - XXX BUGS / PROBLEMS - - - The instance always represents the current directory so it's not - very useful to have more than one instance around simultaneously - - """ - - # Characters allowed in work file names - okchars = string.ascii_letters + string.digits + '-_=+' - - def __init__(self): - """Constructor.""" - pass - - def __del__(self): - """Destructor.""" - pass - - # --- Informational methods about a single file/revision --- - - def log(self, name_rev, otherflags = ''): - """Return the full log text for NAME_REV as a string. - - Optional OTHERFLAGS are passed to rlog. - - """ - f = self._open(name_rev, 'rlog ' + otherflags) - data = f.read() - status = self._closepipe(f) - if status: - data = data + "%s: %s" % status - elif data[-1] == '\n': - data = data[:-1] - return data - - def head(self, name_rev): - """Return the head revision for NAME_REV""" - dict = self.info(name_rev) - return dict['head'] - - def info(self, name_rev): - """Return a dictionary of info (from rlog -h) for NAME_REV - - The dictionary's keys are the keywords that rlog prints - (e.g. 'head' and its values are the corresponding data - (e.g. '1.3'). - - XXX symbolic names and locks are not returned - - """ - f = self._open(name_rev, 'rlog -h') - dict = {} - while 1: - line = f.readline() - if not line: break - if line[0] == '\t': - # XXX could be a lock or symbolic name - # Anything else? - continue - i = string.find(line, ':') - if i > 0: - key, value = line[:i], string.strip(line[i+1:]) - dict[key] = value - status = self._closepipe(f) - if status: - raise IOError(status) - return dict - - # --- Methods that change files --- - - def lock(self, name_rev): - """Set an rcs lock on NAME_REV.""" - name, rev = self.checkfile(name_rev) - cmd = "rcs -l%s %s" % (rev, name) - return self._system(cmd) - - def unlock(self, name_rev): - """Clear an rcs lock on NAME_REV.""" - name, rev = self.checkfile(name_rev) - cmd = "rcs -u%s %s" % (rev, name) - return self._system(cmd) - - def checkout(self, name_rev, withlock=0, otherflags=""): - """Check out NAME_REV to its work file. - - If optional WITHLOCK is set, check out locked, else unlocked. - - The optional OTHERFLAGS is passed to co without - interpretation. - - Any output from co goes to directly to stdout. - - """ - name, rev = self.checkfile(name_rev) - if withlock: lockflag = "-l" - else: lockflag = "-u" - cmd = 'co %s%s %s %s' % (lockflag, rev, otherflags, name) - return self._system(cmd) - - def checkin(self, name_rev, message=None, otherflags=""): - """Check in NAME_REV from its work file. - - The optional MESSAGE argument becomes the checkin message - (default "<none>" if None); or the file description if this is - a new file. - - The optional OTHERFLAGS argument is passed to ci without - interpretation. - - Any output from ci goes to directly to stdout. - - """ - name, rev = self._unmangle(name_rev) - new = not self.isvalid(name) - if not message: message = "<none>" - if message and message[-1] != '\n': - message = message + '\n' - lockflag = "-u" - if new: - f = tempfile.NamedTemporaryFile() - f.write(message) - f.flush() - cmd = 'ci %s%s -t%s %s %s' % \ - (lockflag, rev, f.name, otherflags, name) - else: - message = re.sub(r'([\"$`])', r'\\\1', message) - cmd = 'ci %s%s -m"%s" %s %s' % \ - (lockflag, rev, message, otherflags, name) - return self._system(cmd) - - # --- Exported support methods --- - - def listfiles(self, pat = None): - """Return a list of all version files matching optional PATTERN.""" - files = os.listdir(os.curdir) - files = list(filter(self._isrcs, files)) - if os.path.isdir('RCS'): - files2 = os.listdir('RCS') - files2 = list(filter(self._isrcs, files2)) - files = files + files2 - files = list(map(self.realname, files)) - return self._filter(files, pat) - - def isvalid(self, name): - """Test whether NAME has a version file associated.""" - namev = self.rcsname(name) - return (os.path.isfile(namev) or - os.path.isfile(os.path.join('RCS', namev))) - - def rcsname(self, name): - """Return the pathname of the version file for NAME. - - The argument can be a work file name or a version file name. - If the version file does not exist, the name of the version - file that would be created by "ci" is returned. - - """ - if self._isrcs(name): namev = name - else: namev = name + ',v' - if os.path.isfile(namev): return namev - namev = os.path.join('RCS', os.path.basename(namev)) - if os.path.isfile(namev): return namev - if os.path.isdir('RCS'): - return os.path.join('RCS', namev) - else: - return namev - - def realname(self, namev): - """Return the pathname of the work file for NAME. - - The argument can be a work file name or a version file name. - If the work file does not exist, the name of the work file - that would be created by "co" is returned. - - """ - if self._isrcs(namev): name = namev[:-2] - else: name = namev - if os.path.isfile(name): return name - name = os.path.basename(name) - return name - - def islocked(self, name_rev): - """Test whether FILE (which must have a version file) is locked. - - XXX This does not tell you which revision number is locked and - ignores any revision you may pass in (by virtue of using rlog - -L -R). - - """ - f = self._open(name_rev, 'rlog -L -R') - line = f.readline() - status = self._closepipe(f) - if status: - raise IOError(status) - if not line: return None - if line[-1] == '\n': - line = line[:-1] - return self.realname(name_rev) == self.realname(line) - - def checkfile(self, name_rev): - """Normalize NAME_REV into a (NAME, REV) tuple. - - Raise an exception if there is no corresponding version file. - - """ - name, rev = self._unmangle(name_rev) - if not self.isvalid(name): - raise os.error('not an rcs file %r' % (name,)) - return name, rev - - # --- Internal methods --- - - def _open(self, name_rev, cmd = 'co -p', rflag = '-r'): - """INTERNAL: open a read pipe to NAME_REV using optional COMMAND. - - Optional FLAG is used to indicate the revision (default -r). - - Default COMMAND is "co -p". - - Return a file object connected by a pipe to the command's - output. - - """ - name, rev = self.checkfile(name_rev) - namev = self.rcsname(name) - if rev: - cmd = cmd + ' ' + rflag + rev - return os.popen("%s %r" % (cmd, namev)) - - def _unmangle(self, name_rev): - """INTERNAL: Normalize NAME_REV argument to (NAME, REV) tuple. - - Raise an exception if NAME contains invalid characters. - - A NAME_REV argument is either NAME string (implying REV='') or - a tuple of the form (NAME, REV). - - """ - if type(name_rev) == type(''): - name_rev = name, rev = name_rev, '' - else: - name, rev = name_rev - for c in rev: - if c not in self.okchars: - raise ValueError("bad char in rev") - return name_rev - - def _closepipe(self, f): - """INTERNAL: Close PIPE and print its exit status if nonzero.""" - sts = f.close() - if not sts: return None - detail, reason = divmod(sts, 256) - if reason == 0: return 'exit', detail # Exit status - signal = reason&0x7F - if signal == 0x7F: - code = 'stopped' - signal = detail - else: - code = 'killed' - if reason&0x80: - code = code + '(coredump)' - return code, signal - - def _system(self, cmd): - """INTERNAL: run COMMAND in a subshell. - - Standard input for the command is taken from /dev/null. - - Raise IOError when the exit status is not zero. - - Return whatever the calling method should return; normally - None. - - A derived class may override this method and redefine it to - capture stdout/stderr of the command and return it. - - """ - cmd = cmd + " </dev/null" - sts = os.system(cmd) - if sts: raise IOError("command exit status %d" % sts) - - def _filter(self, files, pat = None): - """INTERNAL: Return a sorted copy of the given list of FILES. - - If a second PATTERN argument is given, only files matching it - are kept. No check for valid filenames is made. - - """ - if pat: - def keep(name, pat = pat): - return fnmatch.fnmatch(name, pat) - files = list(filter(keep, files)) - else: - files = files[:] - files.sort() - return files - - def _remove(self, fn): - """INTERNAL: remove FILE without complaints.""" - try: - os.unlink(fn) - except os.error: - pass - - def _isrcs(self, name): - """INTERNAL: Test whether NAME ends in ',v'.""" - return name[-2:] == ',v' diff --git a/Demo/pdist/rcvs b/Demo/pdist/rcvs deleted file mode 100755 index f82a27a..0000000 --- a/Demo/pdist/rcvs +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python - -import addpack -addpack.addpack('/home/guido/src/python/Demo/pdist') - -import rcvs - -rcvs.main() diff --git a/Demo/pdist/rcvs.py b/Demo/pdist/rcvs.py deleted file mode 100755 index 4e2532a..0000000 --- a/Demo/pdist/rcvs.py +++ /dev/null @@ -1,476 +0,0 @@ -#! /usr/bin/env python - -"""Remote CVS -- command line interface""" - -# XXX To do: -# -# Bugs: -# - if the remote file is deleted, "rcvs update" will fail -# -# Functionality: -# - cvs rm -# - descend into directories (alraedy done for update) -# - conflict resolution -# - other relevant commands? -# - branches -# -# - Finesses: -# - retain file mode's x bits -# - complain when "nothing known about filename" -# - edit log message the way CVS lets you edit it -# - cvs diff -rREVA -rREVB -# - send mail the way CVS sends it -# -# Performance: -# - cache remote checksums (for every revision ever seen!) -# - translate symbolic revisions to numeric revisions -# -# Reliability: -# - remote locking -# -# Security: -# - Authenticated RPC? - - -from cvslib import CVS, File -import md5 -import os -import sys -from cmdfw import CommandFrameWork - - -DEF_LOCAL = 1 # Default -l - - -class MyFile(File): - - def action(self): - """Return a code indicating the update status of this file. - - The possible return values are: - - '=' -- everything's fine - '0' -- file doesn't exist anywhere - '?' -- exists locally only - 'A' -- new locally - 'R' -- deleted locally - 'U' -- changed remotely, no changes locally - (includes new remotely or deleted remotely) - 'M' -- changed locally, no changes remotely - 'C' -- conflict: changed locally as well as remotely - (includes cases where the file has been added - or removed locally and remotely) - 'D' -- deleted remotely - 'N' -- new remotely - 'r' -- get rid of entry - 'c' -- create entry - 'u' -- update entry - - (and probably others :-) - """ - if not self.lseen: - self.getlocal() - if not self.rseen: - self.getremote() - if not self.eseen: - if not self.lsum: - if not self.rsum: return '0' # Never heard of - else: - return 'N' # New remotely - else: # self.lsum - if not self.rsum: return '?' # Local only - # Local and remote, but no entry - if self.lsum == self.rsum: - return 'c' # Restore entry only - else: return 'C' # Real conflict - else: # self.eseen - if not self.lsum: - if self.edeleted: - if self.rsum: return 'R' # Removed - else: return 'r' # Get rid of entry - else: # not self.edeleted - if self.rsum: - print("warning:", end=' ') - print(self.file, end=' ') - print("was lost") - return 'U' - else: return 'r' # Get rid of entry - else: # self.lsum - if not self.rsum: - if self.enew: return 'A' # New locally - else: return 'D' # Deleted remotely - else: # self.rsum - if self.enew: - if self.lsum == self.rsum: - return 'u' - else: - return 'C' - if self.lsum == self.esum: - if self.esum == self.rsum: - return '=' - else: - return 'U' - elif self.esum == self.rsum: - return 'M' - elif self.lsum == self.rsum: - return 'u' - else: - return 'C' - - def update(self): - code = self.action() - if code == '=': return - print(code, self.file) - if code in ('U', 'N'): - self.get() - elif code == 'C': - print("%s: conflict resolution not yet implemented" % \ - self.file) - elif code == 'D': - remove(self.file) - self.eseen = 0 - elif code == 'r': - self.eseen = 0 - elif code in ('c', 'u'): - self.eseen = 1 - self.erev = self.rrev - self.enew = 0 - self.edeleted = 0 - self.esum = self.rsum - self.emtime, self.ectime = os.stat(self.file)[-2:] - self.extra = '' - - def commit(self, message = ""): - code = self.action() - if code in ('A', 'M'): - self.put(message) - return 1 - elif code == 'R': - print("%s: committing removes not yet implemented" % \ - self.file) - elif code == 'C': - print("%s: conflict resolution not yet implemented" % \ - self.file) - - def diff(self, opts = []): - self.action() # To update lseen, rseen - flags = '' - rev = self.rrev - # XXX should support two rev options too! - for o, a in opts: - if o == '-r': - rev = a - else: - flags = flags + ' ' + o + a - if rev == self.rrev and self.lsum == self.rsum: - return - flags = flags[1:] - fn = self.file - data = self.proxy.get((fn, rev)) - sum = md5.new(data).digest() - if self.lsum == sum: - return - import tempfile - tf = tempfile.NamedTemporaryFile() - tf.write(data) - tf.flush() - print('diff %s -r%s %s' % (flags, rev, fn)) - sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) - if sts: - print('='*70) - - def commitcheck(self): - return self.action() != 'C' - - def put(self, message = ""): - print("Checking in", self.file, "...") - data = open(self.file).read() - if not self.enew: - self.proxy.lock(self.file) - messages = self.proxy.put(self.file, data, message) - if messages: - print(messages) - self.setentry(self.proxy.head(self.file), self.lsum) - - def get(self): - data = self.proxy.get(self.file) - f = open(self.file, 'w') - f.write(data) - f.close() - self.setentry(self.rrev, self.rsum) - - def log(self, otherflags): - print(self.proxy.log(self.file, otherflags)) - - def add(self): - self.eseen = 0 # While we're hacking... - self.esum = self.lsum - self.emtime, self.ectime = 0, 0 - self.erev = '' - self.enew = 1 - self.edeleted = 0 - self.eseen = 1 # Done - self.extra = '' - - def setentry(self, erev, esum): - self.eseen = 0 # While we're hacking... - self.esum = esum - self.emtime, self.ectime = os.stat(self.file)[-2:] - self.erev = erev - self.enew = 0 - self.edeleted = 0 - self.eseen = 1 # Done - self.extra = '' - - -SENDMAIL = "/usr/lib/sendmail -t" -MAILFORM = """To: %s -Subject: CVS changes: %s - -...Message from rcvs... - -Committed files: - %s - -Log message: - %s -""" - - -class RCVS(CVS): - - FileClass = MyFile - - def __init__(self): - CVS.__init__(self) - - def update(self, files): - for e in self.whichentries(files, 1): - e.update() - - def commit(self, files, message = ""): - list = self.whichentries(files) - if not list: return - ok = 1 - for e in list: - if not e.commitcheck(): - ok = 0 - if not ok: - print("correct above errors first") - return - if not message: - message = input("One-liner: ") - committed = [] - for e in list: - if e.commit(message): - committed.append(e.file) - self.mailinfo(committed, message) - - def mailinfo(self, files, message = ""): - towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX - mailtext = MAILFORM % (towhom, ' '.join(files), - ' '.join(files), message) - print('-'*70) - print(mailtext) - print('-'*70) - ok = input("OK to mail to %s? " % towhom) - if ok.lower().strip() in ('y', 'ye', 'yes'): - p = os.popen(SENDMAIL, "w") - p.write(mailtext) - sts = p.close() - if sts: - print("Sendmail exit status %s" % str(sts)) - else: - print("Mail sent.") - else: - print("No mail sent.") - - def report(self, files): - for e in self.whichentries(files): - e.report() - - def diff(self, files, opts): - for e in self.whichentries(files): - e.diff(opts) - - def add(self, files): - if not files: - raise RuntimeError("'cvs add' needs at least one file") - list = [] - for e in self.whichentries(files, 1): - e.add() - - def rm(self, files): - if not files: - raise RuntimeError("'cvs rm' needs at least one file") - raise RuntimeError("'cvs rm' not yet imlemented") - - def log(self, files, opts): - flags = '' - for o, a in opts: - flags = flags + ' ' + o + a - for e in self.whichentries(files): - e.log(flags) - - def whichentries(self, files, localfilestoo = 0): - if files: - list = [] - for file in files: - if file in self.entries: - e = self.entries[file] - else: - e = self.FileClass(file) - self.entries[file] = e - list.append(e) - else: - list = list(self.entries.values()) - for file in self.proxy.listfiles(): - if file in self.entries: - continue - e = self.FileClass(file) - self.entries[file] = e - list.append(e) - if localfilestoo: - for file in os.listdir(os.curdir): - if file not in self.entries \ - and not self.ignored(file): - e = self.FileClass(file) - self.entries[file] = e - list.append(e) - list.sort() - if self.proxy: - for e in list: - if e.proxy is None: - e.proxy = self.proxy - return list - - -class rcvs(CommandFrameWork): - - GlobalFlags = 'd:h:p:qvL' - UsageMessage = \ -"usage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]" - PostUsageMessage = \ - "If no subcommand is given, the status of all files is listed" - - def __init__(self): - """Constructor.""" - CommandFrameWork.__init__(self) - self.proxy = None - self.cvs = RCVS() - - def close(self): - if self.proxy: - self.proxy._close() - self.proxy = None - - def recurse(self): - self.close() - names = os.listdir(os.curdir) - for name in names: - if name == os.curdir or name == os.pardir: - continue - if name == "CVS": - continue - if not os.path.isdir(name): - continue - if os.path.islink(name): - continue - print("--- entering subdirectory", name, "---") - os.chdir(name) - try: - if os.path.isdir("CVS"): - self.__class__().run() - else: - self.recurse() - finally: - os.chdir(os.pardir) - print("--- left subdirectory", name, "---") - - def options(self, opts): - self.opts = opts - - def ready(self): - import rcsclient - self.proxy = rcsclient.openrcsclient(self.opts) - self.cvs.setproxy(self.proxy) - self.cvs.getentries() - - def default(self): - self.cvs.report([]) - - def do_report(self, opts, files): - self.cvs.report(files) - - def do_update(self, opts, files): - """update [-l] [-R] [file] ...""" - local = DEF_LOCAL - for o, a in opts: - if o == '-l': local = 1 - if o == '-R': local = 0 - self.cvs.update(files) - self.cvs.putentries() - if not local and not files: - self.recurse() - flags_update = '-lR' - do_up = do_update - flags_up = flags_update - - def do_commit(self, opts, files): - """commit [-m message] [file] ...""" - message = "" - for o, a in opts: - if o == '-m': message = a - self.cvs.commit(files, message) - self.cvs.putentries() - flags_commit = 'm:' - do_com = do_commit - flags_com = flags_commit - - def do_diff(self, opts, files): - """diff [difflags] [file] ...""" - self.cvs.diff(files, opts) - flags_diff = 'cbitwcefhnlr:sD:S:' - do_dif = do_diff - flags_dif = flags_diff - - def do_add(self, opts, files): - """add file ...""" - if not files: - print("'rcvs add' requires at least one file") - return - self.cvs.add(files) - self.cvs.putentries() - - def do_remove(self, opts, files): - """remove file ...""" - if not files: - print("'rcvs remove' requires at least one file") - return - self.cvs.remove(files) - self.cvs.putentries() - do_rm = do_remove - - def do_log(self, opts, files): - """log [rlog-options] [file] ...""" - self.cvs.log(files, opts) - flags_log = 'bhLNRtd:s:V:r:' - - -def remove(fn): - try: - os.unlink(fn) - except os.error: - pass - - -def main(): - r = rcvs() - try: - r.run() - finally: - r.close() - - -if __name__ == "__main__": - main() diff --git a/Demo/pdist/rrcs b/Demo/pdist/rrcs deleted file mode 100755 index 31fc2c5..0000000 --- a/Demo/pdist/rrcs +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python - -import addpack -addpack.addpack('/home/guido/src/python/Demo/pdist') - -import rrcs - -rrcs.main() diff --git a/Demo/pdist/rrcs.py b/Demo/pdist/rrcs.py deleted file mode 100755 index 647ecc5..0000000 --- a/Demo/pdist/rrcs.py +++ /dev/null @@ -1,158 +0,0 @@ -#! /usr/bin/env python - -"Remote RCS -- command line interface" - -import sys -import os -import getopt -import string -import md5 -import tempfile -from rcsclient import openrcsclient - -def main(): - sys.stdout = sys.stderr - try: - opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL') - if not rest: - cmd = 'head' - else: - cmd, rest = rest[0], rest[1:] - if cmd not in commands: - raise getopt.error("unknown command") - coptset, func = commands[cmd] - copts, files = getopt.getopt(rest, coptset) - except getopt.error as msg: - print(msg) - print("usage: rrcs [options] command [options] [file] ...") - print("where command can be:") - print(" ci|put # checkin the given files") - print(" co|get # checkout") - print(" info # print header info") - print(" head # print revision of head branch") - print(" list # list filename if valid") - print(" log # print full log") - print(" diff # diff rcs file and work file") - print("if no files are given, all remote rcs files are assumed") - sys.exit(2) - x = openrcsclient(opts) - if not files: - files = x.listfiles() - for fn in files: - try: - func(x, copts, fn) - except (IOError, os.error) as msg: - print("%s: %s" % (fn, msg)) - -def checkin(x, copts, fn): - f = open(fn) - data = f.read() - f.close() - new = not x.isvalid(fn) - if not new and same(x, copts, fn, data): - print("%s: unchanged since last checkin" % fn) - return - print("Checking in", fn, "...") - message = asklogmessage(new) - messages = x.put(fn, data, message) - if messages: - print(messages) - -def checkout(x, copts, fn): - data = x.get(fn) - f = open(fn, 'w') - f.write(data) - f.close() - -def lock(x, copts, fn): - x.lock(fn) - -def unlock(x, copts, fn): - x.unlock(fn) - -def info(x, copts, fn): - info_dict = x.info(fn) - for key in sorted(info_dict.keys()): - print(key + ':', info_dict[key]) - print('='*70) - -def head(x, copts, fn): - head = x.head(fn) - print(fn, head) - -def list(x, copts, fn): - if x.isvalid(fn): - print(fn) - -def log(x, copts, fn): - flags = '' - for o, a in copts: - flags = flags + ' ' + o + a - flags = flags[1:] - messages = x.log(fn, flags) - print(messages) - -def diff(x, copts, fn): - if same(x, copts, fn): - return - flags = '' - for o, a in copts: - flags = flags + ' ' + o + a - flags = flags[1:] - data = x.get(fn) - tf = tempfile.NamedTemporaryFile() - tf.write(data) - tf.flush() - print('diff %s -r%s %s' % (flags, x.head(fn), fn)) - sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) - if sts: - print('='*70) - -def same(x, copts, fn, data = None): - if data is None: - f = open(fn) - data = f.read() - f.close() - lsum = md5.new(data).digest() - rsum = x.sum(fn) - return lsum == rsum - -def asklogmessage(new): - if new: - print("enter description,", end=' ') - else: - print("enter log message,", end=' ') - print("terminate with single '.' or end of file:") - if new: - print("NOTE: This is NOT the log message!") - message = "" - while 1: - sys.stderr.write(">> ") - sys.stderr.flush() - line = sys.stdin.readline() - if not line or line == '.\n': break - message = message + line - return message - -def remove(fn): - try: - os.unlink(fn) - except os.error: - pass - -commands = { - 'ci': ('', checkin), - 'put': ('', checkin), - 'co': ('', checkout), - 'get': ('', checkout), - 'info': ('', info), - 'head': ('', head), - 'list': ('', list), - 'lock': ('', lock), - 'unlock': ('', unlock), - 'log': ('bhLRtd:l:r:s:w:V:', log), - 'diff': ('c', diff), - } - -if __name__ == '__main__': - main() diff --git a/Demo/pdist/security.py b/Demo/pdist/security.py deleted file mode 100755 index ffdbe2d..0000000 --- a/Demo/pdist/security.py +++ /dev/null @@ -1,33 +0,0 @@ -class Security: - - def __init__(self): - import os - env = os.environ - if 'PYTHON_KEYFILE' in env: - keyfile = env['PYTHON_KEYFILE'] - else: - keyfile = '.python_keyfile' - if 'HOME' in env: - keyfile = os.path.join(env['HOME'], keyfile) - if not os.path.exists(keyfile): - import sys - for dir in sys.path: - kf = os.path.join(dir, keyfile) - if os.path.exists(kf): - keyfile = kf - break - try: - self._key = eval(open(keyfile).readline()) - except IOError: - raise IOError("python keyfile %s: cannot open" % keyfile) - - def _generate_challenge(self): - import random - return random.randint(100, 100000) - - def _compare_challenge_response(self, challenge, response): - return self._encode_challenge(challenge) == response - - def _encode_challenge(self, challenge): - p, m = self._key - return pow(int(challenge), p, m) diff --git a/Demo/pdist/server.py b/Demo/pdist/server.py deleted file mode 100755 index b3943ff..0000000 --- a/Demo/pdist/server.py +++ /dev/null @@ -1,143 +0,0 @@ -"""RPC Server module.""" - -import sys -import socket -import pickle -from fnmatch import fnmatch -from reprlib import repr - - -# Default verbosity (0 = silent, 1 = print connections, 2 = print requests too) -VERBOSE = 1 - - -class Server: - - """RPC Server class. Derive a class to implement a particular service.""" - - def __init__(self, address, verbose = VERBOSE): - if type(address) == type(0): - address = ('', address) - self._address = address - self._verbose = verbose - self._socket = None - self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._socket.bind(address) - self._socket.listen(1) - self._listening = 1 - - def _setverbose(self, verbose): - self._verbose = verbose - - def __del__(self): - self._close() - - def _close(self): - self._listening = 0 - if self._socket: - self._socket.close() - self._socket = None - - def _serverloop(self): - while self._listening: - self._serve() - - def _serve(self): - if self._verbose: print("Wait for connection ...") - conn, address = self._socket.accept() - if self._verbose: print("Accepted connection from %s" % repr(address)) - if not self._verify(conn, address): - print("*** Connection from %s refused" % repr(address)) - conn.close() - return - rf = conn.makefile('r') - wf = conn.makefile('w') - ok = 1 - while ok: - wf.flush() - if self._verbose > 1: print("Wait for next request ...") - ok = self._dorequest(rf, wf) - - _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*'] - - def _verify(self, conn, address): - host, port = address - for pat in self._valid: - if fnmatch(host, pat): return 1 - return 0 - - def _dorequest(self, rf, wf): - rp = pickle.Unpickler(rf) - try: - request = rp.load() - except EOFError: - return 0 - if self._verbose > 1: print("Got request: %s" % repr(request)) - try: - methodname, args, id = request - if '.' in methodname: - reply = (None, self._special(methodname, args), id) - elif methodname[0] == '_': - raise NameError("illegal method name %s" % repr(methodname)) - else: - method = getattr(self, methodname) - reply = (None, method(*args), id) - except: - reply = (sys.exc_info()[:2], id) - if id < 0 and reply[:2] == (None, None): - if self._verbose > 1: print("Suppress reply") - return 1 - if self._verbose > 1: print("Send reply: %s" % repr(reply)) - wp = pickle.Pickler(wf) - wp.dump(reply) - return 1 - - def _special(self, methodname, args): - if methodname == '.methods': - if not hasattr(self, '_methods'): - self._methods = tuple(self._listmethods()) - return self._methods - raise NameError("unrecognized special method name %s" % repr(methodname)) - - def _listmethods(self, cl=None): - if not cl: cl = self.__class__ - names = sorted([x for x in cl.__dict__.keys() if x[0] != '_']) - for base in cl.__bases__: - basenames = self._listmethods(base) - basenames = list(filter(lambda x, names=names: x not in names, basenames)) - names[len(names):] = basenames - return names - - -from security import Security - - -class SecureServer(Server, Security): - - def __init__(self, *args): - Server.__init__(self, *args) - Security.__init__(self) - - def _verify(self, conn, address): - import string - challenge = self._generate_challenge() - conn.send("%d\n" % challenge) - response = "" - while "\n" not in response and len(response) < 100: - data = conn.recv(100) - if not data: - break - response = response + data - try: - response = string.atol(string.strip(response)) - except string.atol_error: - if self._verbose > 0: - print("Invalid response syntax", repr(response)) - return 0 - if not self._compare_challenge_response(challenge, response): - if self._verbose > 0: - print("Invalid response value", repr(response)) - return 0 - if self._verbose > 1: - print("Response matches challenge. Go ahead!") - return 1 diff --git a/Demo/pdist/sumtree.py b/Demo/pdist/sumtree.py deleted file mode 100755 index 92e7771..0000000 --- a/Demo/pdist/sumtree.py +++ /dev/null @@ -1,27 +0,0 @@ -import time -import sys -import FSProxy - -def main(): - t1 = time.time() - #proxy = FSProxy.FSProxyClient(('voorn.cwi.nl', 4127)) - proxy = FSProxy.FSProxyLocal() - sumtree(proxy) - proxy._close() - t2 = time.time() - print(t2-t1, "seconds") - sys.stdout.write("[Return to exit] ") - sys.stdout.flush() - sys.stdin.readline() - -def sumtree(proxy): - print("PWD =", proxy.pwd()) - files = proxy.listfiles() - proxy.infolist(files) - subdirs = proxy.listsubdirs() - for name in subdirs: - proxy.cd(name) - sumtree(proxy) - proxy.back() - -main() diff --git a/Demo/pysvr/Makefile b/Demo/pysvr/Makefile deleted file mode 100644 index b4b9f3e..0000000 --- a/Demo/pysvr/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# Makefile for 'pysvr' application embedding Python. -# Tailored for Python 1.5a3 or later. -# Some details are specific for Solaris or CNRI. -# Also see ## comments for tailoring. - -# Which C compiler -CC=gcc -##PURIFY=/usr/local/pure/purify -LINKCC=$(PURIFY) $(CC) - -# Optimization preferences -OPT=-g - -# Which Python version we're using -VER=2.2 - -# Expressions using the above definitions -PYVER=python$(VER) - -# Use these defs when compiling against installed Python -##INST=/usr/local -##PYC=$(INST)/lib/$(PYVER)/config -##PYINCL=-I$(INST)/include/$(PYVER) -I$(PYC) -##PYLIBS=$(PYC)/lib$(PYVER).a - -# Use these defs when compiling against built Python -PLAT=linux -PYINCL=-I../../Include -I../../$(PLAT) -PYLIBS=../../$(PLAT)/lib$(PYVER).a - -# Libraries to link with -- very installation dependent -# (See LIBS= in Modules/Makefile in build tree) -RLLIBS=-lreadline -ltermcap -OTHERLIBS=-lnsl -lpthread -ldl -lm -ldb -lutil - -# Compilation and link flags -- no need to change normally -CFLAGS=$(OPT) -CPPFLAGS=$(PYINCL) -LIBS=$(PYLIBS) $(RLLIBS) $(OTHERLIBS) - -# Default port for the pysvr application -PORT=4000 - -# Default target -all: pysvr - -# Target to build pysvr -pysvr: pysvr.o $(PYOBJS) $(PYLIBS) - $(LINKCC) pysvr.o $(LIBS) -o pysvr - -# Target to build and run pysvr -run: pysvr - pysvr $(PORT) - -# Target to clean up the directory -clean: - -rm -f pysvr *.o *~ core diff --git a/Demo/pysvr/README b/Demo/pysvr/README deleted file mode 100644 index 5e64e38..0000000 --- a/Demo/pysvr/README +++ /dev/null @@ -1,9 +0,0 @@ -This is an example of a multi-threaded C application embedding a -Python interpreter. - -The particular application is a multi-threaded telnet-like server that -provides you with a Python prompt (instead of a shell prompt). - -The file pysvr.py is a prototype in Python. - -THIS APPLICATION IS NOT SECURE -- ONLY USE IT FOR TESTING! diff --git a/Demo/pysvr/pysvr.c b/Demo/pysvr/pysvr.c deleted file mode 100644 index 706cd2a..0000000 --- a/Demo/pysvr/pysvr.c +++ /dev/null @@ -1,370 +0,0 @@ -/* A multi-threaded telnet-like server that gives a Python prompt. - -Usage: pysvr [port] - -For security reasons, it only accepts requests from the current host. -This can still be insecure, but restricts violations from people who -can log in on your machine. Use with caution! - -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> - -#include <pthread.h> -#include <getopt.h> - -/* XXX Umpfh. - Python.h defines a typedef destructor, which conflicts with pthread.h. - So Python.h must be included after pthread.h. */ - -#include "Python.h" - -extern int Py_VerboseFlag; - -#ifndef PORT -#define PORT 4000 -#endif - -struct workorder { - int conn; - struct sockaddr_in addr; -}; - -/* Forward */ -static void init_python(void); -static void usage(void); -static void oprogname(void); -static void main_thread(int); -static void create_thread(int, struct sockaddr_in *); -static void *service_thread(struct workorder *); -static void run_interpreter(FILE *, FILE *); -static int run_command(char *, PyObject *); -static void ps(void); - -static char *progname = "pysvr"; - -static PyThreadState *gtstate; - -main(int argc, char **argv) -{ - int port = PORT; - int c; - - if (argc > 0 && argv[0] != NULL && argv[0][0] != '\0') - progname = argv[0]; - - while ((c = getopt(argc, argv, "v")) != EOF) { - switch (c) { - case 'v': - Py_VerboseFlag++; - break; - default: - usage(); - } - } - - if (optind < argc) { - if (optind+1 < argc) { - oprogname(); - fprintf(stderr, "too many arguments\n"); - usage(); - } - port = atoi(argv[optind]); - if (port <= 0) { - fprintf(stderr, "bad port (%s)\n", argv[optind]); - usage(); - } - } - - main_thread(port); - - fprintf(stderr, "Bye.\n"); - - exit(0); -} - -static char usage_line[] = "usage: %s [port]\n"; - -static void -usage(void) -{ - fprintf(stderr, usage_line, progname); - exit(2); -} - -static void -main_thread(int port) -{ - int sock, conn, size, i; - struct sockaddr_in addr, clientaddr; - - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock < 0) { - oprogname(); - perror("can't create socket"); - exit(1); - } - -#ifdef SO_REUSEADDR - i = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof i); -#endif - - memset((char *)&addr, '\0', sizeof addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = 0L; - if (bind(sock, (struct sockaddr *)&addr, sizeof addr) < 0) { - oprogname(); - perror("can't bind socket to address"); - exit(1); - } - - if (listen(sock, 5) < 0) { - oprogname(); - perror("can't listen on socket"); - exit(1); - } - - fprintf(stderr, "Listening on port %d...\n", port); - - for (i = 0; ; i++) { - size = sizeof clientaddr; - memset((char *) &clientaddr, '\0', size); - conn = accept(sock, (struct sockaddr *) &clientaddr, &size); - if (conn < 0) { - oprogname(); - perror("can't accept connection from socket"); - exit(1); - } - - size = sizeof addr; - memset((char *) &addr, '\0', size); - if (getsockname(conn, (struct sockaddr *)&addr, &size) < 0) { - oprogname(); - perror("can't get socket name of connection"); - exit(1); - } - if (clientaddr.sin_addr.s_addr != addr.sin_addr.s_addr) { - oprogname(); - perror("connection from non-local host refused"); - fprintf(stderr, "(addr=%lx, clientaddr=%lx)\n", - ntohl(addr.sin_addr.s_addr), - ntohl(clientaddr.sin_addr.s_addr)); - close(conn); - continue; - } - if (i == 4) { - close(conn); - break; - } - create_thread(conn, &clientaddr); - } - - close(sock); - - if (gtstate) { - PyEval_AcquireThread(gtstate); - gtstate = NULL; - Py_Finalize(); - /* And a second time, just because we can. */ - Py_Finalize(); /* This should be harmless. */ - } - exit(0); -} - -static void -create_thread(int conn, struct sockaddr_in *addr) -{ - struct workorder *work; - pthread_t tdata; - - work = malloc(sizeof(struct workorder)); - if (work == NULL) { - oprogname(); - fprintf(stderr, "out of memory for thread.\n"); - close(conn); - return; - } - work->conn = conn; - work->addr = *addr; - - init_python(); - - if (pthread_create(&tdata, NULL, (void *)service_thread, work) < 0) { - oprogname(); - perror("can't create new thread"); - close(conn); - return; - } - - if (pthread_detach(tdata) < 0) { - oprogname(); - perror("can't detach from thread"); - } -} - -static PyThreadState *the_tstate; -static PyInterpreterState *the_interp; -static PyObject *the_builtins; - -static void -init_python(void) -{ - if (gtstate) - return; - Py_Initialize(); /* Initialize the interpreter */ - PyEval_InitThreads(); /* Create (and acquire) the interpreter lock */ - gtstate = PyEval_SaveThread(); /* Release the thread state */ -} - -static void * -service_thread(struct workorder *work) -{ - FILE *input, *output; - - fprintf(stderr, "Start thread for connection %d.\n", work->conn); - - ps(); - - input = fdopen(work->conn, "r"); - if (input == NULL) { - oprogname(); - perror("can't create input stream"); - goto done; - } - - output = fdopen(work->conn, "w"); - if (output == NULL) { - oprogname(); - perror("can't create output stream"); - fclose(input); - goto done; - } - - setvbuf(input, NULL, _IONBF, 0); - setvbuf(output, NULL, _IONBF, 0); - - run_interpreter(input, output); - - fclose(input); - fclose(output); - - done: - fprintf(stderr, "End thread for connection %d.\n", work->conn); - close(work->conn); - free(work); -} - -static void -oprogname(void) -{ - int save = errno; - fprintf(stderr, "%s: ", progname); - errno = save; -} - -static void -run_interpreter(FILE *input, FILE *output) -{ - PyThreadState *tstate; - PyObject *new_stdin, *new_stdout; - PyObject *mainmod, *globals; - char buffer[1000]; - char *p, *q; - int n, end; - - PyEval_AcquireLock(); - tstate = Py_NewInterpreter(); - if (tstate == NULL) { - fprintf(output, "Sorry -- can't create an interpreter\n"); - return; - } - - mainmod = PyImport_AddModule("__main__"); - globals = PyModule_GetDict(mainmod); - Py_INCREF(globals); - - new_stdin = PyFile_FromFile(input, "<socket-in>", "r", NULL); - new_stdout = PyFile_FromFile(output, "<socket-out>", "w", NULL); - - PySys_SetObject("stdin", new_stdin); - PySys_SetObject("stdout", new_stdout); - PySys_SetObject("stderr", new_stdout); - - for (n = 1; !PyErr_Occurred(); n++) { - Py_BEGIN_ALLOW_THREADS - fprintf(output, "%d> ", n); - p = fgets(buffer, sizeof buffer, input); - Py_END_ALLOW_THREADS - - if (p == NULL) - break; - if (p[0] == '\377' && p[1] == '\354') - break; - - q = strrchr(p, '\r'); - if (q && q[1] == '\n' && q[2] == '\0') { - *q++ = '\n'; - *q++ = '\0'; - } - - while (*p && isspace(*p)) - p++; - if (p[0] == '#' || p[0] == '\0') - continue; - - end = run_command(buffer, globals); - if (end < 0) - PyErr_Print(); - - if (end) - break; - } - - Py_XDECREF(globals); - Py_XDECREF(new_stdin); - Py_XDECREF(new_stdout); - - Py_EndInterpreter(tstate); - PyEval_ReleaseLock(); - - fprintf(output, "Goodbye!\n"); -} - -static int -run_command(char *buffer, PyObject *globals) -{ - PyObject *m, *d, *v; - fprintf(stderr, "run_command: %s", buffer); - if (strchr(buffer, '\n') == NULL) - fprintf(stderr, "\n"); - v = PyRun_String(buffer, Py_single_input, globals, globals); - if (v == NULL) { - if (PyErr_Occurred() == PyExc_SystemExit) { - PyErr_Clear(); - return 1; - } - PyErr_Print(); - return 0; - } - Py_DECREF(v); - return 0; -} - -static void -ps(void) -{ - char buffer[100]; - PyOS_snprintf(buffer, sizeof(buffer), - "ps -l -p %d </dev/null | sed 1d\n", getpid()); - system(buffer); -} diff --git a/Demo/pysvr/pysvr.py b/Demo/pysvr/pysvr.py deleted file mode 100755 index 3e94dbe..0000000 --- a/Demo/pysvr/pysvr.py +++ /dev/null @@ -1,124 +0,0 @@ -#! /usr/bin/env python - -"""A multi-threaded telnet-like server that gives a Python prompt. - -This is really a prototype for the same thing in C. - -Usage: pysvr.py [port] - -For security reasons, it only accepts requests from the current host. -This can still be insecure, but restricts violations from people who -can log in on your machine. Use with caution! - -""" - -import sys, os, string, getopt, _thread, socket, traceback - -PORT = 4000 # Default port - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], "") - if len(args) > 1: - raise getopt.error("Too many arguments.") - except getopt.error as msg: - usage(msg) - for o, a in opts: - pass - if args: - try: - port = string.atoi(args[0]) - except ValueError as msg: - usage(msg) - else: - port = PORT - main_thread(port) - -def usage(msg=None): - sys.stdout = sys.stderr - if msg: - print(msg) - print("\n", __doc__, end=' ') - sys.exit(2) - -def main_thread(port): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.bind(("", port)) - sock.listen(5) - print("Listening on port", port, "...") - while 1: - (conn, addr) = sock.accept() - if addr[0] != conn.getsockname()[0]: - conn.close() - print("Refusing connection from non-local host", addr[0], ".") - continue - _thread.start_new_thread(service_thread, (conn, addr)) - del conn, addr - -def service_thread(conn, addr): - (caddr, cport) = addr - print("Thread %s has connection from %s.\n" % (str(_thread.get_ident()), - caddr), end=' ') - stdin = conn.makefile("r") - stdout = conn.makefile("w", 0) - run_interpreter(stdin, stdout) - print("Thread %s is done.\n" % str(_thread.get_ident()), end=' ') - -def run_interpreter(stdin, stdout): - globals = {} - try: - str(sys.ps1) - except: - sys.ps1 = ">>> " - source = "" - while 1: - stdout.write(sys.ps1) - line = stdin.readline() - if line[:2] == '\377\354': - line = "" - if not line and not source: - break - if line[-2:] == '\r\n': - line = line[:-2] + '\n' - source = source + line - try: - code = compile_command(source) - except SyntaxError as err: - source = "" - traceback.print_exception(SyntaxError, err, None, file=stdout) - continue - if not code: - continue - source = "" - try: - run_command(code, stdin, stdout, globals) - except SystemExit as how: - if how: - try: - how = str(how) - except: - how = "" - stdout.write("Exit %s\n" % how) - break - stdout.write("\nGoodbye.\n") - -def run_command(code, stdin, stdout, globals): - save = sys.stdin, sys.stdout, sys.stderr - try: - sys.stdout = sys.stderr = stdout - sys.stdin = stdin - try: - exec(code, globals) - except SystemExit as how: - raise SystemExit(how).with_traceback(sys.exc_info()[2]) - except: - type, value, tb = sys.exc_info() - if tb: tb = tb.tb_next - traceback.print_exception(type, value, tb) - del tb - finally: - sys.stdin, sys.stdout, sys.stderr = save - -from code import compile_command - -main() diff --git a/Demo/rpc/MANIFEST b/Demo/rpc/MANIFEST deleted file mode 100644 index e65f3eb..0000000 --- a/Demo/rpc/MANIFEST +++ /dev/null @@ -1,10 +0,0 @@ - File Name Archive # Description ------------------------------------------------------------ - MANIFEST 1 This shipping list - README 1 - T.py 1 - mountclient.py 1 - nfsclient.py 1 - rpc.py 1 - test 1 - xdr.py 1 diff --git a/Demo/rpc/README b/Demo/rpc/README deleted file mode 100644 index 97948a3..0000000 --- a/Demo/rpc/README +++ /dev/null @@ -1,31 +0,0 @@ -This is a Python interface to Sun RPC, designed and implemented mostly -by reading the Internet RFCs about the subject. - -*** NOTE: xdr.py has evolved into the standard module xdrlib.py *** - -There are two library modules, xdr.py and rpc.py, and several example -clients: mountclient.py, nfsclient.py, and rnusersclient.py, -implementing the NFS Mount protocol, (part of) the NFS protocol, and -the "rnusers" protocol (used by rusers(1)), respectively. The latter -demonstrates the use of broadcast via the Port mapper's CALLIT -procedure. - -There is also a way to create servers in Python. - -To test the nfs client, run it from the shell with something like this: - - python -c 'import nfsclient; nfsclient.test()' [hostname [filesystemname]] - -When called without a filesystemname, it lists the filesystems at the -host; default host is the local machine. - -Other clients are tested similarly. - -For hostname, use e.g. wuarchive.wustl.edu or gatekeeper.dec.com (two -hosts that are known to export NFS filesystems with little restrictions). - -There are now two different RPC compilers: - -1) Wim Lewis rpcgen.py found on http://www.omnigroup.com/~wiml/soft/stale-index.html#python. - -2) Peter Åstrands rpcgen.py, which is part of "pynfs" (http://www.cendio.se/~peter/pynfs/). diff --git a/Demo/rpc/T.py b/Demo/rpc/T.py deleted file mode 100644 index 3325507..0000000 --- a/Demo/rpc/T.py +++ /dev/null @@ -1,22 +0,0 @@ -# Simple interface to report execution times of program fragments. -# Call TSTART() to reset the timer, TSTOP(...) to report times. - -import sys, os, time - -def TSTART(): - global t0, t1 - u, s, cu, cs = os.times() - t0 = u+cu, s+cs, time.time() - -def TSTOP(*label): - global t0, t1 - u, s, cu, cs = os.times() - t1 = u+cu, s+cs, time.time() - tt = [] - for i in range(3): - tt.append(t1[i] - t0[i]) - [u, s, r] = tt - msg = '' - for x in label: msg = msg + (x + ' ') - msg = msg + '%r user, %r sys, %r real\n' % (u, s, r) - sys.stderr.write(msg) diff --git a/Demo/rpc/mountclient.py b/Demo/rpc/mountclient.py deleted file mode 100644 index 81797df..0000000 --- a/Demo/rpc/mountclient.py +++ /dev/null @@ -1,202 +0,0 @@ -# Mount RPC client -- RFC 1094 (NFS), Appendix A - -# This module demonstrates how to write your own RPC client in Python. -# When this example was written, there was no RPC compiler for -# Python. Without such a compiler, you must first create classes -# derived from Packer and Unpacker to handle the data types for the -# server you want to interface to. You then write the client class. -# If you want to support both the TCP and the UDP version of a -# protocol, use multiple inheritance as shown below. - - -import rpc -from rpc import Packer, Unpacker, TCPClient, UDPClient - - -# Program number and version for the mount protocol -MOUNTPROG = 100005 -MOUNTVERS = 1 - -# Size of the 'fhandle' opaque structure -FHSIZE = 32 - - -# Packer derived class for Mount protocol clients. -# The only thing we need to pack beyond basic types is an 'fhandle' - -class MountPacker(Packer): - - def pack_fhandle(self, fhandle): - self.pack_fopaque(FHSIZE, fhandle) - - -# Unpacker derived class for Mount protocol clients. -# The important types we need to unpack are fhandle, fhstatus, -# mountlist and exportlist; mountstruct, exportstruct and groups are -# used to unpack components of mountlist and exportlist and the -# corresponding functions are passed as function argument to the -# generic unpack_list function. - -class MountUnpacker(Unpacker): - - def unpack_fhandle(self): - return self.unpack_fopaque(FHSIZE) - - def unpack_fhstatus(self): - status = self.unpack_uint() - if status == 0: - fh = self.unpack_fhandle() - else: - fh = None - return status, fh - - def unpack_mountlist(self): - return self.unpack_list(self.unpack_mountstruct) - - def unpack_mountstruct(self): - hostname = self.unpack_string() - directory = self.unpack_string() - return (hostname, directory) - - def unpack_exportlist(self): - return self.unpack_list(self.unpack_exportstruct) - - def unpack_exportstruct(self): - filesys = self.unpack_string() - groups = self.unpack_groups() - return (filesys, groups) - - def unpack_groups(self): - return self.unpack_list(self.unpack_string) - - -# These are the procedures specific to the Mount client class. -# Think of this as a derived class of either TCPClient or UDPClient. - -class PartialMountClient: - - # This method is called by Client.__init__ to initialize - # self.packer and self.unpacker - def addpackers(self): - self.packer = MountPacker() - self.unpacker = MountUnpacker('') - - # This method is called by Client.__init__ to bind the socket - # to a particular network interface and port. We use the - # default network interface, but if we're running as root, - # we want to bind to a reserved port - def bindsocket(self): - import os - try: - uid = os.getuid() - except AttributeError: - uid = 1 - if uid == 0: - port = rpc.bindresvport(self.sock, '') - # 'port' is not used - else: - self.sock.bind(('', 0)) - - # This function is called to cough up a suitable - # authentication object for a call to procedure 'proc'. - def mkcred(self): - if self.cred is None: - self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default() - return self.cred - - # The methods Mnt, Dump etc. each implement one Remote - # Procedure Call. This is done by calling self.make_call() - # with as arguments: - # - # - the procedure number - # - the arguments (or None) - # - the "packer" function for the arguments (or None) - # - the "unpacker" function for the return value (or None) - # - # The packer and unpacker function, if not None, *must* be - # methods of self.packer and self.unpacker, respectively. - # A value of None means that there are no arguments or is no - # return value, respectively. - # - # The return value from make_call() is the return value from - # the remote procedure call, as unpacked by the "unpacker" - # function, or None if the unpacker function is None. - # - # (Even if you expect a result of None, you should still - # return the return value from make_call(), since this may be - # needed by a broadcasting version of the class.) - # - # If the call fails, make_call() raises an exception - # (this includes time-outs and invalid results). - # - # Note that (at least with the UDP protocol) there is no - # guarantee that a call is executed at most once. When you do - # get a reply, you know it has been executed at least once; - # when you don't get a reply, you know nothing. - - def Mnt(self, directory): - return self.make_call(1, directory, \ - self.packer.pack_string, \ - self.unpacker.unpack_fhstatus) - - def Dump(self): - return self.make_call(2, None, \ - None, self.unpacker.unpack_mountlist) - - def Umnt(self, directory): - return self.make_call(3, directory, \ - self.packer.pack_string, None) - - def Umntall(self): - return self.make_call(4, None, None, None) - - def Export(self): - return self.make_call(5, None, \ - None, self.unpacker.unpack_exportlist) - - -# We turn the partial Mount client into a full one for either protocol -# by use of multiple inheritance. (In general, when class C has base -# classes B1...Bn, if x is an instance of class C, methods of x are -# searched first in C, then in B1, then in B2, ..., finally in Bn.) - -class TCPMountClient(PartialMountClient, TCPClient): - - def __init__(self, host): - TCPClient.__init__(self, host, MOUNTPROG, MOUNTVERS) - - -class UDPMountClient(PartialMountClient, UDPClient): - - def __init__(self, host): - UDPClient.__init__(self, host, MOUNTPROG, MOUNTVERS) - - -# A little test program for the Mount client. This takes a host as -# command line argument (default the local machine), prints its export -# list, and attempts to mount and unmount each exported files system. -# An optional first argument of -t or -u specifies the protocol to use -# (TCP or UDP), default is UDP. - -def test(): - import sys - if sys.argv[1:] and sys.argv[1] == '-t': - C = TCPMountClient - del sys.argv[1] - elif sys.argv[1:] and sys.argv[1] == '-u': - C = UDPMountClient - del sys.argv[1] - else: - C = UDPMountClient - if sys.argv[1:]: host = sys.argv[1] - else: host = '' - mcl = C(host) - list = mcl.Export() - for item in list: - print(item) - try: - mcl.Mnt(item[0]) - except: - print('Sorry') - continue - mcl.Umnt(item[0]) diff --git a/Demo/rpc/nfsclient.py b/Demo/rpc/nfsclient.py deleted file mode 100644 index a291ce0..0000000 --- a/Demo/rpc/nfsclient.py +++ /dev/null @@ -1,201 +0,0 @@ -# NFS RPC client -- RFC 1094 - -# XXX This is not yet complete. -# XXX Only GETATTR, SETTTR, LOOKUP and READDIR are supported. - -# (See mountclient.py for some hints on how to write RPC clients in -# Python in general) - -import rpc -from rpc import UDPClient, TCPClient -from mountclient import FHSIZE, MountPacker, MountUnpacker - -NFS_PROGRAM = 100003 -NFS_VERSION = 2 - -# enum stat -NFS_OK = 0 -# (...many error values...) - -# enum ftype -NFNON = 0 -NFREG = 1 -NFDIR = 2 -NFBLK = 3 -NFCHR = 4 -NFLNK = 5 - - -class NFSPacker(MountPacker): - - def pack_sattrargs(self, sa): - file, attributes = sa - self.pack_fhandle(file) - self.pack_sattr(attributes) - - def pack_sattr(self, sa): - mode, uid, gid, size, atime, mtime = sa - self.pack_uint(mode) - self.pack_uint(uid) - self.pack_uint(gid) - self.pack_uint(size) - self.pack_timeval(atime) - self.pack_timeval(mtime) - - def pack_diropargs(self, da): - dir, name = da - self.pack_fhandle(dir) - self.pack_string(name) - - def pack_readdirargs(self, ra): - dir, cookie, count = ra - self.pack_fhandle(dir) - self.pack_uint(cookie) - self.pack_uint(count) - - def pack_timeval(self, tv): - secs, usecs = tv - self.pack_uint(secs) - self.pack_uint(usecs) - - -class NFSUnpacker(MountUnpacker): - - def unpack_readdirres(self): - status = self.unpack_enum() - if status == NFS_OK: - entries = self.unpack_list(self.unpack_entry) - eof = self.unpack_bool() - rest = (entries, eof) - else: - rest = None - return (status, rest) - - def unpack_entry(self): - fileid = self.unpack_uint() - name = self.unpack_string() - cookie = self.unpack_uint() - return (fileid, name, cookie) - - def unpack_diropres(self): - status = self.unpack_enum() - if status == NFS_OK: - fh = self.unpack_fhandle() - fa = self.unpack_fattr() - rest = (fh, fa) - else: - rest = None - return (status, rest) - - def unpack_attrstat(self): - status = self.unpack_enum() - if status == NFS_OK: - attributes = self.unpack_fattr() - else: - attributes = None - return status, attributes - - def unpack_fattr(self): - type = self.unpack_enum() - mode = self.unpack_uint() - nlink = self.unpack_uint() - uid = self.unpack_uint() - gid = self.unpack_uint() - size = self.unpack_uint() - blocksize = self.unpack_uint() - rdev = self.unpack_uint() - blocks = self.unpack_uint() - fsid = self.unpack_uint() - fileid = self.unpack_uint() - atime = self.unpack_timeval() - mtime = self.unpack_timeval() - ctime = self.unpack_timeval() - return (type, mode, nlink, uid, gid, size, blocksize, \ - rdev, blocks, fsid, fileid, atime, mtime, ctime) - - def unpack_timeval(self): - secs = self.unpack_uint() - usecs = self.unpack_uint() - return (secs, usecs) - - -class NFSClient(UDPClient): - - def __init__(self, host): - UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION) - - def addpackers(self): - self.packer = NFSPacker() - self.unpacker = NFSUnpacker('') - - def mkcred(self): - if self.cred is None: - self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default() - return self.cred - - def Getattr(self, fh): - return self.make_call(1, fh, \ - self.packer.pack_fhandle, \ - self.unpacker.unpack_attrstat) - - def Setattr(self, sa): - return self.make_call(2, sa, \ - self.packer.pack_sattrargs, \ - self.unpacker.unpack_attrstat) - - # Root() is obsolete - - def Lookup(self, da): - return self.make_call(4, da, \ - self.packer.pack_diropargs, \ - self.unpacker.unpack_diropres) - - # ... - - def Readdir(self, ra): - return self.make_call(16, ra, \ - self.packer.pack_readdirargs, \ - self.unpacker.unpack_readdirres) - - # Shorthand to get the entire contents of a directory - def Listdir(self, dir): - list = [] - ra = (dir, 0, 2000) - while 1: - (status, rest) = self.Readdir(ra) - if status != NFS_OK: - break - entries, eof = rest - last_cookie = None - for fileid, name, cookie in entries: - list.append((fileid, name)) - last_cookie = cookie - if eof or last_cookie is None: - break - ra = (ra[0], last_cookie, ra[2]) - return list - - -def test(): - import sys - if sys.argv[1:]: host = sys.argv[1] - else: host = '' - if sys.argv[2:]: filesys = sys.argv[2] - else: filesys = None - from mountclient import UDPMountClient, TCPMountClient - mcl = TCPMountClient(host) - if filesys is None: - list = mcl.Export() - for item in list: - print(item) - return - sf = mcl.Mnt(filesys) - print(sf) - fh = sf[1] - if fh: - ncl = NFSClient(host) - attrstat = ncl.Getattr(fh) - print(attrstat) - list = ncl.Listdir(fh) - for item in list: print(item) - mcl.Umnt(filesys) diff --git a/Demo/rpc/rnusersclient.py b/Demo/rpc/rnusersclient.py deleted file mode 100644 index eaabefe..0000000 --- a/Demo/rpc/rnusersclient.py +++ /dev/null @@ -1,98 +0,0 @@ -# Remote nusers client interface - -import rpc -from rpc import Packer, Unpacker, UDPClient, BroadcastUDPClient - - -class RnusersPacker(Packer): - def pack_utmp(self, ui): - ut_line, ut_name, ut_host, ut_time = utmp - self.pack_string(ut_line) - self.pack_string(ut_name) - self.pack_string(ut_host) - self.pack_int(ut_time) - def pack_utmpidle(self, ui): - ui_itmp, ui_idle = ui - self.pack_utmp(ui_utmp) - self.pack_uint(ui_idle) - def pack_utmpidlearr(self, list): - self.pack_array(list, self.pack_itmpidle) - - -class RnusersUnpacker(Unpacker): - def unpack_utmp(self): - ut_line = self.unpack_string() - ut_name = self.unpack_string() - ut_host = self.unpack_string() - ut_time = self.unpack_int() - return ut_line, ut_name, ut_host, ut_time - def unpack_utmpidle(self): - ui_utmp = self.unpack_utmp() - ui_idle = self.unpack_uint() - return ui_utmp, ui_idle - def unpack_utmpidlearr(self): - return self.unpack_array(self.unpack_utmpidle) - - -class PartialRnusersClient: - - def addpackers(self): - self.packer = RnusersPacker() - self.unpacker = RnusersUnpacker('') - - def Num(self): - return self.make_call(1, None, None, self.unpacker.unpack_int) - - def Names(self): - return self.make_call(2, None, \ - None, self.unpacker.unpack_utmpidlearr) - - def Allnames(self): - return self.make_call(3, None, \ - None, self.unpacker.unpack_utmpidlearr) - - -class RnusersClient(PartialRnusersClient, UDPClient): - - def __init__(self, host): - UDPClient.__init__(self, host, 100002, 2) - - -class BroadcastRnusersClient(PartialRnusersClient, BroadcastUDPClient): - - def __init__(self, bcastaddr): - BroadcastUDPClient.__init__(self, bcastaddr, 100002, 2) - - -def test(): - import sys - if not sys.argv[1:]: - testbcast() - return - else: - host = sys.argv[1] - c = RnusersClient(host) - list = c.Names() - for (line, name, host, time), idle in list: - line = strip0(line) - name = strip0(name) - host = strip0(host) - print("%r %r %r %s %s" % (name, host, line, time, idle)) - -def testbcast(): - c = BroadcastRnusersClient('<broadcast>') - def listit(list, fromaddr): - host, port = fromaddr - print(host + '\t:', end=' ') - for (line, name, host, time), idle in list: - print(strip0(name), end=' ') - print() - c.set_reply_handler(listit) - all = c.Names() - print('Total Count:', len(all)) - -def strip0(s): - while s and s[-1] == '\0': s = s[:-1] - return s - -test() diff --git a/Demo/rpc/rpc.py b/Demo/rpc/rpc.py deleted file mode 100644 index 30b3017..0000000 --- a/Demo/rpc/rpc.py +++ /dev/null @@ -1,890 +0,0 @@ -# Sun RPC version 2 -- RFC1057. - -# XXX There should be separate exceptions for the various reasons why -# XXX an RPC can fail, rather than using RuntimeError for everything - -# XXX Need to use class based exceptions rather than string exceptions - -# XXX The UDP version of the protocol resends requests when it does -# XXX not receive a timely reply -- use only for idempotent calls! - -# XXX There is no provision for call timeout on TCP connections - -import xdr -import socket -import os - -RPCVERSION = 2 - -CALL = 0 -REPLY = 1 - -AUTH_NULL = 0 -AUTH_UNIX = 1 -AUTH_SHORT = 2 -AUTH_DES = 3 - -MSG_ACCEPTED = 0 -MSG_DENIED = 1 - -SUCCESS = 0 # RPC executed successfully -PROG_UNAVAIL = 1 # remote hasn't exported program -PROG_MISMATCH = 2 # remote can't support version # -PROC_UNAVAIL = 3 # program can't support procedure -GARBAGE_ARGS = 4 # procedure can't decode params - -RPC_MISMATCH = 0 # RPC version number != 2 -AUTH_ERROR = 1 # remote can't authenticate caller - -AUTH_BADCRED = 1 # bad credentials (seal broken) -AUTH_REJECTEDCRED = 2 # client must begin new session -AUTH_BADVERF = 3 # bad verifier (seal broken) -AUTH_REJECTEDVERF = 4 # verifier expired or replayed -AUTH_TOOWEAK = 5 # rejected for security reasons - - -class Packer(xdr.Packer): - - def pack_auth(self, auth): - flavor, stuff = auth - self.pack_enum(flavor) - self.pack_opaque(stuff) - - def pack_auth_unix(self, stamp, machinename, uid, gid, gids): - self.pack_uint(stamp) - self.pack_string(machinename) - self.pack_uint(uid) - self.pack_uint(gid) - self.pack_uint(len(gids)) - for i in gids: - self.pack_uint(i) - - def pack_callheader(self, xid, prog, vers, proc, cred, verf): - self.pack_uint(xid) - self.pack_enum(CALL) - self.pack_uint(RPCVERSION) - self.pack_uint(prog) - self.pack_uint(vers) - self.pack_uint(proc) - self.pack_auth(cred) - self.pack_auth(verf) - # Caller must add procedure-specific part of call - - def pack_replyheader(self, xid, verf): - self.pack_uint(xid) - self.pack_enum(REPLY) - self.pack_uint(MSG_ACCEPTED) - self.pack_auth(verf) - self.pack_enum(SUCCESS) - # Caller must add procedure-specific part of reply - - -# Exceptions -class BadRPCFormat(Exception): pass -class BadRPCVersion(Exception): pass -class GarbageArgs(Exception): pass - -class Unpacker(xdr.Unpacker): - - def unpack_auth(self): - flavor = self.unpack_enum() - stuff = self.unpack_opaque() - return (flavor, stuff) - - def unpack_callheader(self): - xid = self.unpack_uint() - temp = self.unpack_enum() - if temp != CALL: - raise BadRPCFormat('no CALL but %r' % (temp,)) - temp = self.unpack_uint() - if temp != RPCVERSION: - raise BadRPCVersion('bad RPC version %r' % (temp,)) - prog = self.unpack_uint() - vers = self.unpack_uint() - proc = self.unpack_uint() - cred = self.unpack_auth() - verf = self.unpack_auth() - return xid, prog, vers, proc, cred, verf - # Caller must add procedure-specific part of call - - def unpack_replyheader(self): - xid = self.unpack_uint() - mtype = self.unpack_enum() - if mtype != REPLY: - raise RuntimeError('no REPLY but %r' % (mtype,)) - stat = self.unpack_enum() - if stat == MSG_DENIED: - stat = self.unpack_enum() - if stat == RPC_MISMATCH: - low = self.unpack_uint() - high = self.unpack_uint() - raise RuntimeError('MSG_DENIED: RPC_MISMATCH: %r' % ((low, high),)) - if stat == AUTH_ERROR: - stat = self.unpack_uint() - raise RuntimeError('MSG_DENIED: AUTH_ERROR: %r' % (stat,)) - raise RuntimeError('MSG_DENIED: %r' % (stat,)) - if stat != MSG_ACCEPTED: - raise RuntimeError('Neither MSG_DENIED nor MSG_ACCEPTED: %r' % (stat,)) - verf = self.unpack_auth() - stat = self.unpack_enum() - if stat == PROG_UNAVAIL: - raise RuntimeError('call failed: PROG_UNAVAIL') - if stat == PROG_MISMATCH: - low = self.unpack_uint() - high = self.unpack_uint() - raise RuntimeError('call failed: PROG_MISMATCH: %r' % ((low, high),)) - if stat == PROC_UNAVAIL: - raise RuntimeError('call failed: PROC_UNAVAIL') - if stat == GARBAGE_ARGS: - raise RuntimeError('call failed: GARBAGE_ARGS') - if stat != SUCCESS: - raise RuntimeError('call failed: %r' % (stat,)) - return xid, verf - # Caller must get procedure-specific part of reply - - -# Subroutines to create opaque authentication objects - -def make_auth_null(): - return '' - -def make_auth_unix(seed, host, uid, gid, groups): - p = Packer() - p.pack_auth_unix(seed, host, uid, gid, groups) - return p.get_buf() - -def make_auth_unix_default(): - try: - from os import getuid, getgid - uid = getuid() - gid = getgid() - except ImportError: - uid = gid = 0 - import time - return make_auth_unix(int(time.time()-unix_epoch()), \ - socket.gethostname(), uid, gid, []) - -_unix_epoch = -1 -def unix_epoch(): - """Very painful calculation of when the Unix Epoch is. - - This is defined as the return value of time.time() on Jan 1st, - 1970, 00:00:00 GMT. - - On a Unix system, this should always return 0.0. On a Mac, the - calculations are needed -- and hard because of integer overflow - and other limitations. - - """ - global _unix_epoch - if _unix_epoch >= 0: return _unix_epoch - import time - now = time.time() - localt = time.localtime(now) # (y, m, d, hh, mm, ss, ..., ..., ...) - gmt = time.gmtime(now) - offset = time.mktime(localt) - time.mktime(gmt) - y, m, d, hh, mm, ss = 1970, 1, 1, 0, 0, 0 - offset, ss = divmod(ss + offset, 60) - offset, mm = divmod(mm + offset, 60) - offset, hh = divmod(hh + offset, 24) - d = d + offset - _unix_epoch = time.mktime((y, m, d, hh, mm, ss, 0, 0, 0)) - print("Unix epoch:", time.ctime(_unix_epoch)) - return _unix_epoch - - -# Common base class for clients - -class Client: - - def __init__(self, host, prog, vers, port): - self.host = host - self.prog = prog - self.vers = vers - self.port = port - self.makesocket() # Assigns to self.sock - self.bindsocket() - self.connsocket() - self.lastxid = 0 # XXX should be more random? - self.addpackers() - self.cred = None - self.verf = None - - def close(self): - self.sock.close() - - def makesocket(self): - # This MUST be overridden - raise RuntimeError('makesocket not defined') - - def connsocket(self): - # Override this if you don't want/need a connection - self.sock.connect((self.host, self.port)) - - def bindsocket(self): - # Override this to bind to a different port (e.g. reserved) - self.sock.bind(('', 0)) - - def addpackers(self): - # Override this to use derived classes from Packer/Unpacker - self.packer = Packer() - self.unpacker = Unpacker('') - - def make_call(self, proc, args, pack_func, unpack_func): - # Don't normally override this (but see Broadcast) - if pack_func is None and args is not None: - raise TypeError('non-null args with null pack_func') - self.start_call(proc) - if pack_func: - pack_func(args) - self.do_call() - if unpack_func: - result = unpack_func() - else: - result = None - self.unpacker.done() - return result - - def start_call(self, proc): - # Don't override this - self.lastxid = xid = self.lastxid + 1 - cred = self.mkcred() - verf = self.mkverf() - p = self.packer - p.reset() - p.pack_callheader(xid, self.prog, self.vers, proc, cred, verf) - - def do_call(self): - # This MUST be overridden - raise RuntimeError('do_call not defined') - - def mkcred(self): - # Override this to use more powerful credentials - if self.cred is None: - self.cred = (AUTH_NULL, make_auth_null()) - return self.cred - - def mkverf(self): - # Override this to use a more powerful verifier - if self.verf is None: - self.verf = (AUTH_NULL, make_auth_null()) - return self.verf - - def call_0(self): # Procedure 0 is always like this - return self.make_call(0, None, None, None) - - -# Record-Marking standard support - -def sendfrag(sock, last, frag): - x = len(frag) - if last: x = x | 0x80000000 - header = (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \ - chr(int(x>>8 & 0xff)) + chr(int(x & 0xff))) - sock.send(header + frag) - -def sendrecord(sock, record): - sendfrag(sock, 1, record) - -def recvfrag(sock): - header = sock.recv(4) - if len(header) < 4: - raise EOFError - x = int(ord(header[0]))<<24 | ord(header[1])<<16 | \ - ord(header[2])<<8 | ord(header[3]) - last = ((x & 0x80000000) != 0) - n = int(x & 0x7fffffff) - frag = '' - while n > 0: - buf = sock.recv(n) - if not buf: raise EOFError - n = n - len(buf) - frag = frag + buf - return last, frag - -def recvrecord(sock): - record = '' - last = 0 - while not last: - last, frag = recvfrag(sock) - record = record + frag - return record - - -# Try to bind to a reserved port (must be root) - -last_resv_port_tried = None -def bindresvport(sock, host): - global last_resv_port_tried - FIRST, LAST = 600, 1024 # Range of ports to try - if last_resv_port_tried is None: - import os - last_resv_port_tried = FIRST + os.getpid() % (LAST-FIRST) - for i in range(last_resv_port_tried, LAST) + \ - range(FIRST, last_resv_port_tried): - last_resv_port_tried = i - try: - sock.bind((host, i)) - return last_resv_port_tried - except socket.error as e: - (errno, msg) = e - if errno != 114: - raise socket.error(errno, msg) - raise RuntimeError('can\'t assign reserved port') - - -# Client using TCP to a specific port - -class RawTCPClient(Client): - - def makesocket(self): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - - def do_call(self): - call = self.packer.get_buf() - sendrecord(self.sock, call) - reply = recvrecord(self.sock) - u = self.unpacker - u.reset(reply) - xid, verf = u.unpack_replyheader() - if xid != self.lastxid: - # Can't really happen since this is TCP... - raise RuntimeError('wrong xid in reply %r instead of %r' % ( - xid, self.lastxid)) - - -# Client using UDP to a specific port - -class RawUDPClient(Client): - - def makesocket(self): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - - def do_call(self): - call = self.packer.get_buf() - self.sock.send(call) - try: - from select import select - except ImportError: - print('WARNING: select not found, RPC may hang') - select = None - BUFSIZE = 8192 # Max UDP buffer size - timeout = 1 - count = 5 - while 1: - r, w, x = [self.sock], [], [] - if select: - r, w, x = select(r, w, x, timeout) - if self.sock not in r: - count = count - 1 - if count < 0: raise RuntimeError('timeout') - if timeout < 25: timeout = timeout *2 -## print 'RESEND', timeout, count - self.sock.send(call) - continue - reply = self.sock.recv(BUFSIZE) - u = self.unpacker - u.reset(reply) - xid, verf = u.unpack_replyheader() - if xid != self.lastxid: -## print 'BAD xid' - continue - break - - -# Client using UDP broadcast to a specific port - -class RawBroadcastUDPClient(RawUDPClient): - - def __init__(self, bcastaddr, prog, vers, port): - RawUDPClient.__init__(self, bcastaddr, prog, vers, port) - self.reply_handler = None - self.timeout = 30 - - def connsocket(self): - # Don't connect -- use sendto - self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - - def set_reply_handler(self, reply_handler): - self.reply_handler = reply_handler - - def set_timeout(self, timeout): - self.timeout = timeout # Use None for infinite timeout - - def make_call(self, proc, args, pack_func, unpack_func): - if pack_func is None and args is not None: - raise TypeError('non-null args with null pack_func') - self.start_call(proc) - if pack_func: - pack_func(args) - call = self.packer.get_buf() - self.sock.sendto(call, (self.host, self.port)) - try: - from select import select - except ImportError: - print('WARNING: select not found, broadcast will hang') - select = None - BUFSIZE = 8192 # Max UDP buffer size (for reply) - replies = [] - if unpack_func is None: - def dummy(): pass - unpack_func = dummy - while 1: - r, w, x = [self.sock], [], [] - if select: - if self.timeout is None: - r, w, x = select(r, w, x) - else: - r, w, x = select(r, w, x, self.timeout) - if self.sock not in r: - break - reply, fromaddr = self.sock.recvfrom(BUFSIZE) - u = self.unpacker - u.reset(reply) - xid, verf = u.unpack_replyheader() - if xid != self.lastxid: -## print 'BAD xid' - continue - reply = unpack_func() - self.unpacker.done() - replies.append((reply, fromaddr)) - if self.reply_handler: - self.reply_handler(reply, fromaddr) - return replies - - -# Port mapper interface - -# Program number, version and (fixed!) port number -PMAP_PROG = 100000 -PMAP_VERS = 2 -PMAP_PORT = 111 - -# Procedure numbers -PMAPPROC_NULL = 0 # (void) -> void -PMAPPROC_SET = 1 # (mapping) -> bool -PMAPPROC_UNSET = 2 # (mapping) -> bool -PMAPPROC_GETPORT = 3 # (mapping) -> unsigned int -PMAPPROC_DUMP = 4 # (void) -> pmaplist -PMAPPROC_CALLIT = 5 # (call_args) -> call_result - -# A mapping is (prog, vers, prot, port) and prot is one of: - -IPPROTO_TCP = 6 -IPPROTO_UDP = 17 - -# A pmaplist is a variable-length list of mappings, as follows: -# either (1, mapping, pmaplist) or (0). - -# A call_args is (prog, vers, proc, args) where args is opaque; -# a call_result is (port, res) where res is opaque. - - -class PortMapperPacker(Packer): - - def pack_mapping(self, mapping): - prog, vers, prot, port = mapping - self.pack_uint(prog) - self.pack_uint(vers) - self.pack_uint(prot) - self.pack_uint(port) - - def pack_pmaplist(self, list): - self.pack_list(list, self.pack_mapping) - - def pack_call_args(self, ca): - prog, vers, proc, args = ca - self.pack_uint(prog) - self.pack_uint(vers) - self.pack_uint(proc) - self.pack_opaque(args) - - -class PortMapperUnpacker(Unpacker): - - def unpack_mapping(self): - prog = self.unpack_uint() - vers = self.unpack_uint() - prot = self.unpack_uint() - port = self.unpack_uint() - return prog, vers, prot, port - - def unpack_pmaplist(self): - return self.unpack_list(self.unpack_mapping) - - def unpack_call_result(self): - port = self.unpack_uint() - res = self.unpack_opaque() - return port, res - - -class PartialPortMapperClient: - - def addpackers(self): - self.packer = PortMapperPacker() - self.unpacker = PortMapperUnpacker('') - - def Set(self, mapping): - return self.make_call(PMAPPROC_SET, mapping, \ - self.packer.pack_mapping, \ - self.unpacker.unpack_uint) - - def Unset(self, mapping): - return self.make_call(PMAPPROC_UNSET, mapping, \ - self.packer.pack_mapping, \ - self.unpacker.unpack_uint) - - def Getport(self, mapping): - return self.make_call(PMAPPROC_GETPORT, mapping, \ - self.packer.pack_mapping, \ - self.unpacker.unpack_uint) - - def Dump(self): - return self.make_call(PMAPPROC_DUMP, None, \ - None, \ - self.unpacker.unpack_pmaplist) - - def Callit(self, ca): - return self.make_call(PMAPPROC_CALLIT, ca, \ - self.packer.pack_call_args, \ - self.unpacker.unpack_call_result) - - -class TCPPortMapperClient(PartialPortMapperClient, RawTCPClient): - - def __init__(self, host): - RawTCPClient.__init__(self, \ - host, PMAP_PROG, PMAP_VERS, PMAP_PORT) - - -class UDPPortMapperClient(PartialPortMapperClient, RawUDPClient): - - def __init__(self, host): - RawUDPClient.__init__(self, \ - host, PMAP_PROG, PMAP_VERS, PMAP_PORT) - - -class BroadcastUDPPortMapperClient(PartialPortMapperClient, \ - RawBroadcastUDPClient): - - def __init__(self, bcastaddr): - RawBroadcastUDPClient.__init__(self, \ - bcastaddr, PMAP_PROG, PMAP_VERS, PMAP_PORT) - - -# Generic clients that find their server through the Port mapper - -class TCPClient(RawTCPClient): - - def __init__(self, host, prog, vers): - pmap = TCPPortMapperClient(host) - port = pmap.Getport((prog, vers, IPPROTO_TCP, 0)) - pmap.close() - if port == 0: - raise RuntimeError('program not registered') - RawTCPClient.__init__(self, host, prog, vers, port) - - -class UDPClient(RawUDPClient): - - def __init__(self, host, prog, vers): - pmap = UDPPortMapperClient(host) - port = pmap.Getport((prog, vers, IPPROTO_UDP, 0)) - pmap.close() - if port == 0: - raise RuntimeError('program not registered') - RawUDPClient.__init__(self, host, prog, vers, port) - - -class BroadcastUDPClient(Client): - - def __init__(self, bcastaddr, prog, vers): - self.pmap = BroadcastUDPPortMapperClient(bcastaddr) - self.pmap.set_reply_handler(self.my_reply_handler) - self.prog = prog - self.vers = vers - self.user_reply_handler = None - self.addpackers() - - def close(self): - self.pmap.close() - - def set_reply_handler(self, reply_handler): - self.user_reply_handler = reply_handler - - def set_timeout(self, timeout): - self.pmap.set_timeout(timeout) - - def my_reply_handler(self, reply, fromaddr): - port, res = reply - self.unpacker.reset(res) - result = self.unpack_func() - self.unpacker.done() - self.replies.append((result, fromaddr)) - if self.user_reply_handler is not None: - self.user_reply_handler(result, fromaddr) - - def make_call(self, proc, args, pack_func, unpack_func): - self.packer.reset() - if pack_func: - pack_func(args) - if unpack_func is None: - def dummy(): pass - self.unpack_func = dummy - else: - self.unpack_func = unpack_func - self.replies = [] - packed_args = self.packer.get_buf() - dummy_replies = self.pmap.Callit( \ - (self.prog, self.vers, proc, packed_args)) - return self.replies - - -# Server classes - -# These are not symmetric to the Client classes -# XXX No attempt is made to provide authorization hooks yet - -class Server: - - def __init__(self, host, prog, vers, port): - self.host = host # Should normally be '' for default interface - self.prog = prog - self.vers = vers - self.port = port # Should normally be 0 for random port - self.makesocket() # Assigns to self.sock and self.prot - self.bindsocket() - self.host, self.port = self.sock.getsockname() - self.addpackers() - - def register(self): - mapping = self.prog, self.vers, self.prot, self.port - p = TCPPortMapperClient(self.host) - if not p.Set(mapping): - raise RuntimeError('register failed') - - def unregister(self): - mapping = self.prog, self.vers, self.prot, self.port - p = TCPPortMapperClient(self.host) - if not p.Unset(mapping): - raise RuntimeError('unregister failed') - - def handle(self, call): - # Don't use unpack_header but parse the header piecewise - # XXX I have no idea if I am using the right error responses! - self.unpacker.reset(call) - self.packer.reset() - xid = self.unpacker.unpack_uint() - self.packer.pack_uint(xid) - temp = self.unpacker.unpack_enum() - if temp != CALL: - return None # Not worthy of a reply - self.packer.pack_uint(REPLY) - temp = self.unpacker.unpack_uint() - if temp != RPCVERSION: - self.packer.pack_uint(MSG_DENIED) - self.packer.pack_uint(RPC_MISMATCH) - self.packer.pack_uint(RPCVERSION) - self.packer.pack_uint(RPCVERSION) - return self.packer.get_buf() - self.packer.pack_uint(MSG_ACCEPTED) - self.packer.pack_auth((AUTH_NULL, make_auth_null())) - prog = self.unpacker.unpack_uint() - if prog != self.prog: - self.packer.pack_uint(PROG_UNAVAIL) - return self.packer.get_buf() - vers = self.unpacker.unpack_uint() - if vers != self.vers: - self.packer.pack_uint(PROG_MISMATCH) - self.packer.pack_uint(self.vers) - self.packer.pack_uint(self.vers) - return self.packer.get_buf() - proc = self.unpacker.unpack_uint() - methname = 'handle_' + repr(proc) - try: - meth = getattr(self, methname) - except AttributeError: - self.packer.pack_uint(PROC_UNAVAIL) - return self.packer.get_buf() - cred = self.unpacker.unpack_auth() - verf = self.unpacker.unpack_auth() - try: - meth() # Unpack args, call turn_around(), pack reply - except (EOFError, GarbageArgs): - # Too few or too many arguments - self.packer.reset() - self.packer.pack_uint(xid) - self.packer.pack_uint(REPLY) - self.packer.pack_uint(MSG_ACCEPTED) - self.packer.pack_auth((AUTH_NULL, make_auth_null())) - self.packer.pack_uint(GARBAGE_ARGS) - return self.packer.get_buf() - - def turn_around(self): - try: - self.unpacker.done() - except RuntimeError: - raise GarbageArgs - self.packer.pack_uint(SUCCESS) - - def handle_0(self): # Handle NULL message - self.turn_around() - - def makesocket(self): - # This MUST be overridden - raise RuntimeError('makesocket not defined') - - def bindsocket(self): - # Override this to bind to a different port (e.g. reserved) - self.sock.bind((self.host, self.port)) - - def addpackers(self): - # Override this to use derived classes from Packer/Unpacker - self.packer = Packer() - self.unpacker = Unpacker('') - - -class TCPServer(Server): - - def makesocket(self): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.prot = IPPROTO_TCP - - def loop(self): - self.sock.listen(0) - while 1: - self.session(self.sock.accept()) - - def session(self, connection): - sock, (host, port) = connection - while 1: - try: - call = recvrecord(sock) - except EOFError: - break - except socket.error as msg: - print('socket error:', msg) - break - reply = self.handle(call) - if reply is not None: - sendrecord(sock, reply) - - def forkingloop(self): - # Like loop but uses forksession() - self.sock.listen(0) - while 1: - self.forksession(self.sock.accept()) - - def forksession(self, connection): - # Like session but forks off a subprocess - import os - # Wait for deceased children - try: - while 1: - pid, sts = os.waitpid(0, 1) - except os.error: - pass - pid = None - try: - pid = os.fork() - if pid: # Parent - connection[0].close() - return - # Child - self.session(connection) - finally: - # Make sure we don't fall through in the parent - if pid == 0: - os._exit(0) - - -class UDPServer(Server): - - def makesocket(self): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.prot = IPPROTO_UDP - - def loop(self): - while 1: - self.session() - - def session(self): - call, host_port = self.sock.recvfrom(8192) - reply = self.handle(call) - if reply is not None: - self.sock.sendto(reply, host_port) - - -# Simple test program -- dump local portmapper status - -def test(): - pmap = UDPPortMapperClient('') - list = pmap.Dump() - list.sort() - for prog, vers, prot, port in list: - print(prog, vers, end=' ') - if prot == IPPROTO_TCP: print('tcp', end=' ') - elif prot == IPPROTO_UDP: print('udp', end=' ') - else: print(prot, end=' ') - print(port) - - -# Test program for broadcast operation -- dump everybody's portmapper status - -def testbcast(): - import sys - if sys.argv[1:]: - bcastaddr = sys.argv[1] - else: - bcastaddr = '<broadcast>' - def rh(reply, fromaddr): - host, port = fromaddr - print(host + '\t' + repr(reply)) - pmap = BroadcastUDPPortMapperClient(bcastaddr) - pmap.set_reply_handler(rh) - pmap.set_timeout(5) - replies = pmap.Getport((100002, 1, IPPROTO_UDP, 0)) - - -# Test program for server, with corresponding client -# On machine A: python -c 'import rpc; rpc.testsvr()' -# On machine B: python -c 'import rpc; rpc.testclt()' A -# (A may be == B) - -def testsvr(): - # Simple test class -- proc 1 doubles its string argument as reply - class S(UDPServer): - def handle_1(self): - arg = self.unpacker.unpack_string() - self.turn_around() - print('RPC function 1 called, arg', repr(arg)) - self.packer.pack_string(arg + arg) - # - s = S('', 0x20000000, 1, 0) - try: - s.unregister() - except RuntimeError as msg: - print('RuntimeError:', msg, '(ignored)') - s.register() - print('Service started...') - try: - s.loop() - finally: - s.unregister() - print('Service interrupted.') - - -def testclt(): - import sys - if sys.argv[1:]: host = sys.argv[1] - else: host = '' - # Client for above server - class C(UDPClient): - def call_1(self, arg): - return self.make_call(1, arg, \ - self.packer.pack_string, \ - self.unpacker.unpack_string) - c = C(host, 0x20000000, 1) - print('making call...') - reply = c.call_1('hello, world, ') - print('call returned', repr(reply)) diff --git a/Demo/rpc/test b/Demo/rpc/test deleted file mode 100755 index ba220f2..0000000 --- a/Demo/rpc/test +++ /dev/null @@ -1,24 +0,0 @@ -: ${PYTHON=python} -: ${SERVER=charon.cwi.nl} - -set -xe - -$PYTHON -c 'from rpc import test; test()' -$PYTHON -c 'from rpc import test; test()' ${SERVER} - -$PYTHON -c 'from rpc import testsvr; testsvr()' & -PID=$! -sleep 2 -$PYTHON -c 'from rpc import testclt; testclt()' -kill -2 $PID - -$PYTHON -c 'from mountclient import test; test()' -$PYTHON -c 'from mountclient import test; test()' gatekeeper.dec.com - -$PYTHON -c 'from nfsclient import test; test()' -$PYTHON -c 'from nfsclient import test; test()' gatekeeper.dec.com -$PYTHON -c 'from nfsclient import test; test()' gatekeeper.dec.com /archive - -$PYTHON -c 'from rnusersclient import test; test()' '' - -$PYTHON -c 'from rpc import testbcast; testbcast()' diff --git a/Demo/rpc/xdr.py b/Demo/rpc/xdr.py deleted file mode 100644 index 2d5f9c3..0000000 --- a/Demo/rpc/xdr.py +++ /dev/null @@ -1,200 +0,0 @@ -# Implement (a subset of) Sun XDR -- RFC1014. - - -try: - import struct -except ImportError: - struct = None - - -Long = type(0) - - -class Packer: - - def __init__(self): - self.reset() - - def reset(self): - self.buf = '' - - def get_buf(self): - return self.buf - - def pack_uint(self, x): - self.buf = self.buf + \ - (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \ - chr(int(x>>8 & 0xff)) + chr(int(x & 0xff))) - if struct and struct.pack('l', 1) == '\0\0\0\1': - def pack_uint(self, x): - if type(x) == Long: - x = int((x + 0x80000000) % 0x100000000 \ - - 0x80000000) - self.buf = self.buf + struct.pack('l', x) - - pack_int = pack_uint - - pack_enum = pack_int - - def pack_bool(self, x): - if x: self.buf = self.buf + '\0\0\0\1' - else: self.buf = self.buf + '\0\0\0\0' - - def pack_uhyper(self, x): - self.pack_uint(int(x>>32 & 0xffffffff)) - self.pack_uint(int(x & 0xffffffff)) - - pack_hyper = pack_uhyper - - def pack_float(self, x): - # XXX - self.buf = self.buf + struct.pack('f', x) - - def pack_double(self, x): - # XXX - self.buf = self.buf + struct.pack('d', x) - - def pack_fstring(self, n, s): - if n < 0: - raise ValueError('fstring size must be nonnegative') - n = ((n + 3)//4)*4 - data = s[:n] - data = data + (n - len(data)) * '\0' - self.buf = self.buf + data - - pack_fopaque = pack_fstring - - def pack_string(self, s): - n = len(s) - self.pack_uint(n) - self.pack_fstring(n, s) - - pack_opaque = pack_string - - def pack_list(self, list, pack_item): - for item in list: - self.pack_uint(1) - pack_item(item) - self.pack_uint(0) - - def pack_farray(self, n, list, pack_item): - if len(list) != n: - raise ValueError('wrong array size') - for item in list: - pack_item(item) - - def pack_array(self, list, pack_item): - n = len(list) - self.pack_uint(n) - self.pack_farray(n, list, pack_item) - - -class Unpacker: - - def __init__(self, data): - self.reset(data) - - def reset(self, data): - self.buf = data - self.pos = 0 - - def done(self): - if self.pos < len(self.buf): - raise RuntimeError('unextracted data remains') - - def unpack_uint(self): - i = self.pos - self.pos = j = i+4 - data = self.buf[i:j] - if len(data) < 4: - raise EOFError - x = int(ord(data[0]))<<24 | ord(data[1])<<16 | \ - ord(data[2])<<8 | ord(data[3]) - # Return a Python long only if the value is not representable - # as a nonnegative Python int - if x < 0x80000000: x = int(x) - return x - if struct and struct.unpack('l', '\0\0\0\1') == 1: - def unpack_uint(self): - i = self.pos - self.pos = j = i+4 - data = self.buf[i:j] - if len(data) < 4: - raise EOFError - return struct.unpack('l', data) - - def unpack_int(self): - x = self.unpack_uint() - if x >= 0x80000000: x = x - 0x100000000 - return int(x) - - unpack_enum = unpack_int - - unpack_bool = unpack_int - - def unpack_uhyper(self): - hi = self.unpack_uint() - lo = self.unpack_uint() - return int(hi)<<32 | lo - - def unpack_hyper(self): - x = self.unpack_uhyper() - if x >= 0x8000000000000000: x = x - 0x10000000000000000 - return x - - def unpack_float(self): - # XXX - i = self.pos - self.pos = j = i+4 - data = self.buf[i:j] - if len(data) < 4: - raise EOFError - return struct.unpack('f', data)[0] - - def unpack_double(self): - # XXX - i = self.pos - self.pos = j = i+8 - data = self.buf[i:j] - if len(data) < 8: - raise EOFError - return struct.unpack('d', data)[0] - - def unpack_fstring(self, n): - if n < 0: - raise ValueError('fstring size must be nonnegative') - i = self.pos - j = i + (n+3)//4*4 - if j > len(self.buf): - raise EOFError - self.pos = j - return self.buf[i:i+n] - - unpack_fopaque = unpack_fstring - - def unpack_string(self): - n = self.unpack_uint() - return self.unpack_fstring(n) - - unpack_opaque = unpack_string - - def unpack_list(self, unpack_item): - list = [] - while 1: - x = self.unpack_uint() - if x == 0: break - if x != 1: - raise RuntimeError('0 or 1 expected, got %r' % (x, )) - item = unpack_item() - list.append(item) - return list - - def unpack_farray(self, n, unpack_item): - list = [] - for i in range(n): - list.append(unpack_item()) - return list - - def unpack_array(self, unpack_item): - n = self.unpack_uint() - return self.unpack_farray(n, unpack_item) diff --git a/Demo/scripts/README b/Demo/scripts/README deleted file mode 100644 index 097b9b7..0000000 --- a/Demo/scripts/README +++ /dev/null @@ -1,22 +0,0 @@ -This directory contains a collection of executable Python scripts. - -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 -from.py Summarize mailbox -lpwatch.py Watch BSD line printer queues -makedir.py Like mkdir -p -markov.py Markov chain simulation of words or characters -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 -queens.py Dijkstra's solution to Wirth's "N Queens problem" -script.py Equivalent to BSD script(1) -- by Steen Lumholt -unbirthday.py Print unbirthday count -update.py Update a bunch of files according to a script. diff --git a/Demo/scripts/beer.py b/Demo/scripts/beer.py deleted file mode 100644 index 8135509..0000000 --- a/Demo/scripts/beer.py +++ /dev/null @@ -1,20 +0,0 @@ -#! /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]) - -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, 0, -1): - print(bottle(i), "on the wall,") - print(bottle(i) + ".") - print("Take one down, pass it around,") - print(bottle(i-1), "on the wall.") diff --git a/Demo/scripts/eqfix.py b/Demo/scripts/eqfix.py deleted file mode 100755 index 47c00d3..0000000 --- a/Demo/scripts/eqfix.py +++ /dev/null @@ -1,198 +0,0 @@ -#! /usr/bin/env python - -# Fix Python source files to use the new equality test operator, i.e., -# if x = y: ... -# is changed to -# if x == y: ... -# The script correctly tokenizes the Python program to reliably -# distinguish between assignments and equality tests. -# -# Command line arguments are files or directories to be processed. -# Directories are searched recursively for files whose name looks -# like a python module. -# Symbolic links are always ignored (except as explicit directory -# arguments). Of course, the original file is kept as a back-up -# (with a "~" attached to its name). -# It complains about binaries (files containing null bytes) -# and about files that are ostensibly not Python files: if the first -# line starts with '#!' and does not contain the string 'python'. -# -# Changes made are reported to stdout in a diff-like format. -# -# Undoubtedly you can do this using find and sed or perl, but this is -# a nice example of Python code that recurses down a directory tree -# and uses regular expressions. Also note several subtleties like -# preserving the file's mode and avoiding to even write a temp file -# when no changes are needed for a file. -# -# NB: by changing only the function fixline() you can turn this -# into a program for a different change to Python programs... - -import sys -import re -import os -from stat import * -import string - -err = sys.stderr.write -dbg = err -rep = sys.stdout.write - -def main(): - bad = 0 - if not sys.argv[1:]: # No arguments - err('usage: ' + sys.argv[0] + ' file-or-directory ...\n') - sys.exit(2) - for arg in sys.argv[1:]: - if os.path.isdir(arg): - if recursedown(arg): bad = 1 - elif os.path.islink(arg): - err(arg + ': will not process symbolic links\n') - bad = 1 - else: - if fix(arg): bad = 1 - sys.exit(bad) - -ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$') -def ispython(name): - return ispythonprog.match(name) >= 0 - -def recursedown(dirname): - dbg('recursedown(%r)\n' % (dirname,)) - bad = 0 - try: - names = os.listdir(dirname) - except os.error as msg: - err('%s: cannot list directory: %r\n' % (dirname, msg)) - return 1 - names.sort() - subdirs = [] - for name in names: - if name in (os.curdir, os.pardir): continue - fullname = os.path.join(dirname, name) - if os.path.islink(fullname): pass - elif os.path.isdir(fullname): - subdirs.append(fullname) - elif ispython(name): - if fix(fullname): bad = 1 - for fullname in subdirs: - if recursedown(fullname): bad = 1 - return bad - -def fix(filename): -## dbg('fix(%r)\n' % (dirname,)) - try: - f = open(filename, 'r') - except IOError as msg: - err('%s: cannot open: %r\n' % (filename, msg)) - return 1 - head, tail = os.path.split(filename) - tempname = os.path.join(head, '@' + tail) - g = None - # If we find a match, we rewind the file and start over but - # now copy everything to a temp file. - lineno = 0 - while 1: - line = f.readline() - if not line: break - lineno = lineno + 1 - if g is None and '\0' in line: - # Check for binary files - err(filename + ': contains null bytes; not fixed\n') - f.close() - return 1 - if lineno == 1 and g is None and line[:2] == '#!': - # Check for non-Python scripts - words = string.split(line[2:]) - if words and re.search('[pP]ython', words[0]) < 0: - msg = filename + ': ' + words[0] - msg = msg + ' script; not fixed\n' - err(msg) - f.close() - return 1 - while line[-2:] == '\\\n': - nextline = f.readline() - if not nextline: break - line = line + nextline - lineno = lineno + 1 - newline = fixline(line) - if newline != line: - if g is None: - try: - g = open(tempname, 'w') - except IOError as msg: - f.close() - err('%s: cannot create: %r\n' % (tempname, msg)) - return 1 - f.seek(0) - lineno = 0 - rep(filename + ':\n') - continue # restart from the beginning - rep(repr(lineno) + '\n') - rep('< ' + line) - rep('> ' + newline) - if g is not None: - g.write(newline) - - # End of file - f.close() - if not g: return 0 # No changes - - # Finishing touch -- move files - - # First copy the file's mode to the temp file - try: - statbuf = os.stat(filename) - os.chmod(tempname, statbuf[ST_MODE] & 0o7777) - except os.error as msg: - err('%s: warning: chmod failed (%r)\n' % (tempname, msg)) - # Then make a backup of the original file as filename~ - try: - os.rename(filename, filename + '~') - except os.error as msg: - err('%s: warning: backup failed (%r)\n' % (filename, msg)) - # Now move the temp file to the original file - try: - os.rename(tempname, filename) - except os.error as msg: - err('%s: rename failed (%r)\n' % (filename, msg)) - return 1 - # Return succes - return 0 - - -from tokenize import tokenprog - -match = {'if':':', 'elif':':', 'while':':', 'return':'\n', \ - '(':')', '[':']', '{':'}', '`':'`'} - -def fixline(line): - # Quick check for easy case - if '=' not in line: return line - - i, n = 0, len(line) - stack = [] - while i < n: - j = tokenprog.match(line, i) - if j < 0: - # A bad token; forget about the rest of this line - print('(Syntax error:)') - print(line, end=' ') - return line - a, b = tokenprog.regs[3] # Location of the token proper - token = line[a:b] - i = i+j - if stack and token == stack[-1]: - del stack[-1] - elif token in match: - stack.append(match[token]) - elif token == '=' and stack: - line = line[:a] + '==' + line[b:] - i, n = a + len('=='), len(line) - elif token == '==' and not stack: - print('(Warning: \'==\' at top level:)') - print(line, end=' ') - return line - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/fact.py b/Demo/scripts/fact.py deleted file mode 100755 index 71fcda2..0000000 --- a/Demo/scripts/fact.py +++ /dev/null @@ -1,49 +0,0 @@ -#! /usr/bin/env python - -# Factorize numbers. -# The algorithm is not efficient, but easy to understand. -# If there are large factors, it will take forever to find them, -# because we try all odd numbers between 3 and sqrt(n)... - -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 - res = [] - # Treat even factors special, so we can use i += 2 later - while n % 2 == 0: - res.append(2) - n //= 2 - # Try odd numbers up to sqrt(n) - limit = sqrt(n+1) - i = 3 - while i <= limit: - if n % i == 0: - res.append(i) - n //= i - limit = sqrt(n+1) - else: - i += 2 - if n != 1: - res.append(n) - return res - -def main(): - if len(sys.argv) > 1: - source = sys.argv[1:] - else: - source = iter(input, '') - for arg in source: - try: - n = int(arg) - except ValueError: - print(arg, 'is not an integer') - else: - print(n, fact(n)) - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/find-uname.py b/Demo/scripts/find-uname.py deleted file mode 100644 index 1902423..0000000 --- a/Demo/scripts/find-uname.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python - -""" -For each argument on the command line, look for it in the set of all Unicode -names. Arguments are treated as case-insensitive regular expressions, e.g.: - - % find-uname 'small letter a$' 'horizontal line' - *** small letter a$ matches *** - LATIN SMALL LETTER A (97) - COMBINING LATIN SMALL LETTER A (867) - CYRILLIC SMALL LETTER A (1072) - PARENTHESIZED LATIN SMALL LETTER A (9372) - CIRCLED LATIN SMALL LETTER A (9424) - FULLWIDTH LATIN SMALL LETTER A (65345) - *** horizontal line matches *** - HORIZONTAL LINE EXTENSION (9135) -""" - -import unicodedata -import sys -import re - -def main(args): - unicode_names = [] - for ix in range(sys.maxunicode+1): - try: - 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 = [(y,x) for (x,y) in unicode_names - if pat.search(y) is not None] - if matches: - print("***", arg, "matches", "***") - for match in matches: - print("%s (%d)" % match) - -if __name__ == "__main__": - main(sys.argv[1:]) diff --git a/Demo/scripts/from.py b/Demo/scripts/from.py deleted file mode 100755 index 323e684..0000000 --- a/Demo/scripts/from.py +++ /dev/null @@ -1,35 +0,0 @@ -#! /usr/bin/env python - -# Print From and Subject of messages in $MAIL. -# Extension to multiple mailboxes and other bells & whistles are left -# as exercises for the reader. - -import sys, os - -# Open mailbox file. Exits with exception when this fails. - -try: - mailbox = os.environ['MAIL'] -except (AttributeError, KeyError): - sys.stderr.write('No environment variable $MAIL\n') - sys.exit(2) - -try: - mail = open(mailbox) -except IOError: - sys.exit('Cannot open mailbox file: ' + mailbox) - -while 1: - line = mail.readline() - if not line: - break # EOF - if line.startswith('From '): - # Start of message found - print(line[:-1], end=' ') - while 1: - line = mail.readline() - if not line or line == '\n': - break - if line.startswith('Subject: '): - print(repr(line[9:-1]), end=' ') - print() diff --git a/Demo/scripts/lpwatch.py b/Demo/scripts/lpwatch.py deleted file mode 100755 index 90b3ecf..0000000 --- a/Demo/scripts/lpwatch.py +++ /dev/null @@ -1,102 +0,0 @@ -#! /usr/bin/env python - -# Watch line printer queue(s). -# Intended for BSD 4.3 lpq. - -import os -import sys -import time - -DEF_PRINTER = 'psc' -DEF_DELAY = 10 - -def main(): - delay = DEF_DELAY # XXX Use getopt() later - try: - thisuser = os.environ['LOGNAME'] - except: - thisuser = os.environ['USER'] - printers = sys.argv[1:] - if printers: - # Strip '-P' from printer names just in case - # the user specified it... - for i, name in enumerate(printers): - if name[:2] == '-P': - printers[i] = name[2:] - else: - if 'PRINTER' in os.environ: - printers = [os.environ['PRINTER']] - else: - printers = [DEF_PRINTER] - - clearhome = os.popen('clear', 'r').read() - - while True: - text = clearhome - for name in printers: - text += makestatus(name, thisuser) + '\n' - print(text) - time.sleep(delay) - -def makestatus(name, thisuser): - pipe = os.popen('lpq -P' + name + ' 2>&1', 'r') - lines = [] - users = {} - aheadbytes = 0 - aheadjobs = 0 - userseen = False - totalbytes = 0 - totaljobs = 0 - for line in pipe: - fields = line.split() - n = len(fields) - if len(fields) >= 6 and fields[n-1] == 'bytes': - rank, user, job = fields[0:3] - files = fields[3:-2] - bytes = int(fields[n-2]) - if user == thisuser: - userseen = True - elif not userseen: - 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 = 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) - if totaljobs != len(users): - line += ' (%d jobs)' % totaljobs - if len(users) == 1: - line += ' for %s' % next(iter(users)) - else: - line += ' for %d users' % len(users) - if userseen: - if aheadjobs == 0: - line += ' (%s first)' % thisuser - else: - 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 ': '.join(lines) - -if __name__ == "__main__": - try: - main() - except KeyboardInterrupt: - pass diff --git a/Demo/scripts/makedir.py b/Demo/scripts/makedir.py deleted file mode 100755 index 7095868..0000000 --- a/Demo/scripts/makedir.py +++ /dev/null @@ -1,21 +0,0 @@ -#! /usr/bin/env python - -# Like mkdir, but also make intermediate directories if necessary. -# It is not an error if the given directory already exists (as long -# as it is a directory). -# Errors are not treated specially -- you just get a Python exception. - -import sys, os - -def main(): - for p in sys.argv[1:]: - makedirs(p) - -def makedirs(p): - if p and not os.path.isdir(p): - head, tail = os.path.split(p) - makedirs(head) - os.mkdir(p, 0o777) - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/markov.py b/Demo/scripts/markov.py deleted file mode 100755 index 990c972..0000000 --- a/Demo/scripts/markov.py +++ /dev/null @@ -1,121 +0,0 @@ -#! /usr/bin/env python - -class Markov: - def __init__(self, histsize, choice): - self.histsize = histsize - self.choice = choice - self.trans = {} - - def add(self, state, next): - self.trans.setdefault(state, []).append(next) - - def put(self, seq): - n = self.histsize - add = self.add - add(None, seq[:0]) - 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 True: - subseq = seq[max(0, len(seq)-n):] - options = trans[subseq] - next = choice(options) - if not next: - break - seq += next - return seq - - -def test(): - import sys, random, getopt - args = sys.argv[1:] - try: - opts, args = getopt.getopt(args, '0123456789cdwq') - except getopt.error: - print('Usage: %s [-#] [-cddqw] [file] ...' % sys.argv[0]) - print('Options:') - print('-#: 1-digit history size (default 2)') - print('-c: characters (default)') - print('-w: words') - print('-d: more debugging output') - print('-q: no debugging output') - print('Input files (default stdin) are split in paragraphs') - print('separated blank lines and each paragraph is split') - print('in words by whitespace, then reconcatenated with') - 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 = False - debug = 1 - for o, a in opts: - 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 = True - if not args: - args = ['-'] - - m = Markov(histsize, random.choice) - try: - for filename in args: - if filename == '-': - f = sys.stdin - if f.isatty(): - print('Sorry, need stdin from file') - continue - else: - f = open(filename, 'r') - if debug: print('processing', filename, '...') - text = f.read() - f.close() - paralist = text.split('\n\n') - for para in paralist: - if debug > 1: print('feeding ...') - words = para.split() - if words: - if do_words: - data = tuple(words) - else: - data = ' '.join(words) - m.put(data) - except KeyboardInterrupt: - print('Interrupted -- continue with data read so far') - if not m.trans: - 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 True: - data = m.get() - if do_words: - words = data - else: - words = data.split() - n = 0 - limit = 72 - for w in words: - if n + len(w) > limit: - print() - n = 0 - print(w, end=' ') - n += len(w) + 1 - print() - print() - -if __name__ == "__main__": - test() diff --git a/Demo/scripts/mboxconvert.py b/Demo/scripts/mboxconvert.py deleted file mode 100755 index 2e44f06..0000000 --- a/Demo/scripts/mboxconvert.py +++ /dev/null @@ -1,124 +0,0 @@ -#! /usr/bin/env python - -# Convert MH directories (1 message per file) or MMDF mailboxes (4x^A -# delimited) to unix mailbox (From ... delimited) on stdout. -# If -f is given, files contain one message per file (e.g. MH messages) - -import rfc822 -import sys -import time -import os -import stat -import getopt -import re - -def main(): - dofile = mmdf - try: - opts, args = getopt.getopt(sys.argv[1:], 'f') - except getopt.error as msg: - sys.stderr.write('%s\n' % msg) - sys.exit(2) - for o, a in opts: - if o == '-f': - dofile = message - if not args: - args = ['-'] - sts = 0 - for arg in args: - if arg == '-' or arg == '': - sts = dofile(sys.stdin) or sts - elif os.path.isdir(arg): - sts = mh(arg) or sts - elif os.path.isfile(arg): - try: - f = open(arg) - except IOError as msg: - sys.stderr.write('%s: %s\n' % (arg, msg)) - sts = 1 - continue - sts = dofile(f) or sts - f.close() - else: - sys.stderr.write('%s: not found\n' % arg) - sts = 1 - if sts: - sys.exit(sts) - -numeric = re.compile('[1-9][0-9]*') - -def mh(dir): - sts = 0 - msgs = os.listdir(dir) - for msg in msgs: - if numeric.match(msg) != len(msg): - continue - fn = os.path.join(dir, msg) - try: - f = open(fn) - except IOError as msg: - sys.stderr.write('%s: %s\n' % (fn, msg)) - sts = 1 - continue - sts = message(f) or sts - return sts - -def mmdf(f): - sts = 0 - while 1: - line = f.readline() - if not line: - break - if line == '\1\1\1\1\n': - sts = message(f, line) or sts - else: - sys.stderr.write( - 'Bad line in MMFD mailbox: %r\n' % (line,)) - return sts - -counter = 0 # for generating unique Message-ID headers - -def message(f, delimiter = ''): - sts = 0 - # Parse RFC822 header - m = rfc822.Message(f) - # Write unix header line - fullname, email = m.getaddr('From') - tt = m.getdate('Date') - if tt: - t = time.mktime(tt) - else: - sys.stderr.write( - 'Unparseable date: %r\n' % (m.get('Date'),)) - t = os.fstat(f.fileno())[stat.ST_MTIME] - print('From', email, time.ctime(t)) - # Copy RFC822 header - for line in m.headers: - print(line, end=' ') - # Invent Message-ID header if none is present - if 'message-id' not in m: - global counter - counter = counter + 1 - msgid = "<%s.%d>" % (hex(t), counter) - sys.stderr.write("Adding Message-ID %s (From %s)\n" % - (msgid, email)) - print("Message-ID:", msgid) - print() - # Copy body - while 1: - line = f.readline() - if line == delimiter: - break - if not line: - sys.stderr.write('Unexpected EOF in message\n') - sts = 1 - break - if line[:5] == 'From ': - line = '>' + line - print(line, end=' ') - # Print trailing newline - print() - return sts - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/morse.py b/Demo/scripts/morse.py deleted file mode 100755 index 5aacaa1..0000000 --- a/Demo/scripts/morse.py +++ /dev/null @@ -1,128 +0,0 @@ -#! /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() diff --git a/Demo/scripts/newslist.doc b/Demo/scripts/newslist.doc deleted file mode 100755 index 87fd9ba..0000000 --- a/Demo/scripts/newslist.doc +++ /dev/null @@ -1,59 +0,0 @@ - NEWSLIST - ======== - A program to assist HTTP browsing of newsgroups - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -WWW browsers such as NCSA Mosaic allow the user to read newsgroup -articles by specifying the group name in a URL eg 'news:comp.answers'. - -To browse through many groups, though, (and there are several thousand -of them) you really need a page or pages containing links to all the -groups. There are some good ones out there, for example, - - http://info.cern.ch/hypertext/DataSources/News/Groups/Overview.html - -is the standard one at CERN, but it only shows the groups available there, -which may be rather different from those available on your machine. - -Newslist is a program which creates a hierarchy of pages for you based -on the groups available from YOUR server. It is written in python - a -splendid interpreted object-oriented language which I suggest you get -right now from the directory /pub/python at ftp.cwi.nl, if you haven't -already got it. - -You should be able to see some sample output by looking at: - http://pelican.cl.cam.ac.uk/newspage/root.html - -Descriptions of newsgroups can be added from a file with one group -per line. eg: - - alt.foo Articles about foo - comp.bar Programming in 'bar' and related languages - -A suitable list detailing most groups can be found at ftp.uu.net in -/uunet-info/newsgroups.gz. - -Make sure you read the information at the beginning of the program source and -configure the variables before running. - -In addition to python, you need: - - An NNTP-based news feed. - A directory in which to put the pages. - -The programming is not very beautiful, but it works! It comes with no -warranty, express or implied, but with the hope that some others may -find it useful. - -Comments, improvements & suggestions welcomed. -Quentin Stafford-Fraser - - ---------------------------------------------------------------------- - Quentin Stafford-Fraser - http://pelican.cl.cam.ac.uk/people/qs101/me.html - - Cambridge University Computer Lab Rank Xerox Cambridge EuroPARC - qs101@cl.cam.ac.uk fraser@europarc.xerox.com - Tel: +44 223 334411 Tel: +44 223 341521 - Fax: +44 223 334679 Fax: +44 223 341510 - ---------------------------------------------------------------------- diff --git a/Demo/scripts/newslist.py b/Demo/scripts/newslist.py deleted file mode 100755 index 9cea1b4..0000000 --- a/Demo/scripts/newslist.py +++ /dev/null @@ -1,361 +0,0 @@ -#! /usr/bin/env python -####################################################################### -# Newslist $Revision$ -# -# Syntax: -# newslist [ -a ] -# -# This is a program to create a directory full of HTML pages -# which between them contain links to all the newsgroups available -# on your server. -# -# The -a option causes a complete list of all groups to be read from -# the server rather than just the ones which have appeared since last -# execution. This recreates the local list from scratch. Use this on -# the first invocation of the program, and from time to time thereafter. -# When new groups are first created they may appear on your server as -# empty groups. By default, empty groups are ignored by the -a option. -# However, these new groups will not be created again, and so will not -# appear in the server's list of 'new groups' at a later date. Hence it -# won't appear until you do a '-a' after some articles have appeared. -# -# I should really keep a list of ignored empty groups and re-check them -# for articles on every run, but I haven't got around to it yet. -# -# This assumes an NNTP news feed. -# -# Feel free to copy, distribute and modify this code for -# non-commercial use. If you make any useful modifications, let me -# know! -# -# (c) Quentin Stafford-Fraser 1994 -# fraser@europarc.xerox.com qs101@cl.cam.ac.uk -# # -####################################################################### -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 = 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 = os.environ['NNTPSERVER'] -newshost = 'news.example.com' - -# The filename for a local cache of the newsgroup list -treefile = 'grouptree' - -# The filename for descriptions of newsgroups -# I found a suitable one at ftp.uu.net in /uunet-info/newgroups.gz -# You can set this to '' if you don't wish to use one. -descfile = 'newsgroups' - -# The directory in which HTML pages should be created -# eg. -# pagedir = '/usr/local/lib/html/newspage' -# pagedir = 'pages' -pagedir = topdir - -# The html prefix which will refer to this directory -# eg. -# httppref = '/newspage/', -# or leave blank for relative links between pages: (Recommended) -# httppref = '' -httppref = '' - -# The name of the 'root' news page in this directory. -# A .html suffix will be added. -rootpage = 'root' - -# Set skipempty to 0 if you wish to see links to empty groups as well. -# Only affects the -a option. -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"> ' - -# --------------------------------------------------------------------- -# Less important personal preferences: - -# Sublistsize controls the maximum number of items the will appear as -# an indented sub-list before the whole thing is moved onto a different -# page. The smaller this is, the more pages you will have, but the -# shorter each will be. -sublistsize = 4 - -# That should be all. # -####################################################################### - -for dir in os.curdir, os.environ['HOME']: - rcfile = os.path.join(dir, '.newslistrc.py') - if os.path.exists(rcfile): - print(rcfile) - exec(open(rcfile).read()) - break - -from nntplib import NNTP -from stat import * - -rcsrev = '$Revision$' -rcsrev = ' '.join([s for s in rcsrev.split() if '$' not in s]) -desc = {} - -# Make (possibly) relative filenames into absolute ones -treefile = os.path.join(topdir,treefile) -descfile = os.path.join(topdir,descfile) -page = os.path.join(topdir,pagedir) - -# First the bits for creating trees --------------------------- - -# Addtotree creates/augments a tree from a list of group names -def addtotree(tree, groups): - print('Updating tree...') - for i in groups: - parts = i.split('.') - makeleaf(tree, parts) - -# Makeleaf makes a leaf and the branch leading to it if necessary -def makeleaf(tree,path): - j = path[0] - l = len(path) - - if j not in tree: - tree[j] = {} - if l == 1: - tree[j]['.'] = '.' - if l > 1: - makeleaf(tree[j],path[1:]) - -# Then the bits for outputting trees as pages ---------------- - -# Createpage creates an HTML file named <root>.html containing links -# to those groups beginning with <root>. - -def createpage(root, tree, p): - filename = os.path.join(pagedir, root+'.html') - if root == rootpage: - detail = '' - else: - detail = ' under ' + root - 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): - l = len(tree) - - if l > sublistsize and indent > 0: - # Create a new page and a link to it - 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 - - kl = sorted(tree.keys()) - - if l > 1: - if indent > 0: - # Create a sub-list - f.write('<li>%s\n<ul>' % p[1:]) - else: - # Create a main list - f.write('<ul>') - indent = indent + 1 - - for i in kl: - if i == '.': - # Output a newsgroup - f.write('<li><a href="news:%s">%s</a> ' % (p[1:], p[1:])) - if p[1:] in desc: - f.write(' <i>%s</i>\n' % desc[p[1:]]) - else: - f.write('\n') - else: - # Output a hierarchy - printtree(f, tree[i], indent, p+'.'+i) - - if l > 1: - f.write('\n</ul>') - -# Reading descriptions file --------------------------------------- - -# This returns a dict mapping group name to its description - -def readdesc(descfile): - global desc - desc = {} - - if descfile == '': - return - - try: - 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 - -# Check that ouput directory exists, ------------------------------ -# and offer to create it if not - -def checkopdir(pagedir): - if not os.path.isdir(pagedir): - 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) - except: - print('Sorry - failed!') - sys.exit(1) - else: - print('OK. Exiting.') - sys.exit(1) - -# Read and write current local tree ---------------------------------- - -def readlocallist(treefile): - print('Reading current local group list...') - tree = {} - try: - treetime = time.localtime(os.stat(treefile)[ST_MTIME]) - except: - print('\n*** Failed to open local group cache '+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]) - try: - 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: - 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('Does it (or its directory) have the correct permissions?') - sys.exit(1) - -# Return list of all groups on server ----------------------------- - -def getallgroups(server): - print('Getting list of all groups...') - treedate = '010101' - info = server.list()[1] - groups = [] - print('Processing...') - if skipempty: - print('\nIgnoring following empty groups:') - for i in info: - grpname = i[0].split()[0] - if skipempty and int(i[1]) < int(i[2]): - print(grpname.decode() + ' ', end=' ') - else: - groups.append(grpname.decode()) - print('\n') - if skipempty: - print('(End of empty groups)') - return groups - -# Return list of new groups on server ----------------------------- - -def getnewgroups(server, treedate): - 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 = i.split()[0] - groups.append(grpname.decode()) - print('Done') - return groups - -# Now the main program -------------------------------------------- - -def main(): - tree = {} - - # Check that the output directory exists - checkopdir(pagedir) - - try: - print('Connecting to %s...' % newshost) - if sys.version[0] == '0': - s = NNTP.init(newshost) - else: - s = NNTP(newshost) - 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 = 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 - # groups created since local file last modified. - else: - - (tree, treedate) = readlocallist(treefile) - if connected: - groups = getnewgroups(s, treedate) - - if connected: - addtotree(tree, groups) - writelocallist(treefile,tree) - - # Read group descriptions - readdesc(descfile) - - print('Creating pages...') - createpage(rootpage, tree, '') - print('Done') - -if __name__ == "__main__": - main() - -# That's all folks -###################################################################### diff --git a/Demo/scripts/pi.py b/Demo/scripts/pi.py deleted file mode 100755 index 0740cd0..0000000 --- a/Demo/scripts/pi.py +++ /dev/null @@ -1,33 +0,0 @@ -#! /usr/bin/env python - -# Print digits of pi forever. -# -# The algorithm, using Python's 'long' integers ("bignums"), works -# with continued fractions, and was conceived by Lambert Meertens. -# -# See also the ABC Programmer's Handbook, by Geurts, Meertens & Pemberton, -# published by Prentice-Hall (UK) Ltd., 1990. - -import sys - -def main(): - k, a, b, a1, b1 = 2, 4, 1, 12, 4 - 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 - # Print common digits - d, d1 = a//b, a1//b1 - while d == d1: - output(d) - a, a1 = 10*(a%b), 10*(a1%b1) - d, d1 = a//b, a1//b1 - -def output(d): - # Use write() to avoid spaces between the digits - sys.stdout.write(str(d)) - # Flush so the output is seen immediately - sys.stdout.flush() - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/pp.py b/Demo/scripts/pp.py deleted file mode 100755 index 2c948f7..0000000 --- a/Demo/scripts/pp.py +++ /dev/null @@ -1,125 +0,0 @@ -#! /usr/bin/env python - -# Emulate some Perl command line options. -# Usage: pp [-a] [-c] [-d] [-e scriptline] [-F fieldsep] [-n] [-p] [file] ... -# Where the options mean the following: -# -a : together with -n or -p, splits each line into list F -# -c : check syntax only, do not execute any code -# -d : run the script under the debugger, pdb -# -e scriptline : gives one line of the Python script; may be repeated -# -F fieldsep : sets the field separator for the -a option [not in Perl] -# -n : runs the script for each line of input -# -p : prints the line after the script has run -# When no script lines have been passed, the first file argument -# contains the script. With -n or -p, the remaining arguments are -# read as input to the script, line by line. If a file is '-' -# or missing, standard input is read. - -# XXX To do: -# - add -i extension option (change files in place) -# - make a single loop over the files and lines (changes effect of 'break')? -# - add an option to specify the record separator -# - except for -n/-p, run directly from the file if at all possible - -import sys -import getopt - -FS = '' -SCRIPT = [] -AFLAG = 0 -CFLAG = 0 -DFLAG = 0 -NFLAG = 0 -PFLAG = 0 - -try: - optlist, ARGS = getopt.getopt(sys.argv[1:], 'acde:F:np') -except getopt.error as msg: - sys.stderr.write('%s: %s\n' % (sys.argv[0], msg)) - sys.exit(2) - -for option, optarg in optlist: - if option == '-a': - AFLAG = 1 - elif option == '-c': - CFLAG = 1 - elif option == '-d': - DFLAG = 1 - elif option == '-e': - for line in optarg.split('\n'): - SCRIPT.append(line) - elif option == '-F': - FS = optarg - elif option == '-n': - NFLAG = 1 - PFLAG = 0 - elif option == '-p': - NFLAG = 1 - PFLAG = 1 - else: - print(option, 'not recognized???') - -if not ARGS: ARGS.append('-') - -if not SCRIPT: - if ARGS[0] == '-': - fp = sys.stdin - else: - fp = open(ARGS[0], 'r') - while 1: - line = fp.readline() - if not line: break - SCRIPT.append(line[:-1]) - del fp - del ARGS[0] - if not ARGS: ARGS.append('-') - -if CFLAG: - prologue = ['if 0:'] - epilogue = [] -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 = L.split(FS)', - ' \t \t \telse: F = L.split()' - ] - 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:'] - epilogue = [] - -# Note that we indent using tabs only, so that any indentation style -# used in 'command' will come out right after re-indentation. - -program = '\n'.join(prologue) + '\n' -for line in SCRIPT: - program += ' \t \t' + line + '\n' -program += '\n'.join(epilogue) + '\n' - -if DFLAG: - import pdb - pdb.run(program) -else: - exec(program) diff --git a/Demo/scripts/primes.py b/Demo/scripts/primes.py deleted file mode 100755 index 0924aab..0000000 --- a/Demo/scripts/primes.py +++ /dev/null @@ -1,27 +0,0 @@ -#! /usr/bin/env python - -# Print prime numbers in a given range - -def main(): - import sys - min, max = 2, 0x7fffffff - if sys.argv[1:]: - min = int(eval(sys.argv[1])) - if sys.argv[2:]: - max = int(eval(sys.argv[2])) - primes(min, max) - -def primes(min, max): - if 2 >= min: print(2) - primes = [2] - i = 3 - while i <= max: - for p in primes: - if i%p == 0 or p*p > i: break - if i%p != 0: - primes.append(i) - if i >= min: print(i) - i = i+2 - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/queens.py b/Demo/scripts/queens.py deleted file mode 100755 index 726433c..0000000 --- a/Demo/scripts/queens.py +++ /dev/null @@ -1,85 +0,0 @@ -#! /usr/bin/env python - -"""N queens problem. - -The (well-known) problem is due to Niklaus Wirth. - -This solution is inspired by Dijkstra (Structured Programming). It is -a classic recursive backtracking approach. - -""" - -N = 8 # Default; command line overrides - -class Queens: - - def __init__(self, n=N): - self.n = n - self.reset() - - 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.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 - - def solve(self, x=0): # Recursive solver - for y in range(self.n): - if self.safe(x, y): - self.place(x, y) - if x+1 == self.n: - self.display() - else: - self.solve(x+1) - self.remove(x, y) - - def safe(self, x, y): - return not self.row[y] and not self.up[x-y] and not self.down[x+y] - - def place(self, x, y): - self.y[x] = y - self.row[y] = 1 - self.up[x-y] = 1 - self.down[x+y] = 1 - - def remove(self, x, y): - self.y[x] = None - self.row[y] = 0 - self.up[x-y] = 0 - self.down[x+y] = 0 - - silent = 0 # If true, count solutions only - - def display(self): - self.nfound = self.nfound + 1 - if self.silent: - return - print('+-' + '--'*self.n + '+') - for y in range(self.n-1, -1, -1): - print('|', end=' ') - for x in range(self.n): - if self.y[x] == y: - print("Q", end=' ') - else: - print(".", end=' ') - print('|') - print('+-' + '--'*self.n + '+') - -def main(): - import sys - silent = 0 - n = N - if sys.argv[1:2] == ['-n']: - silent = 1 - del sys.argv[1] - if sys.argv[1:]: - n = int(sys.argv[1]) - q = Queens(n) - q.silent = silent - q.solve() - print("Found", q.nfound, "solutions.") - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/script.py b/Demo/scripts/script.py deleted file mode 100755 index b490b17..0000000 --- a/Demo/scripts/script.py +++ /dev/null @@ -1,42 +0,0 @@ -#! /usr/bin/env python - -# script.py -- Make typescript of terminal session. -# Usage: -# -a Append to typescript. -# -p Use Python as shell. -# Author: Steen Lumholt. - - -import os, time, sys, getopt -import pty - -def read(fd): - data = os.read(fd, 1024) - script.write(data) - return data - -shell = 'sh' -filename = 'typescript' -mode = 'wb' -if 'SHELL' in os.environ: - shell = os.environ['SHELL'] - -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) -script.write(('Script started on %s\n' % time.ctime(time.time())).encode()) -pty.spawn(shell, read) -script.write(('Script done on %s\n' % time.ctime(time.time())).encode()) -sys.stdout.write('Script done, file is %s\n' % filename) diff --git a/Demo/scripts/toaiff.py b/Demo/scripts/toaiff.py deleted file mode 100644 index 0e9be23..0000000 --- a/Demo/scripts/toaiff.py +++ /dev/null @@ -1,107 +0,0 @@ -"""Convert "arbitrary" sound files to AIFF (Apple and SGI's audio format). - -Input may be compressed. -Uncompressed file type may be AIFF, WAV, VOC, 8SVX, NeXT/Sun, and others. -An exception is raised if the file is not of a recognized type. -Returned filename is either the input filename or a temporary filename; -in the latter case the caller must ensure that it is removed. -Other temporary files used are removed by the function. -""" - -import os -import tempfile -import pipes -import sndhdr - -__all__ = ["error", "toaiff"] - -table = {} - -t = pipes.Template() -t.append('sox -t au - -t aiff -r 8000 -', '--') -table['au'] = t - -# XXX The following is actually sub-optimal. -# XXX The HCOM sampling rate can be 22k, 22k/2, 22k/3 or 22k/4. -# XXX We must force the output sampling rate else the SGI won't play -# XXX files sampled at 5.5k or 7.333k; however this means that files -# XXX sampled at 11k are unnecessarily expanded. -# XXX Similar comments apply to some other file types. -t = pipes.Template() -t.append('sox -t hcom - -t aiff -r 22050 -', '--') -table['hcom'] = t - -t = pipes.Template() -t.append('sox -t voc - -t aiff -r 11025 -', '--') -table['voc'] = t - -t = pipes.Template() -t.append('sox -t wav - -t aiff -', '--') -table['wav'] = t - -t = pipes.Template() -t.append('sox -t 8svx - -t aiff -r 16000 -', '--') -table['8svx'] = t - -t = pipes.Template() -t.append('sox -t sndt - -t aiff -r 16000 -', '--') -table['sndt'] = t - -t = pipes.Template() -t.append('sox -t sndr - -t aiff -r 16000 -', '--') -table['sndr'] = t - -uncompress = pipes.Template() -uncompress.append('uncompress', '--') - - -class error(Exception): - pass - -def toaiff(filename): - temps = [] - ret = None - try: - ret = _toaiff(filename, temps) - finally: - for temp in temps[:]: - if temp != ret: - try: - os.unlink(temp) - except os.error: - pass - temps.remove(temp) - return ret - -def _toaiff(filename, temps): - if filename[-2:] == '.Z': - (fd, fname) = tempfile.mkstemp() - os.close(fd) - temps.append(fname) - sts = uncompress.copy(filename, fname) - if sts: - raise error(filename + ': uncompress failed') - else: - fname = filename - try: - ftype = sndhdr.whathdr(fname) - if ftype: - ftype = ftype[0] # All we're interested in - except IOError as msg: - if type(msg) == type(()) and len(msg) == 2 and \ - type(msg.args[0]) == type(0) and type(msg.args[1]) == type(''): - msg = msg.args[1] - if type(msg) != type(''): - msg = repr(msg) - raise error(filename + ': ' + msg) - if ftype == 'aiff': - return fname - if ftype is None or not ftype in table: - raise error('%s: unsupported audio file type %r' % (filename, ftype)) - (fd, temp) = tempfile.mkstemp() - os.close(fd) - temps.append(temp) - sts = table[ftype].copy(fname, temp) - if sts: - raise error(filename + ': conversion to aiff failed') - return temp diff --git a/Demo/scripts/unbirthday.py b/Demo/scripts/unbirthday.py deleted file mode 100755 index af58f8f..0000000 --- a/Demo/scripts/unbirthday.py +++ /dev/null @@ -1,106 +0,0 @@ -#! /usr/bin/env python - -# Calculate your unbirthday count (see Alice in Wonderland). -# This is defined as the number of days from your birth until today -# that weren't your birthday. (The day you were born is not counted). -# Leap years make it interesting. - -import sys -import time -import calendar - -def main(): - if sys.argv[1:]: - year = int(sys.argv[1]) - else: - year = int(input('In which year were you born? ')) - 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 <= 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): - print('There is no month numbered', month) - return - - if sys.argv[3:]: - day = int(sys.argv[3]) - else: - day = int(input('And on what day of that month? (1-31) ')) - if month == 2 and calendar.isleap(year): - maxday = 29 - else: - maxday = calendar.mdays[month] - 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=' ') - else: - print('Today is your', end=' ') - print(nth(days - age), 'unbirthday') - -def format(date): - (year, month, day) = date - return '%d %s %d' % (day, calendar.month_name[month], year) - -def nth(n): - if n == 1: return '1st' - if n == 2: return '2nd' - if n == 3: return '3rd' - return '%dth' % n - -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) = 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 - for i in range(1, month): - if i == 2 and calendar.isleap(year): - days = days + 29 - else: - days = days + calendar.mdays[i] - days = days + day - return days - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/update.py b/Demo/scripts/update.py deleted file mode 100755 index d49e4b3..0000000 --- a/Demo/scripts/update.py +++ /dev/null @@ -1,92 +0,0 @@ -#! /usr/bin/env python - -# Update a bunch of files according to a script. -# The input file contains lines of the form <filename>:<lineno>:<text>, -# meaning that the given line of the given file is to be replaced -# by the given text. This is useful for performing global substitutions -# on grep output: - -import os -import sys -import re - -pat = '^([^: \t\n]+):([1-9][0-9]*):' -prog = re.compile(pat) - -class FileObj: - def __init__(self, filename): - self.filename = filename - self.changed = 0 - try: - self.lines = open(filename, 'r').readlines() - except IOError as msg: - print('*** Can\'t open "%s":' % filename, msg) - self.lines = None - return - print('diffing', self.filename) - - def finish(self): - if not self.changed: - print('no changes to', self.filename) - return - try: - os.rename(self.filename, self.filename + '~') - fp = open(self.filename, 'w') - except (os.error, IOError) as msg: - print('*** Can\'t rewrite "%s":' % self.filename, msg) - return - print('writing', self.filename) - for line in self.lines: - fp.write(line) - fp.close() - self.changed = 0 - - def process(self, lineno, rest): - if self.lines is None: - print('(not processed): %s:%s:%s' % ( - self.filename, lineno, rest), end=' ') - return - i = eval(lineno) - 1 - if not 0 <= i < len(self.lines): - print('*** Line number out of range: %s:%s:%s' % ( - self.filename, lineno, rest), end=' ') - return - if self.lines[i] == rest: - print('(no change): %s:%s:%s' % ( - self.filename, lineno, rest), end=' ') - return - if not self.changed: - self.changed = 1 - print('%sc%s' % (lineno, lineno)) - print('<', self.lines[i], end=' ') - print('---') - self.lines[i] = rest - print('>', self.lines[i], end=' ') - -def main(): - if sys.argv[1:]: - try: - fp = open(sys.argv[1], 'r') - except IOError as msg: - print('Can\'t open "%s":' % sys.argv[1], msg) - sys.exit(1) - else: - fp = sys.stdin - curfile = None - while 1: - line = fp.readline() - if not line: - if curfile: curfile.finish() - break - n = prog.match(line) - if n < 0: - print('Funny line:', line, end=' ') - continue - filename, lineno = prog.group(1, 2) - if not curfile or filename != curfile.filename: - if curfile: curfile.finish() - curfile = FileObj(filename) - curfile.process(lineno, line[n:]) - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/wh.py b/Demo/scripts/wh.py deleted file mode 100755 index b9b09ef..0000000 --- a/Demo/scripts/wh.py +++ /dev/null @@ -1,2 +0,0 @@ -# This is here so I can use 'wh' instead of 'which' in '~/bin/generic_python' -import which diff --git a/Demo/sockets/README b/Demo/sockets/README deleted file mode 100644 index eba7c23..0000000 --- a/Demo/sockets/README +++ /dev/null @@ -1,14 +0,0 @@ -This directory contains some demonstrations of the socket module: - -broadcast.py Broadcast the time to radio.py. -echosvr.py About the simplest TCP server possible. -finger.py Client for the 'finger' protocol. -ftp.py A very simple ftp client. -gopher.py A simple gopher client. -mcast.py IPv4/v6 multicast example -radio.py Receive time broadcasts from broadcast.py. -telnet.py Client for the 'telnet' protocol. -throughput.py Client and server to measure TCP throughput. -unixclient.py Unix socket example, client side -unixserver.py Unix socket example, server side -udpecho.py Client and server for the UDP echo protocol. diff --git a/Demo/sockets/broadcast.py b/Demo/sockets/broadcast.py deleted file mode 100755 index 6d2b1e8..0000000 --- a/Demo/sockets/broadcast.py +++ /dev/null @@ -1,15 +0,0 @@ -# Send UDP broadcast packets - -MYPORT = 50000 - -import sys, time -from socket import * - -s = socket(AF_INET, SOCK_DGRAM) -s.bind(('', 0)) -s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) - -while 1: - data = repr(time.time()) + '\n' - s.sendto(data, ('<broadcast>', MYPORT)) - time.sleep(2) diff --git a/Demo/sockets/echosvr.py b/Demo/sockets/echosvr.py deleted file mode 100755 index 7de6391..0000000 --- a/Demo/sockets/echosvr.py +++ /dev/null @@ -1,31 +0,0 @@ -#! /usr/bin/env python - -# Python implementation of an 'echo' tcp server: echo all data it receives. -# -# This is the simplest possible server, servicing a single request only. - -import sys -from socket import * - -# The standard echo port isn't very useful, it requires root permissions! -# ECHO_PORT = 7 -ECHO_PORT = 50000 + 7 -BUFSIZE = 1024 - -def main(): - if len(sys.argv) > 1: - port = int(eval(sys.argv[1])) - else: - port = ECHO_PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - conn, (remotehost, remoteport) = s.accept() - print('connected by', remotehost, remoteport) - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - conn.send(data) - -main() diff --git a/Demo/sockets/finger.py b/Demo/sockets/finger.py deleted file mode 100755 index e8b9ed2..0000000 --- a/Demo/sockets/finger.py +++ /dev/null @@ -1,58 +0,0 @@ -#! /usr/bin/env python - -# Python interface to the Internet finger daemon. -# -# Usage: finger [options] [user][@host] ... -# -# If no host is given, the finger daemon on the local host is contacted. -# Options are passed uninterpreted to the finger daemon! - - -import sys, string -from socket import * - - -# Hardcode the number of the finger port here. -# It's not likely to change soon... -# -FINGER_PORT = 79 - - -# Function to do one remote finger invocation. -# Output goes directly to stdout (although this can be changed). -# -def finger(host, args): - s = socket(AF_INET, SOCK_STREAM) - s.connect((host, FINGER_PORT)) - s.send(args + '\n') - while 1: - buf = s.recv(1024) - if not buf: break - sys.stdout.write(buf) - sys.stdout.flush() - - -# Main function: argument parsing. -# -def main(): - options = '' - i = 1 - while i < len(sys.argv) and sys.argv[i][:1] == '-': - options = options + sys.argv[i] + ' ' - i = i+1 - args = sys.argv[i:] - if not args: - args = [''] - for arg in args: - if '@' in arg: - at = string.index(arg, '@') - host = arg[at+1:] - arg = arg[:at] - else: - host = '' - finger(host, options + arg) - - -# Call the main function. -# -main() diff --git a/Demo/sockets/ftp.py b/Demo/sockets/ftp.py deleted file mode 100755 index 5ea99c7..0000000 --- a/Demo/sockets/ftp.py +++ /dev/null @@ -1,152 +0,0 @@ -# A simple FTP client. -# -# The information to write this program was gathered from RFC 959, -# but this is not a complete implementation! Yet it shows how a simple -# FTP client can be built, and you are welcome to extend it to suit -# it to your needs... -# -# How it works (assuming you've read the RFC): -# -# User commands are passed uninterpreted to the server. However, the -# user never needs to send a PORT command. Rather, the client opens a -# port right away and sends the appropriate PORT command to the server. -# When a response code 150 is received, this port is used to receive -# the data (which is written to stdout in this version), and when the -# data is exhausted, a new port is opened and a corresponding PORT -# command sent. In order to avoid errors when reusing ports quickly -# (and because there is no s.getsockname() method in Python yet) we -# cycle through a number of ports in the 50000 range. - - -import sys, posix, string -from socket import * - - -BUFSIZE = 1024 - -# Default port numbers used by the FTP protocol. -# -FTP_PORT = 21 -FTP_DATA_PORT = FTP_PORT - 1 - -# Change the data port to something not needing root permissions. -# -FTP_DATA_PORT = FTP_DATA_PORT + 50000 - - -# Main program (called at the end of this file). -# -def main(): - hostname = sys.argv[1] - control(hostname) - - -# Control process (user interface and user protocol interpreter). -# -def control(hostname): - # - # Create control connection - # - s = socket(AF_INET, SOCK_STREAM) - s.connect((hostname, FTP_PORT)) - f = s.makefile('r') # Reading the replies is easier from a file... - # - # Control loop - # - r = None - while 1: - code = getreply(f) - if code in ('221', 'EOF'): break - if code == '150': - getdata(r) - code = getreply(f) - r = None - if not r: - r = newdataport(s, f) - cmd = getcommand() - if not cmd: break - s.send(cmd + '\r\n') - - -# Create a new data port and send a PORT command to the server for it. -# (Cycle through a number of ports to avoid problems with reusing -# a port within a short time.) -# -nextport = 0 -# -def newdataport(s, f): - global nextport - port = nextport + FTP_DATA_PORT - nextport = (nextport+1) % 16 - r = socket(AF_INET, SOCK_STREAM) - r.bind((gethostbyname(gethostname()), port)) - r.listen(1) - sendportcmd(s, f, port) - return r - - -# Send an appropriate port command. -# -def sendportcmd(s, f, port): - hostname = gethostname() - hostaddr = gethostbyname(hostname) - hbytes = string.splitfields(hostaddr, '.') - pbytes = [repr(port//256), repr(port%256)] - bytes = hbytes + pbytes - cmd = 'PORT ' + string.joinfields(bytes, ',') - s.send(cmd + '\r\n') - code = getreply(f) - - -# Process an ftp reply and return the 3-digit reply code (as a string). -# The reply should be a line of text starting with a 3-digit number. -# If the 4th char is '-', it is a multi-line reply and is -# terminate by a line starting with the same 3-digit number. -# Any text while receiving the reply is echoed to the file. -# -def getreply(f): - line = f.readline() - if not line: return 'EOF' - print(line, end=' ') - code = line[:3] - if line[3:4] == '-': - while 1: - line = f.readline() - if not line: break # Really an error - print(line, end=' ') - if line[:3] == code and line[3:4] != '-': break - return code - - -# Get the data from the data connection. -# -def getdata(r): - print('(accepting data connection)') - conn, host = r.accept() - print('(data connection accepted)') - while 1: - data = conn.recv(BUFSIZE) - if not data: break - sys.stdout.write(data) - print('(end of data connection)') - -def raw_input(prompt): - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() - -# Get a command from the user. -# -def getcommand(): - try: - while 1: - line = input('ftp.py> ') - if line: return line - except EOFError: - return '' - - -# Call the main program. -# -if __name__ == '__main__': - main() diff --git a/Demo/sockets/gopher.py b/Demo/sockets/gopher.py deleted file mode 100755 index c287319..0000000 --- a/Demo/sockets/gopher.py +++ /dev/null @@ -1,352 +0,0 @@ -#! /usr/bin/env python - -# A simple gopher client. -# -# Usage: gopher [ [selector] host [port] ] - -import sys -import os -import socket - -# Default selector, host and port -DEF_SELECTOR = '' -DEF_HOST = 'gopher.micro.umn.edu' -DEF_PORT = 70 - -# Recognized file types -T_TEXTFILE = '0' -T_MENU = '1' -T_CSO = '2' -T_ERROR = '3' -T_BINHEX = '4' -T_DOS = '5' -T_UUENCODE = '6' -T_SEARCH = '7' -T_TELNET = '8' -T_BINARY = '9' -T_REDUNDANT = '+' -T_SOUND = 's' - -# Dictionary mapping types to strings -typename = {'0': '<TEXT>', '1': '<DIR>', '2': '<CSO>', '3': '<ERROR>', \ - '4': '<BINHEX>', '5': '<DOS>', '6': '<UUENCODE>', '7': '<SEARCH>', \ - '8': '<TELNET>', '9': '<BINARY>', '+': '<REDUNDANT>', 's': '<SOUND>'} - -# Oft-used characters and strings -CRLF = '\r\n' -TAB = '\t' - -# Open a TCP connection to a given host and port -def open_socket(host, port): - if not port: - port = DEF_PORT - elif type(port) == type(''): - port = int(port) - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((host, port)) - return s - -# Send a selector to a given host and port, return a file with the reply -def send_request(selector, host, port): - s = open_socket(host, port) - s.send(selector + CRLF) - s.shutdown(1) - return s.makefile('r') - -# Get a menu in the form of a list of entries -def get_menu(selector, host, port): - f = send_request(selector, host, port) - list = [] - while 1: - line = f.readline() - if not line: - print('(Unexpected EOF from server)') - break - if line[-2:] == CRLF: - line = line[:-2] - elif line[-1:] in CRLF: - line = line[:-1] - if line == '.': - break - if not line: - print('(Empty line from server)') - continue - typechar = line[0] - parts = line[1:].split(TAB) - if len(parts) < 4: - print('(Bad line from server: %r)' % (line,)) - continue - if len(parts) > 4: - print('(Extra info from server: %r)' % (parts[4:],)) - parts.insert(0, typechar) - list.append(parts) - f.close() - return list - -# Get a text file as a list of lines, with trailing CRLF stripped -def get_textfile(selector, host, port): - list = [] - get_alt_textfile(selector, host, port, list.append) - return list - -# Get a text file and pass each line to a function, with trailing CRLF stripped -def get_alt_textfile(selector, host, port, func): - f = send_request(selector, host, port) - while 1: - line = f.readline() - if not line: - print('(Unexpected EOF from server)') - break - if line[-2:] == CRLF: - line = line[:-2] - elif line[-1:] in CRLF: - line = line[:-1] - if line == '.': - break - if line[:2] == '..': - line = line[1:] - func(line) - f.close() - -# Get a binary file as one solid data block -def get_binary(selector, host, port): - f = send_request(selector, host, port) - data = f.read() - f.close() - return data - -# Get a binary file and pass each block to a function -def get_alt_binary(selector, host, port, func, blocksize): - f = send_request(selector, host, port) - while 1: - data = f.read(blocksize) - if not data: - break - func(data) - -# A *very* simple interactive browser - -# Browser main command, has default arguments -def browser(*args): - selector = DEF_SELECTOR - host = DEF_HOST - port = DEF_PORT - n = len(args) - if n > 0 and args[0]: - selector = args[0] - if n > 1 and args[1]: - host = args[1] - if n > 2 and args[2]: - port = args[2] - if n > 3: - raise RuntimeError('too many args') - try: - browse_menu(selector, host, port) - except socket.error as msg: - print('Socket error:', msg) - sys.exit(1) - except KeyboardInterrupt: - print('\n[Goodbye]') - -# Browse a menu -def browse_menu(selector, host, port): - list = get_menu(selector, host, port) - while 1: - print('----- MENU -----') - print('Selector:', repr(selector)) - print('Host:', host, ' Port:', port) - print() - for i in range(len(list)): - item = list[i] - typechar, description = item[0], item[1] - print(repr(i+1).rjust(3) + ':', description, end=' ') - if typechar in typename: - print(typename[typechar]) - else: - print('<TYPE=' + repr(typechar) + '>') - print() - while 1: - try: - str = input('Choice [CR == up a level]: ') - except EOFError: - print() - return - if not str: - return - try: - choice = int(str) - except ValueError: - print('Choice must be a number; try again:') - continue - if not 0 < choice <= len(list): - print('Choice out of range; try again:') - continue - break - item = list[choice-1] - typechar = item[0] - [i_selector, i_host, i_port] = item[2:5] - if typechar in typebrowser: - browserfunc = typebrowser[typechar] - try: - browserfunc(i_selector, i_host, i_port) - except (IOError, socket.error): - t, v, tb = sys.exc_info() - print('***', t, ':', v) - else: - print('Unsupported object type') - -# Browse a text file -def browse_textfile(selector, host, port): - x = None - try: - p = os.popen('${PAGER-more}', 'w') - x = SaveLines(p) - get_alt_textfile(selector, host, port, x.writeln) - except IOError as msg: - print('IOError:', msg) - if x: - x.close() - f = open_savefile() - if not f: - return - x = SaveLines(f) - try: - get_alt_textfile(selector, host, port, x.writeln) - print('Done.') - except IOError as msg: - print('IOError:', msg) - x.close() - -def raw_input(prompt): - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() - -# Browse a search index -def browse_search(selector, host, port): - while 1: - print('----- SEARCH -----') - print('Selector:', repr(selector)) - print('Host:', host, ' Port:', port) - print() - try: - query = input('Query [CR == up a level]: ') - except EOFError: - print() - break - query = query.strip() - if not query: - break - if '\t' in query: - print('Sorry, queries cannot contain tabs') - continue - browse_menu(selector + TAB + query, host, port) - -# "Browse" telnet-based information, i.e. open a telnet session -def browse_telnet(selector, host, port): - if selector: - print('Log in as', repr(selector)) - if type(port) != type(''): - port = repr(port) - sts = os.system('set -x; exec telnet ' + host + ' ' + port) - if sts: - print('Exit status:', sts) - -# "Browse" a binary file, i.e. save it to a file -def browse_binary(selector, host, port): - f = open_savefile() - if not f: - return - x = SaveWithProgress(f) - get_alt_binary(selector, host, port, x.write, 8*1024) - x.close() - -# "Browse" a sound file, i.e. play it or save it -def browse_sound(selector, host, port): - browse_binary(selector, host, port) - -# Dictionary mapping types to browser functions -typebrowser = {'0': browse_textfile, '1': browse_menu, \ - '4': browse_binary, '5': browse_binary, '6': browse_textfile, \ - '7': browse_search, \ - '8': browse_telnet, '9': browse_binary, 's': browse_sound} - -# Class used to save lines, appending a newline to each line -class SaveLines: - def __init__(self, f): - self.f = f - def writeln(self, line): - self.f.write(line + '\n') - def close(self): - sts = self.f.close() - if sts: - print('Exit status:', sts) - -# Class used to save data while showing progress -class SaveWithProgress: - def __init__(self, f): - self.f = f - def write(self, data): - sys.stdout.write('#') - sys.stdout.flush() - self.f.write(data) - def close(self): - print() - sts = self.f.close() - if sts: - print('Exit status:', sts) - -# Ask for and open a save file, or return None if not to save -def open_savefile(): - try: - savefile = input( \ - 'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ') - except EOFError: - print() - return None - savefile = savefile.strip() - if not savefile: - return None - if savefile[0] == '|': - cmd = savefile[1:].strip() - try: - p = os.popen(cmd, 'w') - except IOError as msg: - print(repr(cmd), ':', msg) - return None - print('Piping through', repr(cmd), '...') - return p - if savefile[0] == '~': - savefile = os.path.expanduser(savefile) - try: - f = open(savefile, 'w') - except IOError as msg: - print(repr(savefile), ':', msg) - return None - print('Saving to', repr(savefile), '...') - return f - -# Test program -def test(): - if sys.argv[4:]: - print('usage: gopher [ [selector] host [port] ]') - sys.exit(2) - elif sys.argv[3:]: - browser(sys.argv[1], sys.argv[2], sys.argv[3]) - elif sys.argv[2:]: - try: - port = int(sys.argv[2]) - selector = '' - host = sys.argv[1] - except ValueError: - selector = sys.argv[1] - host = sys.argv[2] - port = '' - browser(selector, host, port) - elif sys.argv[1:]: - browser('', sys.argv[1]) - else: - browser() - -# Call the test program as a main program -test() diff --git a/Demo/sockets/mcast.py b/Demo/sockets/mcast.py deleted file mode 100755 index b7f8556..0000000 --- a/Demo/sockets/mcast.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python -# -# Send/receive UDP multicast packets. -# Requires that your OS kernel supports IP multicast. -# -# Usage: -# mcast -s (sender, IPv4) -# mcast -s -6 (sender, IPv6) -# mcast (receivers, IPv4) -# mcast -6 (receivers, IPv6) - -MYPORT = 8123 -MYGROUP_4 = '225.0.0.250' -MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173' -MYTTL = 1 # Increase to reach other networks - -import time -import struct -import socket -import sys - -def main(): - group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4 - - if "-s" in sys.argv[1:]: - sender(group) - else: - receiver(group) - - -def sender(group): - addrinfo = socket.getaddrinfo(group, None)[0] - - s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) - - # Set Time-to-live (optional) - ttl_bin = struct.pack('@i', MYTTL) - if addrinfo[0] == socket.AF_INET: # IPv4 - s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin) - else: - s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin) - - while True: - data = repr(time.time()).encode('utf-8') + b'\0' - s.sendto(data, (addrinfo[4][0], MYPORT)) - time.sleep(1) - - -def receiver(group): - # Look up multicast group address in name server and find out IP version - addrinfo = socket.getaddrinfo(group, None)[0] - - # Create a socket - s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) - - # Allow multiple copies of this program on one machine - # (not strictly needed) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - # Bind it to the port - s.bind(('', MYPORT)) - - group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) - # Join group - if addrinfo[0] == socket.AF_INET: # IPv4 - mreq = group_bin + struct.pack('=I', socket.INADDR_ANY) - s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - else: - mreq = group_bin + struct.pack('@I', 0) - s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) - - # Loop, printing any data we receive - while True: - data, sender = s.recvfrom(1500) - while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's - print(str(sender) + ' ' + repr(data)) - - -if __name__ == '__main__': - main() diff --git a/Demo/sockets/radio.py b/Demo/sockets/radio.py deleted file mode 100755 index fa4ce75..0000000 --- a/Demo/sockets/radio.py +++ /dev/null @@ -1,14 +0,0 @@ -# Receive UDP packets transmitted by a broadcasting service - -MYPORT = 50000 - -import sys -from socket import * - -s = socket(AF_INET, SOCK_DGRAM) -s.bind(('', MYPORT)) - -while 1: - data, wherefrom = s.recvfrom(1500, 0) - sys.stderr.write(repr(wherefrom) + '\n') - sys.stdout.write(data) diff --git a/Demo/sockets/rpython.py b/Demo/sockets/rpython.py deleted file mode 100755 index b654dc2..0000000 --- a/Demo/sockets/rpython.py +++ /dev/null @@ -1,35 +0,0 @@ -#! /usr/bin/env python - -# Remote python client. -# Execute Python commands remotely and send output back. - -import sys -import string -from socket import * - -PORT = 4127 -BUFSIZE = 1024 - -def main(): - if len(sys.argv) < 3: - print("usage: rpython host command") - sys.exit(2) - host = sys.argv[1] - port = PORT - i = string.find(host, ':') - if i >= 0: - port = string.atoi(port[i+1:]) - host = host[:i] - command = string.join(sys.argv[2:]) - s = socket(AF_INET, SOCK_STREAM) - s.connect((host, port)) - s.send(command) - s.shutdown(1) - reply = '' - while 1: - data = s.recv(BUFSIZE) - if not data: break - reply = reply + data - print(reply, end=' ') - -main() diff --git a/Demo/sockets/rpythond.py b/Demo/sockets/rpythond.py deleted file mode 100755 index d745cc7..0000000 --- a/Demo/sockets/rpythond.py +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env python - -# Remote python server. -# Execute Python commands remotely and send output back. -# WARNING: This version has a gaping security hole -- it accepts requests -# from any host on the Internet! - -import sys -from socket import * -import io -import traceback - -PORT = 4127 -BUFSIZE = 1024 - -def main(): - if len(sys.argv) > 1: - port = int(eval(sys.argv[1])) - else: - port = PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - while 1: - conn, (remotehost, remoteport) = s.accept() - print('connected by', remotehost, remoteport) - request = '' - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - request = request + data - reply = execute(request) - conn.send(reply) - conn.close() - -def execute(request): - stdout = sys.stdout - stderr = sys.stderr - sys.stdout = sys.stderr = fakefile = io.StringIO() - try: - try: - exec(request, {}, {}) - except: - print() - traceback.print_exc(100) - finally: - sys.stderr = stderr - sys.stdout = stdout - return fakefile.getvalue() - -main() diff --git a/Demo/sockets/telnet.py b/Demo/sockets/telnet.py deleted file mode 100755 index 038036ff..0000000 --- a/Demo/sockets/telnet.py +++ /dev/null @@ -1,109 +0,0 @@ -#! /usr/bin/env python - -# Minimal interface to the Internet telnet protocol. -# -# It refuses all telnet options and does not recognize any of the other -# telnet commands, but can still be used to connect in line-by-line mode. -# It's also useful to play with a number of other services, -# like time, finger, smtp and even ftp. -# -# Usage: telnet host [port] -# -# The port may be a service name or a decimal port number; -# it defaults to 'telnet'. - - -import sys, posix, time -from socket import * - -BUFSIZE = 1024 - -# Telnet protocol characters - -IAC = chr(255) # Interpret as command -DONT = chr(254) -DO = chr(253) -WONT = chr(252) -WILL = chr(251) - -def main(): - host = sys.argv[1] - try: - hostaddr = gethostbyname(host) - except error: - sys.stderr.write(sys.argv[1] + ': bad host name\n') - sys.exit(2) - # - if len(sys.argv) > 2: - servname = sys.argv[2] - else: - servname = 'telnet' - # - if '0' <= servname[:1] <= '9': - port = eval(servname) - else: - try: - port = getservbyname(servname, 'tcp') - except error: - sys.stderr.write(servname + ': bad tcp service name\n') - sys.exit(2) - # - s = socket(AF_INET, SOCK_STREAM) - # - try: - s.connect((host, port)) - except error as msg: - sys.stderr.write('connect failed: ' + repr(msg) + '\n') - sys.exit(1) - # - pid = posix.fork() - # - if pid == 0: - # child -- read stdin, write socket - while 1: - line = sys.stdin.readline() - s.send(line) - else: - # parent -- read socket, write stdout - iac = 0 # Interpret next char as command - opt = '' # Interpret next char as option - while 1: - data = s.recv(BUFSIZE) - if not data: - # EOF; kill child and exit - sys.stderr.write( '(Closed by remote host)\n') - posix.kill(pid, 9) - sys.exit(1) - cleandata = '' - for c in data: - if opt: - print(ord(c)) - s.send(opt + c) - opt = '' - elif iac: - iac = 0 - if c == IAC: - cleandata = cleandata + c - elif c in (DO, DONT): - if c == DO: print('(DO)', end=' ') - else: print('(DONT)', end=' ') - opt = IAC + WONT - elif c in (WILL, WONT): - if c == WILL: print('(WILL)', end=' ') - else: print('(WONT)', end=' ') - opt = IAC + DONT - else: - print('(command)', ord(c)) - elif c == IAC: - iac = 1 - print('(IAC)', end=' ') - else: - cleandata = cleandata + c - sys.stdout.write(cleandata) - sys.stdout.flush() - - -try: - main() -except KeyboardInterrupt: - pass diff --git a/Demo/sockets/throughput.py b/Demo/sockets/throughput.py deleted file mode 100755 index 64244aa..0000000 --- a/Demo/sockets/throughput.py +++ /dev/null @@ -1,93 +0,0 @@ -#! /usr/bin/env python - -# Test network throughput. -# -# Usage: -# 1) on host_A: throughput -s [port] # start a server -# 2) on host_B: throughput -c count host_A [port] # start a client -# -# The server will service multiple clients until it is killed. -# -# The client performs one transfer of count*BUFSIZE bytes and -# measures the time it takes (roundtrip!). - - -import sys, time -from socket import * - -MY_PORT = 50000 + 42 - -BUFSIZE = 1024 - - -def main(): - if len(sys.argv) < 2: - usage() - if sys.argv[1] == '-s': - server() - elif sys.argv[1] == '-c': - client() - else: - usage() - - -def usage(): - sys.stdout = sys.stderr - print('Usage: (on host_A) throughput -s [port]') - print('and then: (on host_B) throughput -c count host_A [port]') - sys.exit(2) - - -def server(): - if len(sys.argv) > 2: - port = eval(sys.argv[2]) - else: - port = MY_PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - print('Server ready...') - while 1: - conn, (host, remoteport) = s.accept() - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - del data - conn.send('OK\n') - conn.close() - print('Done with', host, 'port', remoteport) - - -def client(): - if len(sys.argv) < 4: - usage() - count = int(eval(sys.argv[2])) - host = sys.argv[3] - if len(sys.argv) > 4: - port = eval(sys.argv[4]) - else: - port = MY_PORT - testdata = 'x' * (BUFSIZE-1) + '\n' - t1 = time.time() - s = socket(AF_INET, SOCK_STREAM) - t2 = time.time() - s.connect((host, port)) - t3 = time.time() - i = 0 - while i < count: - i = i+1 - s.send(testdata) - s.shutdown(1) # Send EOF - t4 = time.time() - data = s.recv(BUFSIZE) - t5 = time.time() - print(data) - print('Raw timers:', t1, t2, t3, t4, t5) - print('Intervals:', t2-t1, t3-t2, t4-t3, t5-t4) - print('Total:', t5-t1) - print('Throughput:', round((BUFSIZE*count*0.001) / (t5-t1), 3), end=' ') - print('K/sec.') - - -main() diff --git a/Demo/sockets/udpecho.py b/Demo/sockets/udpecho.py deleted file mode 100755 index 9966fd8..0000000 --- a/Demo/sockets/udpecho.py +++ /dev/null @@ -1,64 +0,0 @@ -#! /usr/bin/env python - -# Client and server for udp (datagram) echo. -# -# Usage: udpecho -s [port] (to start a server) -# or: udpecho -c host [port] <file (client) - -import sys -from socket import * - -ECHO_PORT = 50000 + 7 -BUFSIZE = 1024 - -def main(): - if len(sys.argv) < 2: - usage() - if sys.argv[1] == '-s': - server() - elif sys.argv[1] == '-c': - client() - else: - usage() - -def usage(): - sys.stdout = sys.stderr - print('Usage: udpecho -s [port] (server)') - print('or: udpecho -c host [port] <file (client)') - sys.exit(2) - -def server(): - if len(sys.argv) > 2: - port = eval(sys.argv[2]) - else: - port = ECHO_PORT - s = socket(AF_INET, SOCK_DGRAM) - s.bind(('', port)) - print('udp echo server ready') - while 1: - data, addr = s.recvfrom(BUFSIZE) - print('server received %r from %r' % (data, addr)) - s.sendto(data, addr) - -def client(): - if len(sys.argv) < 3: - usage() - host = sys.argv[2] - if len(sys.argv) > 3: - port = eval(sys.argv[3]) - else: - port = ECHO_PORT - addr = host, port - s = socket(AF_INET, SOCK_DGRAM) - s.bind(('', 0)) - print('udp echo client ready, reading stdin') - while 1: - line = sys.stdin.readline() - if not line: - break - print('addr = ', addr) - s.sendto(bytes(line, 'ascii'), addr) - data, fromaddr = s.recvfrom(BUFSIZE) - print('client received %r from %r' % (data, fromaddr)) - -main() diff --git a/Demo/sockets/unicast.py b/Demo/sockets/unicast.py deleted file mode 100644 index dd15e3c..0000000 --- a/Demo/sockets/unicast.py +++ /dev/null @@ -1,14 +0,0 @@ -# Send UDP broadcast packets - -MYPORT = 50000 - -import sys, time -from socket import * - -s = socket(AF_INET, SOCK_DGRAM) -s.bind(('', 0)) - -while 1: - data = repr(time.time()) + '\n' - s.sendto(data, ('', MYPORT)) - time.sleep(2) diff --git a/Demo/sockets/unixclient.py b/Demo/sockets/unixclient.py deleted file mode 100644 index 5e87eed..0000000 --- a/Demo/sockets/unixclient.py +++ /dev/null @@ -1,12 +0,0 @@ -# Echo client demo using Unix sockets -# Piet van Oostrum - -from socket import * - -FILE = 'unix-socket' -s = socket(AF_UNIX, SOCK_STREAM) -s.connect(FILE) -s.send(b'Hello, world') -data = s.recv(1024) -s.close() -print('Received', repr(data)) diff --git a/Demo/sockets/unixserver.py b/Demo/sockets/unixserver.py deleted file mode 100644 index c3c9c4f..0000000 --- a/Demo/sockets/unixserver.py +++ /dev/null @@ -1,24 +0,0 @@ -# Echo server demo using Unix sockets (handles one connection only) -# Piet van Oostrum - -import os -from socket import * - -FILE = 'unix-socket' -s = socket(AF_UNIX, SOCK_STREAM) -s.bind(FILE) - -print('Sock name is: ['+s.getsockname()+']') - -# Wait for a connection -s.listen(1) -conn, addr = s.accept() - -while True: - data = conn.recv(1024) - if not data: - break - conn.send(data) - -conn.close() -os.unlink(FILE) diff --git a/Demo/threads/Coroutine.py b/Demo/threads/Coroutine.py deleted file mode 100644 index 690fadc..0000000 --- a/Demo/threads/Coroutine.py +++ /dev/null @@ -1,159 +0,0 @@ -# Coroutine implementation using Python threads. -# -# Combines ideas from Guido's Generator module, and from the coroutine -# features of Icon and Simula 67. -# -# To run a collection of functions as coroutines, you need to create -# a Coroutine object to control them: -# co = Coroutine() -# and then 'create' a subsidiary object for each function in the -# collection: -# cof1 = co.create(f1 [, arg1, arg2, ...]) # [] means optional, -# cof2 = co.create(f2 [, arg1, arg2, ...]) #... not list -# cof3 = co.create(f3 [, arg1, arg2, ...]) -# etc. The functions need not be distinct; 'create'ing the same -# function multiple times gives you independent instances of the -# function. -# -# To start the coroutines running, use co.tran on one of the create'd -# functions; e.g., co.tran(cof2). The routine that first executes -# co.tran is called the "main coroutine". It's special in several -# respects: it existed before you created the Coroutine object; if any of -# the create'd coroutines exits (does a return, or suffers an unhandled -# exception), EarlyExit error is raised in the main coroutine; and the -# co.detach() method transfers control directly to the main coroutine -# (you can't use co.tran() for this because the main coroutine doesn't -# have a name ...). -# -# Coroutine objects support these methods: -# -# handle = .create(func [, arg1, arg2, ...]) -# Creates a coroutine for an invocation of func(arg1, arg2, ...), -# and returns a handle ("name") for the coroutine so created. The -# handle can be used as the target in a subsequent .tran(). -# -# .tran(target, data=None) -# Transfer control to the create'd coroutine "target", optionally -# passing it an arbitrary piece of data. To the coroutine A that does -# the .tran, .tran acts like an ordinary function call: another -# coroutine B can .tran back to it later, and if it does A's .tran -# returns the 'data' argument passed to B's tran. E.g., -# -# in coroutine coA in coroutine coC in coroutine coB -# x = co.tran(coC) co.tran(coB) co.tran(coA,12) -# print x # 12 -# -# The data-passing feature is taken from Icon, and greatly cuts -# the need to use global variables for inter-coroutine communication. -# -# .back( data=None ) -# The same as .tran(invoker, data=None), where 'invoker' is the -# coroutine that most recently .tran'ed control to the coroutine -# doing the .back. This is akin to Icon's "&source". -# -# .detach( data=None ) -# The same as .tran(main, data=None), where 'main' is the -# (unnameable!) coroutine that started it all. 'main' has all the -# rights of any other coroutine: upon receiving control, it can -# .tran to an arbitrary coroutine of its choosing, go .back to -# the .detach'er, or .kill the whole thing. -# -# .kill() -# Destroy all the coroutines, and return control to the main -# coroutine. None of the create'ed coroutines can be resumed after a -# .kill(). An EarlyExit exception does a .kill() automatically. It's -# a good idea to .kill() coroutines you're done with, since the -# current implementation consumes a thread for each coroutine that -# may be resumed. - -import _thread as thread -import sync - -class _CoEvent: - def __init__(self, func): - self.f = func - self.e = sync.event() - - def __repr__(self): - if self.f is None: - return 'main coroutine' - else: - return 'coroutine for func ' + self.f.__name__ - - def __hash__(self): - return id(self) - - def __cmp__(x,y): - return cmp(id(x), id(y)) - - def resume(self): - self.e.post() - - def wait(self): - self.e.wait() - self.e.clear() - -class Killed(Exception): pass -class EarlyExit(Exception): pass - -class Coroutine: - def __init__(self): - self.active = self.main = _CoEvent(None) - self.invokedby = {self.main: None} - self.killed = 0 - self.value = None - self.terminated_by = None - - def create(self, func, *args): - me = _CoEvent(func) - self.invokedby[me] = None - thread.start_new_thread(self._start, (me,) + args) - return me - - def _start(self, me, *args): - me.wait() - if not self.killed: - try: - try: - me.f(*args) - except Killed: - pass - finally: - if not self.killed: - self.terminated_by = me - self.kill() - - def kill(self): - if self.killed: - raise TypeError('kill() called on dead coroutines') - self.killed = 1 - for coroutine in self.invokedby.keys(): - coroutine.resume() - - def back(self, data=None): - return self.tran( self.invokedby[self.active], data ) - - def detach(self, data=None): - return self.tran( self.main, data ) - - def tran(self, target, data=None): - if target not in self.invokedby: - raise TypeError('.tran target %r is not an active coroutine' % (target,)) - if self.killed: - raise TypeError('.tran target %r is killed' % (target,)) - self.value = data - me = self.active - self.invokedby[target] = me - self.active = target - target.resume() - - me.wait() - if self.killed: - if self.main is not me: - raise Killed - if self.terminated_by is not None: - raise EarlyExit('%r terminated early' % (self.terminated_by,)) - - return self.value - -# end of module diff --git a/Demo/threads/Generator.py b/Demo/threads/Generator.py deleted file mode 100644 index 3a2963f..0000000 --- a/Demo/threads/Generator.py +++ /dev/null @@ -1,92 +0,0 @@ -# Generator implementation using threads - -import _thread as thread -import sys - -class Killed(Exception): - pass - -class Generator: - # Constructor - def __init__(self, func, args): - self.getlock = thread.allocate_lock() - self.putlock = thread.allocate_lock() - self.getlock.acquire() - self.putlock.acquire() - self.func = func - self.args = args - self.done = 0 - self.killed = 0 - thread.start_new_thread(self._start, ()) - - # Internal routine - def _start(self): - try: - self.putlock.acquire() - if not self.killed: - try: - self.func(self, *self.args) - except Killed: - pass - finally: - if not self.killed: - self.done = 1 - self.getlock.release() - - # Called by producer for each value; raise Killed if no more needed - def put(self, value): - if self.killed: - raise TypeError('put() called on killed generator') - self.value = value - self.getlock.release() # Resume consumer thread - self.putlock.acquire() # Wait for next get() call - if self.killed: - raise Killed - - # Called by producer to get next value; raise EOFError if no more - def get(self): - if self.killed: - raise TypeError('get() called on killed generator') - self.putlock.release() # Resume producer thread - self.getlock.acquire() # Wait for value to appear - if self.done: - raise EOFError # Say there are no more values - return self.value - - # Called by consumer if no more values wanted - def kill(self): - if self.killed: - raise TypeError('kill() called on killed generator') - self.killed = 1 - self.putlock.release() - - # Clone constructor - def clone(self): - return Generator(self.func, self.args) - -def pi(g): - k, a, b, a1, b1 = 2, 4, 1, 12, 4 - while 1: - # 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 - # Print common digits - d, d1 = a//b, a1//b1 - while d == d1: - g.put(int(d)) - a, a1 = 10*(a%b), 10*(a1%b1) - d, d1 = a//b, a1//b1 - -def test(): - g = Generator(pi, ()) - g.kill() - g = Generator(pi, ()) - for i in range(10): print(g.get(), end=' ') - print() - h = g.clone() - g.kill() - while 1: - print(h.get(), end=' ') - sys.stdout.flush() - -test() diff --git a/Demo/threads/README b/Demo/threads/README deleted file mode 100644 index a379521..0000000 --- a/Demo/threads/README +++ /dev/null @@ -1,11 +0,0 @@ -This directory contains some demonstrations of the thread module. - -These are mostly "proof of concept" type applications: - -Generator.py Generator class implemented with threads. -sync.py Condition variables primitives by Tim Peters. -telnet.py Version of ../sockets/telnet.py using threads. - -Coroutine.py Coroutines using threads, by Tim Peters (22 May 94) -fcmp.py Example of above, by Tim -squasher.py Another example of above, also by Tim diff --git a/Demo/threads/fcmp.py b/Demo/threads/fcmp.py deleted file mode 100644 index bc2e3ed..0000000 --- a/Demo/threads/fcmp.py +++ /dev/null @@ -1,64 +0,0 @@ -# Coroutine example: controlling multiple instances of a single function - -from Coroutine import * - -# fringe visits a nested list in inorder, and detaches for each non-list -# element; raises EarlyExit after the list is exhausted -def fringe(co, list): - for x in list: - if type(x) is type([]): - fringe(co, x) - else: - co.back(x) - -def printinorder(list): - co = Coroutine() - f = co.create(fringe, co, list) - try: - while 1: - print(co.tran(f), end=' ') - except EarlyExit: - pass - print() - -printinorder([1,2,3]) # 1 2 3 -printinorder([[[[1,[2]]],3]]) # ditto -x = [0, 1, [2, [3]], [4,5], [[[6]]] ] -printinorder(x) # 0 1 2 3 4 5 6 - -# fcmp lexicographically compares the fringes of two nested lists -def fcmp(l1, l2): - co1 = Coroutine(); f1 = co1.create(fringe, co1, l1) - co2 = Coroutine(); f2 = co2.create(fringe, co2, l2) - while 1: - try: - v1 = co1.tran(f1) - except EarlyExit: - try: - v2 = co2.tran(f2) - except EarlyExit: - return 0 - co2.kill() - return -1 - try: - v2 = co2.tran(f2) - except EarlyExit: - co1.kill() - return 1 - if v1 != v2: - co1.kill(); co2.kill() - return cmp(v1,v2) - -print(fcmp(range(7), x)) # 0; fringes are equal -print(fcmp(range(6), x)) # -1; 1st list ends early -print(fcmp(x, range(6))) # 1; 2nd list ends early -print(fcmp(range(8), x)) # 1; 2nd list ends early -print(fcmp(x, range(8))) # -1; 1st list ends early -print(fcmp([1,[[2],8]], - [[[1],2],8])) # 0 -print(fcmp([1,[[3],8]], - [[[1],2],8])) # 1 -print(fcmp([1,[[2],8]], - [[[1],2],9])) # -1 - -# end of example diff --git a/Demo/threads/find.py b/Demo/threads/find.py deleted file mode 100644 index 2b4ef7d..0000000 --- a/Demo/threads/find.py +++ /dev/null @@ -1,154 +0,0 @@ -# A parallelized "find(1)" using the thread module. - -# This demonstrates the use of a work queue and worker threads. -# It really does do more stats/sec when using multiple threads, -# although the improvement is only about 20-30 percent. -# (That was 8 years ago. In 2002, on Linux, I can't measure -# a speedup. :-( ) - -# I'm too lazy to write a command line parser for the full find(1) -# command line syntax, so the predicate it searches for is wired-in, -# see function selector() below. (It currently searches for files with -# world write permission.) - -# Usage: parfind.py [-w nworkers] [directory] ... -# Default nworkers is 4 - - -import sys -import getopt -import time -import os -from stat import * -import _thread as thread - - -# Work queue class. Usage: -# wq = WorkQ() -# wq.addwork(func, (arg1, arg2, ...)) # one or more calls -# wq.run(nworkers) -# The work is done when wq.run() completes. -# The function calls executed by the workers may add more work. -# Don't use keyboard interrupts! - -class WorkQ: - - # Invariants: - - # - busy and work are only modified when mutex is locked - # - len(work) is the number of jobs ready to be taken - # - busy is the number of jobs being done - # - todo is locked iff there is no work and somebody is busy - - def __init__(self): - self.mutex = thread.allocate() - self.todo = thread.allocate() - self.todo.acquire() - self.work = [] - self.busy = 0 - - def addwork(self, func, args): - job = (func, args) - self.mutex.acquire() - self.work.append(job) - self.mutex.release() - if len(self.work) == 1: - self.todo.release() - - def _getwork(self): - self.todo.acquire() - self.mutex.acquire() - if self.busy == 0 and len(self.work) == 0: - self.mutex.release() - self.todo.release() - return None - job = self.work[0] - del self.work[0] - self.busy = self.busy + 1 - self.mutex.release() - if len(self.work) > 0: - self.todo.release() - return job - - def _donework(self): - self.mutex.acquire() - self.busy = self.busy - 1 - if self.busy == 0 and len(self.work) == 0: - self.todo.release() - self.mutex.release() - - def _worker(self): - time.sleep(0.00001) # Let other threads run - while 1: - job = self._getwork() - if not job: - break - func, args = job - func(*args) - self._donework() - - def run(self, nworkers): - if not self.work: - return # Nothing to do - for i in range(nworkers-1): - thread.start_new(self._worker, ()) - self._worker() - self.todo.acquire() - - -# Main program - -def main(): - nworkers = 4 - opts, args = getopt.getopt(sys.argv[1:], '-w:') - for opt, arg in opts: - if opt == '-w': - nworkers = int(arg) - if not args: - args = [os.curdir] - - wq = WorkQ() - for dir in args: - wq.addwork(find, (dir, selector, wq)) - - t1 = time.time() - wq.run(nworkers) - t2 = time.time() - - sys.stderr.write('Total time %r sec.\n' % (t2-t1)) - - -# The predicate -- defines what files we look for. -# Feel free to change this to suit your purpose - -def selector(dir, name, fullname, stat): - # Look for world writable files that are not symlinks - return (stat[ST_MODE] & 0o002) != 0 and not S_ISLNK(stat[ST_MODE]) - - -# The find procedure -- calls wq.addwork() for subdirectories - -def find(dir, pred, wq): - try: - names = os.listdir(dir) - except os.error as msg: - print(repr(dir), ':', msg) - return - for name in names: - if name not in (os.curdir, os.pardir): - fullname = os.path.join(dir, name) - try: - stat = os.lstat(fullname) - except os.error as msg: - print(repr(fullname), ':', msg) - continue - if pred(dir, name, fullname, stat): - print(fullname) - if S_ISDIR(stat[ST_MODE]): - if not os.path.ismount(fullname): - wq.addwork(find, (fullname, pred, wq)) - - -# Call the main program - -main() diff --git a/Demo/threads/squasher.py b/Demo/threads/squasher.py deleted file mode 100644 index 35b1b1d..0000000 --- a/Demo/threads/squasher.py +++ /dev/null @@ -1,105 +0,0 @@ -# Coroutine example: general coroutine transfers -# -# The program is a variation of a Simula 67 program due to Dahl & Hoare, -# (Dahl/Dijkstra/Hoare, Structured Programming; Academic Press, 1972) -# who in turn credit the original example to Conway. -# -# We have a number of input lines, terminated by a 0 byte. The problem -# is to squash them together into output lines containing 72 characters -# each. A semicolon must be added between input lines. Runs of blanks -# and tabs in input lines must be squashed into single blanks. -# Occurrences of "**" in input lines must be replaced by "^". -# -# Here's a test case: - -test = """\ - d = sqrt(b**2 - 4*a*c) -twoa = 2*a - L = -b/twoa - R = d/twoa - A1 = L + R - A2 = L - R\0 -""" - -# The program should print: - -# d = sqrt(b^2 - 4*a*c);twoa = 2*a; L = -b/twoa; R = d/twoa; A1 = L + R; -#A2 = L - R -#done - -# getline: delivers the next input line to its invoker -# disassembler: grabs input lines from getline, and delivers them one -# character at a time to squasher, also inserting a semicolon into -# the stream between lines -# squasher: grabs characters from disassembler and passes them on to -# assembler, first replacing "**" with "^" and squashing runs of -# whitespace -# assembler: grabs characters from squasher and packs them into lines -# with 72 character each, delivering each such line to putline; -# when it sees a null byte, passes the last line to putline and -# then kills all the coroutines -# putline: grabs lines from assembler, and just prints them - -from Coroutine import * - -def getline(text): - for line in string.splitfields(text, '\n'): - co.tran(codisassembler, line) - -def disassembler(): - while 1: - card = co.tran(cogetline) - for i in range(len(card)): - co.tran(cosquasher, card[i]) - co.tran(cosquasher, ';') - -def squasher(): - while 1: - ch = co.tran(codisassembler) - if ch == '*': - ch2 = co.tran(codisassembler) - if ch2 == '*': - ch = '^' - else: - co.tran(coassembler, ch) - ch = ch2 - if ch in ' \t': - while 1: - ch2 = co.tran(codisassembler) - if ch2 not in ' \t': - break - co.tran(coassembler, ' ') - ch = ch2 - co.tran(coassembler, ch) - -def assembler(): - line = '' - while 1: - ch = co.tran(cosquasher) - if ch == '\0': - break - if len(line) == 72: - co.tran(coputline, line) - line = '' - line = line + ch - line = line + ' ' * (72 - len(line)) - co.tran(coputline, line) - co.kill() - -def putline(): - while 1: - line = co.tran(coassembler) - print(line) - -import string -co = Coroutine() -cogetline = co.create(getline, test) -coputline = co.create(putline) -coassembler = co.create(assembler) -codisassembler = co.create(disassembler) -cosquasher = co.create(squasher) - -co.tran(coputline) -print('done') - -# end of example diff --git a/Demo/threads/sync.py b/Demo/threads/sync.py deleted file mode 100644 index 90fff2e..0000000 --- a/Demo/threads/sync.py +++ /dev/null @@ -1,599 +0,0 @@ -# Defines classes that provide synchronization objects. Note that use of -# this module requires that your Python support threads. -# -# condition(lock=None) # a POSIX-like condition-variable object -# barrier(n) # an n-thread barrier -# event() # an event object -# semaphore(n=1) # a semaphore object, with initial count n -# mrsw() # a multiple-reader single-writer lock -# -# CONDITIONS -# -# A condition object is created via -# import this_module -# your_condition_object = this_module.condition(lock=None) -# -# As explained below, a condition object has a lock associated with it, -# used in the protocol to protect condition data. You can specify a -# lock to use in the constructor, else the constructor will allocate -# an anonymous lock for you. Specifying a lock explicitly can be useful -# when more than one condition keys off the same set of shared data. -# -# Methods: -# .acquire() -# acquire the lock associated with the condition -# .release() -# release the lock associated with the condition -# .wait() -# block the thread until such time as some other thread does a -# .signal or .broadcast on the same condition, and release the -# lock associated with the condition. The lock associated with -# the condition MUST be in the acquired state at the time -# .wait is invoked. -# .signal() -# wake up exactly one thread (if any) that previously did a .wait -# on the condition; that thread will awaken with the lock associated -# with the condition in the acquired state. If no threads are -# .wait'ing, this is a nop. If more than one thread is .wait'ing on -# the condition, any of them may be awakened. -# .broadcast() -# wake up all threads (if any) that are .wait'ing on the condition; -# the threads are woken up serially, each with the lock in the -# acquired state, so should .release() as soon as possible. If no -# threads are .wait'ing, this is a nop. -# -# Note that if a thread does a .wait *while* a signal/broadcast is -# in progress, it's guaranteeed to block until a subsequent -# signal/broadcast. -# -# Secret feature: `broadcast' actually takes an integer argument, -# and will wake up exactly that many waiting threads (or the total -# number waiting, if that's less). Use of this is dubious, though, -# and probably won't be supported if this form of condition is -# reimplemented in C. -# -# DIFFERENCES FROM POSIX -# -# + A separate mutex is not needed to guard condition data. Instead, a -# condition object can (must) be .acquire'ed and .release'ed directly. -# This eliminates a common error in using POSIX conditions. -# -# + Because of implementation difficulties, a POSIX `signal' wakes up -# _at least_ one .wait'ing thread. Race conditions make it difficult -# to stop that. This implementation guarantees to wake up only one, -# but you probably shouldn't rely on that. -# -# PROTOCOL -# -# Condition objects are used to block threads until "some condition" is -# true. E.g., a thread may wish to wait until a producer pumps out data -# for it to consume, or a server may wish to wait until someone requests -# its services, or perhaps a whole bunch of threads want to wait until a -# preceding pass over the data is complete. Early models for conditions -# relied on some other thread figuring out when a blocked thread's -# condition was true, and made the other thread responsible both for -# waking up the blocked thread and guaranteeing that it woke up with all -# data in a correct state. This proved to be very delicate in practice, -# and gave conditions a bad name in some circles. -# -# The POSIX model addresses these problems by making a thread responsible -# for ensuring that its own state is correct when it wakes, and relies -# on a rigid protocol to make this easy; so long as you stick to the -# protocol, POSIX conditions are easy to "get right": -# -# A) The thread that's waiting for some arbitrarily-complex condition -# (ACC) to become true does: -# -# condition.acquire() -# while not (code to evaluate the ACC): -# condition.wait() -# # That blocks the thread, *and* releases the lock. When a -# # condition.signal() happens, it will wake up some thread that -# # did a .wait, *and* acquire the lock again before .wait -# # returns. -# # -# # Because the lock is acquired at this point, the state used -# # in evaluating the ACC is frozen, so it's safe to go back & -# # reevaluate the ACC. -# -# # At this point, ACC is true, and the thread has the condition -# # locked. -# # So code here can safely muck with the shared state that -# # went into evaluating the ACC -- if it wants to. -# # When done mucking with the shared state, do -# condition.release() -# -# B) Threads that are mucking with shared state that may affect the -# ACC do: -# -# condition.acquire() -# # muck with shared state -# condition.release() -# if it's possible that ACC is true now: -# condition.signal() # or .broadcast() -# -# Note: You may prefer to put the "if" clause before the release(). -# That's fine, but do note that anyone waiting on the signal will -# stay blocked until the release() is done (since acquiring the -# condition is part of what .wait() does before it returns). -# -# TRICK OF THE TRADE -# -# With simpler forms of conditions, it can be impossible to know when -# a thread that's supposed to do a .wait has actually done it. But -# because this form of condition releases a lock as _part_ of doing a -# wait, the state of that lock can be used to guarantee it. -# -# E.g., suppose thread A spawns thread B and later wants to wait for B to -# complete: -# -# In A: In B: -# -# B_done = condition() ... do work ... -# B_done.acquire() B_done.acquire(); B_done.release() -# spawn B B_done.signal() -# ... some time later ... ... and B exits ... -# B_done.wait() -# -# Because B_done was in the acquire'd state at the time B was spawned, -# B's attempt to acquire B_done can't succeed until A has done its -# B_done.wait() (which releases B_done). So B's B_done.signal() is -# guaranteed to be seen by the .wait(). Without the lock trick, B -# may signal before A .waits, and then A would wait forever. -# -# BARRIERS -# -# A barrier object is created via -# import this_module -# your_barrier = this_module.barrier(num_threads) -# -# Methods: -# .enter() -# the thread blocks until num_threads threads in all have done -# .enter(). Then the num_threads threads that .enter'ed resume, -# and the barrier resets to capture the next num_threads threads -# that .enter it. -# -# EVENTS -# -# An event object is created via -# import this_module -# your_event = this_module.event() -# -# An event has two states, `posted' and `cleared'. An event is -# created in the cleared state. -# -# Methods: -# -# .post() -# Put the event in the posted state, and resume all threads -# .wait'ing on the event (if any). -# -# .clear() -# Put the event in the cleared state. -# -# .is_posted() -# Returns 0 if the event is in the cleared state, or 1 if the event -# is in the posted state. -# -# .wait() -# If the event is in the posted state, returns immediately. -# If the event is in the cleared state, blocks the calling thread -# until the event is .post'ed by another thread. -# -# Note that an event, once posted, remains posted until explicitly -# cleared. Relative to conditions, this is both the strength & weakness -# of events. It's a strength because the .post'ing thread doesn't have to -# worry about whether the threads it's trying to communicate with have -# already done a .wait (a condition .signal is seen only by threads that -# do a .wait _prior_ to the .signal; a .signal does not persist). But -# it's a weakness because .clear'ing an event is error-prone: it's easy -# to mistakenly .clear an event before all the threads you intended to -# see the event get around to .wait'ing on it. But so long as you don't -# need to .clear an event, events are easy to use safely. -# -# SEMAPHORES -# -# A semaphore object is created via -# import this_module -# your_semaphore = this_module.semaphore(count=1) -# -# A semaphore has an integer count associated with it. The initial value -# of the count is specified by the optional argument (which defaults to -# 1) passed to the semaphore constructor. -# -# Methods: -# -# .p() -# If the semaphore's count is greater than 0, decrements the count -# by 1 and returns. -# Else if the semaphore's count is 0, blocks the calling thread -# until a subsequent .v() increases the count. When that happens, -# the count will be decremented by 1 and the calling thread resumed. -# -# .v() -# Increments the semaphore's count by 1, and wakes up a thread (if -# any) blocked by a .p(). It's an (detected) error for a .v() to -# increase the semaphore's count to a value larger than the initial -# count. -# -# MULTIPLE-READER SINGLE-WRITER LOCKS -# -# A mrsw lock is created via -# import this_module -# your_mrsw_lock = this_module.mrsw() -# -# This kind of lock is often useful with complex shared data structures. -# The object lets any number of "readers" proceed, so long as no thread -# wishes to "write". When a (one or more) thread declares its intention -# to "write" (e.g., to update a shared structure), all current readers -# are allowed to finish, and then a writer gets exclusive access; all -# other readers & writers are blocked until the current writer completes. -# Finally, if some thread is waiting to write and another is waiting to -# read, the writer takes precedence. -# -# Methods: -# -# .read_in() -# If no thread is writing or waiting to write, returns immediately. -# Else blocks until no thread is writing or waiting to write. So -# long as some thread has completed a .read_in but not a .read_out, -# writers are blocked. -# -# .read_out() -# Use sometime after a .read_in to declare that the thread is done -# reading. When all threads complete reading, a writer can proceed. -# -# .write_in() -# If no thread is writing (has completed a .write_in, but hasn't yet -# done a .write_out) or reading (similarly), returns immediately. -# Else blocks the calling thread, and threads waiting to read, until -# the current writer completes writing or all the current readers -# complete reading; if then more than one thread is waiting to -# write, one of them is allowed to proceed, but which one is not -# specified. -# -# .write_out() -# Use sometime after a .write_in to declare that the thread is done -# writing. Then if some other thread is waiting to write, it's -# allowed to proceed. Else all threads (if any) waiting to read are -# allowed to proceed. -# -# .write_to_read() -# Use instead of a .write_in to declare that the thread is done -# writing but wants to continue reading without other writers -# intervening. If there are other threads waiting to write, they -# are allowed to proceed only if the current thread calls -# .read_out; threads waiting to read are only allowed to proceed -# if there are are no threads waiting to write. (This is a -# weakness of the interface!) - -import _thread as thread - -class condition: - def __init__(self, lock=None): - # the lock actually used by .acquire() and .release() - if lock is None: - self.mutex = thread.allocate_lock() - else: - if hasattr(lock, 'acquire') and \ - hasattr(lock, 'release'): - self.mutex = lock - else: - raise TypeError('condition constructor requires ' \ - 'a lock argument') - - # lock used to block threads until a signal - self.checkout = thread.allocate_lock() - self.checkout.acquire() - - # internal critical-section lock, & the data it protects - self.idlock = thread.allocate_lock() - self.id = 0 - self.waiting = 0 # num waiters subject to current release - self.pending = 0 # num waiters awaiting next signal - self.torelease = 0 # num waiters to release - self.releasing = 0 # 1 iff release is in progress - - def acquire(self): - self.mutex.acquire() - - def release(self): - self.mutex.release() - - def wait(self): - mutex, checkout, idlock = self.mutex, self.checkout, self.idlock - if not mutex.locked(): - raise ValueError("condition must be .acquire'd when .wait() invoked") - - idlock.acquire() - myid = self.id - self.pending = self.pending + 1 - idlock.release() - - mutex.release() - - while 1: - checkout.acquire(); idlock.acquire() - if myid < self.id: - break - checkout.release(); idlock.release() - - self.waiting = self.waiting - 1 - self.torelease = self.torelease - 1 - if self.torelease: - checkout.release() - else: - self.releasing = 0 - if self.waiting == self.pending == 0: - self.id = 0 - idlock.release() - mutex.acquire() - - def signal(self): - self.broadcast(1) - - def broadcast(self, num = -1): - if num < -1: - raise ValueError('.broadcast called with num %r' % (num,)) - if num == 0: - return - self.idlock.acquire() - if self.pending: - self.waiting = self.waiting + self.pending - self.pending = 0 - self.id = self.id + 1 - if num == -1: - self.torelease = self.waiting - else: - self.torelease = min( self.waiting, - self.torelease + num ) - if self.torelease and not self.releasing: - self.releasing = 1 - self.checkout.release() - self.idlock.release() - -class barrier: - def __init__(self, n): - self.n = n - self.togo = n - self.full = condition() - - def enter(self): - full = self.full - full.acquire() - self.togo = self.togo - 1 - if self.togo: - full.wait() - else: - self.togo = self.n - full.broadcast() - full.release() - -class event: - def __init__(self): - self.state = 0 - self.posted = condition() - - def post(self): - self.posted.acquire() - self.state = 1 - self.posted.broadcast() - self.posted.release() - - def clear(self): - self.posted.acquire() - self.state = 0 - self.posted.release() - - def is_posted(self): - self.posted.acquire() - answer = self.state - self.posted.release() - return answer - - def wait(self): - self.posted.acquire() - if not self.state: - self.posted.wait() - self.posted.release() - -class semaphore: - def __init__(self, count=1): - if count <= 0: - raise ValueError('semaphore count %d; must be >= 1' % count) - self.count = count - self.maxcount = count - self.nonzero = condition() - - def p(self): - self.nonzero.acquire() - while self.count == 0: - self.nonzero.wait() - self.count = self.count - 1 - self.nonzero.release() - - def v(self): - self.nonzero.acquire() - if self.count == self.maxcount: - raise ValueError('.v() tried to raise semaphore count above ' \ - 'initial value %r' % self.maxcount) - self.count = self.count + 1 - self.nonzero.signal() - self.nonzero.release() - -class mrsw: - def __init__(self): - # critical-section lock & the data it protects - self.rwOK = thread.allocate_lock() - self.nr = 0 # number readers actively reading (not just waiting) - self.nw = 0 # number writers either waiting to write or writing - self.writing = 0 # 1 iff some thread is writing - - # conditions - self.readOK = condition(self.rwOK) # OK to unblock readers - self.writeOK = condition(self.rwOK) # OK to unblock writers - - def read_in(self): - self.rwOK.acquire() - while self.nw: - self.readOK.wait() - self.nr = self.nr + 1 - self.rwOK.release() - - def read_out(self): - self.rwOK.acquire() - if self.nr <= 0: - raise ValueError('.read_out() invoked without an active reader') - self.nr = self.nr - 1 - if self.nr == 0: - self.writeOK.signal() - self.rwOK.release() - - def write_in(self): - self.rwOK.acquire() - self.nw = self.nw + 1 - while self.writing or self.nr: - self.writeOK.wait() - self.writing = 1 - self.rwOK.release() - - def write_out(self): - self.rwOK.acquire() - if not self.writing: - raise ValueError('.write_out() invoked without an active writer') - self.writing = 0 - self.nw = self.nw - 1 - if self.nw: - self.writeOK.signal() - else: - self.readOK.broadcast() - self.rwOK.release() - - def write_to_read(self): - self.rwOK.acquire() - if not self.writing: - raise ValueError('.write_to_read() invoked without an active writer') - self.writing = 0 - self.nw = self.nw - 1 - self.nr = self.nr + 1 - if not self.nw: - self.readOK.broadcast() - self.rwOK.release() - -# The rest of the file is a test case, that runs a number of parallelized -# quicksorts in parallel. If it works, you'll get about 600 lines of -# tracing output, with a line like -# test passed! 209 threads created in all -# as the last line. The content and order of preceding lines will -# vary across runs. - -def _new_thread(func, *args): - global TID - tid.acquire(); id = TID = TID+1; tid.release() - io.acquire(); alive.append(id); \ - print('starting thread', id, '--', len(alive), 'alive'); \ - io.release() - thread.start_new_thread( func, (id,) + args ) - -def _qsort(tid, a, l, r, finished): - # sort a[l:r]; post finished when done - io.acquire(); print('thread', tid, 'qsort', l, r); io.release() - if r-l > 1: - pivot = a[l] - j = l+1 # make a[l:j] <= pivot, and a[j:r] > pivot - for i in range(j, r): - if a[i] <= pivot: - a[j], a[i] = a[i], a[j] - j = j + 1 - a[l], a[j-1] = a[j-1], pivot - - l_subarray_sorted = event() - r_subarray_sorted = event() - _new_thread(_qsort, a, l, j-1, l_subarray_sorted) - _new_thread(_qsort, a, j, r, r_subarray_sorted) - l_subarray_sorted.wait() - r_subarray_sorted.wait() - - io.acquire(); print('thread', tid, 'qsort done'); \ - alive.remove(tid); io.release() - finished.post() - -def _randarray(tid, a, finished): - io.acquire(); print('thread', tid, 'randomizing array'); \ - io.release() - for i in range(1, len(a)): - wh.acquire(); j = randint(0,i); wh.release() - a[i], a[j] = a[j], a[i] - io.acquire(); print('thread', tid, 'randomizing done'); \ - alive.remove(tid); io.release() - finished.post() - -def _check_sort(a): - if a != range(len(a)): - raise ValueError('a not sorted', a) - -def _run_one_sort(tid, a, bar, done): - # randomize a, and quicksort it - # for variety, all the threads running this enter a barrier - # at the end, and post `done' after the barrier exits - io.acquire(); print('thread', tid, 'randomizing', a); \ - io.release() - finished = event() - _new_thread(_randarray, a, finished) - finished.wait() - - io.acquire(); print('thread', tid, 'sorting', a); io.release() - finished.clear() - _new_thread(_qsort, a, 0, len(a), finished) - finished.wait() - _check_sort(a) - - io.acquire(); print('thread', tid, 'entering barrier'); \ - io.release() - bar.enter() - io.acquire(); print('thread', tid, 'leaving barrier'); \ - io.release() - io.acquire(); alive.remove(tid); io.release() - bar.enter() # make sure they've all removed themselves from alive - ## before 'done' is posted - bar.enter() # just to be cruel - done.post() - -def test(): - global TID, tid, io, wh, randint, alive - import random - randint = random.randint - - TID = 0 # thread ID (1, 2, ...) - tid = thread.allocate_lock() # for changing TID - io = thread.allocate_lock() # for printing, and 'alive' - wh = thread.allocate_lock() # for calls to random - alive = [] # IDs of active threads - - NSORTS = 5 - arrays = [] - for i in range(NSORTS): - arrays.append( range( (i+1)*10 ) ) - - bar = barrier(NSORTS) - finished = event() - for i in range(NSORTS): - _new_thread(_run_one_sort, arrays[i], bar, finished) - finished.wait() - - print('all threads done, and checking results ...') - if alive: - raise ValueError('threads still alive at end', alive) - for i in range(NSORTS): - a = arrays[i] - if len(a) != (i+1)*10: - raise ValueError('length of array', i, 'screwed up') - _check_sort(a) - - print('test passed!', TID, 'threads created in all') - -if __name__ == '__main__': - test() - -# end of module diff --git a/Demo/threads/telnet.py b/Demo/threads/telnet.py deleted file mode 100644 index dfe4905..0000000 --- a/Demo/threads/telnet.py +++ /dev/null @@ -1,114 +0,0 @@ -# Minimal interface to the Internet telnet protocol. -# -# *** modified to use threads *** -# -# It refuses all telnet options and does not recognize any of the other -# telnet commands, but can still be used to connect in line-by-line mode. -# It's also useful to play with a number of other services, -# like time, finger, smtp and even ftp. -# -# Usage: telnet host [port] -# -# The port may be a service name or a decimal port number; -# it defaults to 'telnet'. - - -import sys, os, time -from socket import * -import _thread as thread - -BUFSIZE = 8*1024 - -# Telnet protocol characters - -IAC = chr(255) # Interpret as command -DONT = chr(254) -DO = chr(253) -WONT = chr(252) -WILL = chr(251) - -def main(): - if len(sys.argv) < 2: - sys.stderr.write('usage: telnet hostname [port]\n') - sys.exit(2) - host = sys.argv[1] - try: - hostaddr = gethostbyname(host) - except error: - sys.stderr.write(sys.argv[1] + ': bad host name\n') - sys.exit(2) - # - if len(sys.argv) > 2: - servname = sys.argv[2] - else: - servname = 'telnet' - # - if '0' <= servname[:1] <= '9': - port = eval(servname) - else: - try: - port = getservbyname(servname, 'tcp') - except error: - sys.stderr.write(servname + ': bad tcp service name\n') - sys.exit(2) - # - s = socket(AF_INET, SOCK_STREAM) - # - try: - s.connect((host, port)) - except error as msg: - sys.stderr.write('connect failed: %r\n' % (msg,)) - sys.exit(1) - # - thread.start_new(child, (s,)) - parent(s) - -def parent(s): - # read socket, write stdout - iac = 0 # Interpret next char as command - opt = '' # Interpret next char as option - while 1: - data, dummy = s.recvfrom(BUFSIZE) - if not data: - # EOF -- exit - sys.stderr.write( '(Closed by remote host)\n') - sys.exit(1) - cleandata = '' - for c in data: - if opt: - print(ord(c)) -## print '(replying: %r)' % (opt+c,) - s.send(opt + c) - opt = '' - elif iac: - iac = 0 - if c == IAC: - cleandata = cleandata + c - elif c in (DO, DONT): - if c == DO: print('(DO)', end=' ') - else: print('(DONT)', end=' ') - opt = IAC + WONT - elif c in (WILL, WONT): - if c == WILL: print('(WILL)', end=' ') - else: print('(WONT)', end=' ') - opt = IAC + DONT - else: - print('(command)', ord(c)) - elif c == IAC: - iac = 1 - print('(IAC)', end=' ') - else: - cleandata = cleandata + c - sys.stdout.write(cleandata) - sys.stdout.flush() -## print 'Out:', repr(cleandata) - -def child(s): - # read stdin, write socket - while 1: - line = sys.stdin.readline() -## print 'Got:', repr(line) - if not line: break - s.send(line) - -main() diff --git a/Demo/tix/INSTALL.txt b/Demo/tix/INSTALL.txt deleted file mode 100644 index ac70b68..0000000 --- a/Demo/tix/INSTALL.txt +++ /dev/null @@ -1,89 +0,0 @@ -$Id$ - -Installing Tix.py ----------------- - -0) To use Tix.py, you need Tcl/Tk (V8.3.3), Tix (V8.1.1) and Python (V2.1.1). - Tix.py has been written and tested on a Intel Pentium running RH Linux 5.2 - and Mandrake Linux 7.0 and Windows with the above mentioned packages. - - Older versions, e.g. Tix 4.1 and Tk 8.0, might also work. - - There is nothing OS-specific in Tix.py itself so it should work on - any machine with Tix and Python installed. You can get Tcl and Tk - from http://dev.scriptics.com and Tix from http://tix.sourceforge.net. - -1) Build and install Tcl/Tk 8.3. Build and install Tix 8.1. - Ensure that Tix is properly installed by running tixwish and executing - the demo programs. Under Unix, use the --enable-shared configure option - for all three. We recommend tcl8.3.3 for this release of Tix.py. - -2a) If you have a distribution like ActiveState with a tcl subdirectory - of $PYTHONHOME, which contains the directories tcl8.3 and tk8.3, - make a directory tix8.1 as well. Recursively copy the files from - <tix>/library to $PYTHONHOME/lib/tix8.1, and copy the dynamic library - (tix8183.dll or libtix8.1.8.3.so) to the same place as the tcl dynamic - libraries ($PYTHONHOME/Dlls or lib/python-2.1/lib-dynload). In this - case you are all installed, and you can skip to the end. - -2b) Modify Modules/Setup.dist and setup.py to change the version of the - tix library from tix4.1.8.0 to tix8.1.8.3 - These modified files can be used for Tkinter with or without Tix. - -3) The default is to build dynamically, and use the Tcl 'package require'. - To build statically, modify the Modules/Setup file to link in the Tix - library according to the comments in the file. On Linux this looks like: - -# *** Always uncomment this (leave the leading underscore in!): -_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ -# *** Uncomment and edit to reflect where your Tcl/Tk libraries are: - -L/usr/local/lib \ -# *** Uncomment and edit to reflect where your Tcl/Tk headers are: - -I/usr/local/include \ -# *** Uncomment and edit to reflect where your X11 header files are: - -I/usr/X11R6/include \ -# *** Or uncomment this for Solaris: -# -I/usr/openwin/include \ -# *** Uncomment and edit for BLT extension only: -# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \ -# *** Uncomment and edit for PIL (TkImaging) extension only: -# (See http://www.pythonware.com/products/pil/ for more info) -# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ -# *** Uncomment and edit for TOGL extension only: -# -DWITH_TOGL togl.c \ -# *** Uncomment and edit for Tix extension only: - -DWITH_TIX -ltix8.1.8.3 \ -# *** Uncomment and edit to reflect your Tcl/Tk versions: - -ltk8.3 -ltcl8.3 \ -# *** Uncomment and edit to reflect where your X11 libraries are: - -L/usr/X11R6/lib \ -# *** Or uncomment this for Solaris: -# -L/usr/openwin/lib \ -# *** Uncomment these for TOGL extension only: -# -lGL -lGLU -lXext -lXmu \ -# *** Uncomment for AIX: -# -lld \ -# *** Always uncomment this; X11 libraries to link with: - -lX11 - -4) Rebuild Python and reinstall. - -You should now have a working Tix implementation in Python. To see if all -is as it should be, run the 'tixwidgets.py' script in the Demo/tix directory. -Under X windows, do - /usr/local/bin/python Demo/tix/tixwidgets.py - -If this does not work, you may need to tell python where to find -the Tcl, Tk and Tix library files. This is done by setting the -TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. Try this: - - env TCL_LIBRARY=/usr/local/lib/tcl8.3 \ - TK_LIBRARY=/usr/local/lib/tk8.3 \ - TIX_LIBRARY=/usr/local/lib/tix8.1 \ - /usr/local/bin/python Demo/tix/tixwidgets.py - - -If you find any bugs or have suggestions for improvement, please report them -via http://tix.sourceforge.net - - diff --git a/Demo/tix/README.txt b/Demo/tix/README.txt deleted file mode 100644 index e0196ac..0000000 --- a/Demo/tix/README.txt +++ /dev/null @@ -1,19 +0,0 @@ -About Tix.py ------------ - -Tix.py is based on an idea of Jean-Marc Lugrin (lugrin@ms.com) who wrote -pytix (another Python-Tix marriage). Tix widgets are an attractive and -useful extension to Tk. See http://tix.sourceforge.net -for more details about Tix and how to get it. - -Features: - 1) It is almost complete. - 2) Tix widgets are represented by classes in Python. Sub-widgets - are members of the mega-widget class. For example, if a - particular TixWidget (e.g. ScrolledText) has an embedded widget - (Text in this case), it is possible to call the methods of the - child directly. - 3) The members of the class are created automatically. In the case - of widgets like ButtonBox, the members are added dynamically. - - diff --git a/Demo/tix/bitmaps/about.xpm b/Demo/tix/bitmaps/about.xpm deleted file mode 100755 index 33ffcc0..0000000 --- a/Demo/tix/bitmaps/about.xpm +++ /dev/null @@ -1,50 +0,0 @@ -/* XPM */ -static char * about_xpm[] = { -"50 40 7 1", -" s None c None", -". c black", -"X c white", -"o c gray70", -"O c navy", -"+ c red", -"@ c yellow", -" ", -" ", -" ", -" ................................. ", -" ..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXoo. ", -" .XooooooooooooooooooooooooooooooXo. ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXooXo. ", -" ..oooooooooooooooooooooooooooooooXo. ", -" ...............................XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.++++ ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo+++ ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++++ ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo++++++ ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++ + ", -" .OOOOO@@@@@OOOOOOOOOOOOOOOOOOO.Xo++. ", -" .OOOOOOO@OOOOO@OOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOO@OOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOO@OOOO@@OOO@OOO@OOOOOOO.XoXo. ", -" .OOOOOOO@OOOOO@OOOO@O@OOOOOOOO.XoXo. ", -" .OOOOOOO@OOOOO@OOOOO@OOOOOOOOO.XoXo. ", -" .OOOOOOO@OOOOO@OOOOO@OOOOOOOOO.XoXo. ", -" .OOOOOOO@OOOOO@OOOO@O@OOOOOOOO.XoXo. ", -" .OOOOOOO@OOOO@@@OO@OOO@OOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo.. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ", -" OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.X. ", -" ............................. ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/bold.xbm b/Demo/tix/bitmaps/bold.xbm deleted file mode 100755 index ebff8d1..0000000 --- a/Demo/tix/bitmaps/bold.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define bold_width 16 -#define bold_height 16 -static unsigned char bold_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x0f, 0x18, 0x1c, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x1c, 0xf8, 0x0f, 0xf8, 0x0f, 0x18, 0x18, 0x18, 0x30, - 0x18, 0x30, 0x18, 0x38, 0xfc, 0x3f, 0xfc, 0x1f}; diff --git a/Demo/tix/bitmaps/capital.xbm b/Demo/tix/bitmaps/capital.xbm deleted file mode 100755 index fb4e070..0000000 --- a/Demo/tix/bitmaps/capital.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define capital_width 16 -#define capital_height 16 -static unsigned char capital_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0x30, 0x0c, 0x30, 0x06, - 0x30, 0x03, 0xb0, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x01, 0xb0, 0x03, - 0x30, 0x07, 0x30, 0x0e, 0x30, 0x1c, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/centerj.xbm b/Demo/tix/bitmaps/centerj.xbm deleted file mode 100755 index 9d2c064..0000000 --- a/Demo/tix/bitmaps/centerj.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define centerj_width 16 -#define centerj_height 16 -static unsigned char centerj_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xc0, 0x0d, - 0x00, 0x00, 0x58, 0x77, 0x00, 0x00, 0xb0, 0x3b, 0x00, 0x00, 0xdc, 0xf7, - 0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xd8, 0x7e}; diff --git a/Demo/tix/bitmaps/combobox.xbm b/Demo/tix/bitmaps/combobox.xbm deleted file mode 100755 index f5947f5..0000000 --- a/Demo/tix/bitmaps/combobox.xbm +++ /dev/null @@ -1,14 +0,0 @@ -#define combobox_width 32 -#define combobox_height 32 -static unsigned char combobox_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfc, 0xff, 0xff, 0x3e, 0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2a, - 0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2b, 0xfc, 0xff, 0xff, 0x3e, - 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a, - 0x28, 0x49, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x22, - 0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x12, 0x22, 0x08, 0x00, 0x00, 0x22, - 0x08, 0x00, 0x00, 0x22, 0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x02, 0x22, - 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x2a, - 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/combobox.xpm b/Demo/tix/bitmaps/combobox.xpm deleted file mode 100755 index d0234ab..0000000 --- a/Demo/tix/bitmaps/combobox.xpm +++ /dev/null @@ -1,49 +0,0 @@ -/* XPM */ -static char * combobox_xpm[] = { -"50 40 6 1", -" s None c None", -". c black", -"X c white", -"o c #FFFF80808080", -"O c gray70", -"+ c #808000008080", -" ", -" ", -" ", -" .................................... XXXXXXX ", -" .ooooooooooooooooooooooooooooooooooX X . . ", -" .ooooooooooooooooooooooooooooooooooX X . . ", -" .oooo.oooooooooooooooooooooooooooooX X . . ", -" .oo.o..oo.o.oo.o.ooooooooooooooooooX X . . ", -" .o..o.o.o.oo.oo.oo.ooooooooooooooooX X ... . ", -" .oo.oo.oo.o.oo.ooo.ooooooooooooooooX X . . ", -" .ooooooooooooooooooooooooooooooooooX X . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X...... ", -" ", -" ", -" ", -" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ", -" X............................................ ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ", -" X.O+OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OX OX. ", -" X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.X ..X. ", -" X.O+O+O+OOO+O+OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ", -" X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.XXXXX. ", -" X.O.....X..........................OOX.X .X. ", -" X.OX...XXX.X.XX.XX.................OOX.X .X. ", -" X.OX.X..X..X.XX..XX.X..............OOX.X .X. ", -" X.O.X...X..X.X...X..X..............OOX.X .X. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOO+OOOOOOOOOOX.X .X. ", -" X.OOOOOOOOO+OOO+OOOOO+OOOO+OOOOOOOOOOX.X .X. ", -" X.O+++OO+OO+O+OO++O++OO+OO+OOOOOOOOOOX.X...X. ", -" X.OO+OO++OO+O+OO+OOO+OO+O++OOOOOOOOOOX.OOOOX. ", -" X.OOOOOOOO+OOOOO++OO+OOOOOOOOOOOOOOOOX.OOOOX. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.X .X. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.O .OX. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ", -" X.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXX. ", -" X............................................ ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/combobox.xpm.1 b/Demo/tix/bitmaps/combobox.xpm.1 deleted file mode 100755 index 63792a4..0000000 --- a/Demo/tix/bitmaps/combobox.xpm.1 +++ /dev/null @@ -1,47 +0,0 @@ -/* XPM */ -static char * combobox_xpm[] = { -"50 40 4 1", -" s None c None", -". c black", -"X c #FFFF80808080", -"o c gray70", -" ", -" ", -" ", -" .................................... ....... ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . ... . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . ", -" .................................... ....... ", -" ", -" ............................................. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .o...................................o.ooooo. ", -" .o...................................o.ooooo. ", -" .o...................................o.ooooo. ", -" .o...................................o.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" ............................................. ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/drivea.xbm b/Demo/tix/bitmaps/drivea.xbm deleted file mode 100755 index 83c636c..0000000 --- a/Demo/tix/bitmaps/drivea.xbm +++ /dev/null @@ -1,14 +0,0 @@ -#define drivea_width 32 -#define drivea_height 32 -static unsigned char drivea_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a, - 0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d, - 0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a, - 0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d, - 0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/drivea.xpm b/Demo/tix/bitmaps/drivea.xpm deleted file mode 100755 index 4d274b9..0000000 --- a/Demo/tix/bitmaps/drivea.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char * drivea_xpm[] = { -/* width height ncolors chars_per_pixel */ -"32 32 5 1", -/* colors */ -" s None c None", -". c #000000000000", -"X c white", -"o c #c000c000c000", -"O c #800080008000", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" .......................... ", -" .XXXXXXXXXXXXXXXXXXXXXXXo. ", -" .XooooooooooooooooooooooO. ", -" .Xooooooooooooooooo..oooO. ", -" .Xooooooooooooooooo..oooO. ", -" .XooooooooooooooooooooooO. ", -" .Xoooooooo.......oooooooO. ", -" .Xoo...................oO. ", -" .Xoooooooo.......oooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .oOOOOOOOOOOOOOOOOOOOOOOO. ", -" .......................... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/exit.xpm b/Demo/tix/bitmaps/exit.xpm deleted file mode 100755 index 505a07b..0000000 --- a/Demo/tix/bitmaps/exit.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char * exit_xpm[] = { -"50 40 5 1", -" s None c None", -". c black", -"X c white", -"o c #000080800000", -"O c yellow", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ....................................... ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XoooooooooooooooooooooooOoooooooooooX. ", -" .XoooooooooooooooooooooooOOooooooooooX. ", -" .XoooooooooooooooooooooooOOOoooooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOOoooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX. ", -" .XoooooooooooooooooooooooOOOoooooooooX. ", -" .XoooooooooooooooooooooooOOooooooooooX. ", -" .XoooooooooooooooooooooooOoooooooooooX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. ", -" ....................................... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/filebox.xbm b/Demo/tix/bitmaps/filebox.xbm deleted file mode 100755 index c8f7ac2..0000000 --- a/Demo/tix/bitmaps/filebox.xbm +++ /dev/null @@ -1,14 +0,0 @@ -#define filebox_width 32 -#define filebox_height 32 -static unsigned char filebox_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x3f, 0x04, 0x00, 0x00, 0x20, - 0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24, - 0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xe4, 0x7f, 0xfe, 0x27, - 0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25, - 0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24, - 0x24, 0x50, 0x02, 0x25, 0xe4, 0x7f, 0xfe, 0x27, 0x04, 0x00, 0x00, 0x20, - 0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24, - 0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xfc, 0xff, 0xff, 0x3f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/filebox.xpm b/Demo/tix/bitmaps/filebox.xpm deleted file mode 100755 index 7377ee6..0000000 --- a/Demo/tix/bitmaps/filebox.xpm +++ /dev/null @@ -1,49 +0,0 @@ -/* XPM */ -static char * filebox_xpm[] = { -"50 40 6 1", -" s None c None", -". c white", -"X c gray80", -"o c black", -"O c #FFFF80808080", -"+ c gray70", -" ", -" ", -" ", -" ............................................ ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooooooooooooooooooooooooooooooooooooo.XXo ", -" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo ", -" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo ", -" .XX......................................XXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXoooooooooooooooo.XXXXoooooooooooooooo.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XX.................XXXX.................XXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooXooXoXooXoXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooXooXoXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXoooooooooooooooooooooooooooooooooooooo.Xo ", -" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ", -" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ", -" .XX.......................................Xo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .ooooooooooooooooooooooooooooooooooooooooooo ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/italic.xbm b/Demo/tix/bitmaps/italic.xbm deleted file mode 100755 index 169c3cb..0000000 --- a/Demo/tix/bitmaps/italic.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define italic_width 16 -#define italic_height 16 -static unsigned char italic_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x80, 0x3f, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x03, 0x00, 0x03, 0x80, 0x01, 0x80, 0x01, 0xc0, 0x00, 0xc0, 0x00, - 0x60, 0x00, 0x60, 0x00, 0xfc, 0x01, 0xfc, 0x01}; diff --git a/Demo/tix/bitmaps/justify.xbm b/Demo/tix/bitmaps/justify.xbm deleted file mode 100755 index bba660a..0000000 --- a/Demo/tix/bitmaps/justify.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define justify_width 16 -#define justify_height 16 -static unsigned char justify_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xdb, 0x00, 0x00, 0x7c, 0xdb, - 0x00, 0x00, 0xbc, 0xf7, 0x00, 0x00, 0xdc, 0xde, 0x00, 0x00, 0x6c, 0xdf, - 0x00, 0x00, 0x6c, 0xef, 0x00, 0x00, 0xdc, 0xdf}; diff --git a/Demo/tix/bitmaps/leftj.xbm b/Demo/tix/bitmaps/leftj.xbm deleted file mode 100755 index 5f8e006..0000000 --- a/Demo/tix/bitmaps/leftj.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define leftj_width 16 -#define leftj_height 16 -static unsigned char leftj_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x6d, 0x00, 0x00, 0xdc, 0x01, - 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xfc, 0x7e, 0x00, 0x00, 0xdc, 0x03, - 0x00, 0x00, 0x6c, 0x3b, 0x00, 0x00, 0x6c, 0x1f}; diff --git a/Demo/tix/bitmaps/netw.xbm b/Demo/tix/bitmaps/netw.xbm deleted file mode 100755 index a684d65..0000000 --- a/Demo/tix/bitmaps/netw.xbm +++ /dev/null @@ -1,14 +0,0 @@ -#define netw_width 32 -#define netw_height 32 -static unsigned char netw_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40, - 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52, - 0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50, - 0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50, - 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55, - 0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f, - 0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00, - 0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03, - 0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02, - 0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, - 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/netw.xpm b/Demo/tix/bitmaps/netw.xpm deleted file mode 100755 index fff6593..0000000 --- a/Demo/tix/bitmaps/netw.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * netw_xpm[] = { -/* width height ncolors chars_per_pixel */ -"32 32 7 1", -/* colors */ -" s None c None", -". c #000000000000", -"X c white", -"o c #c000c000c000", -"O c #404040", -"+ c blue", -"@ c red", -/* pixels */ -" ", -" .............. ", -" .XXXXXXXXXXXX. ", -" .XooooooooooO. ", -" .Xo.......XoO. ", -" .Xo.++++o+XoO. ", -" .Xo.++++o+XoO. ", -" .Xo.++oo++XoO. ", -" .Xo.++++++XoO. ", -" .Xo.+o++++XoO. ", -" .Xo.++++++XoO. ", -" .Xo.XXXXXXXoO. ", -" .XooooooooooO. ", -" .Xo@ooo....oO. ", -" .............. .XooooooooooO. ", -" .XXXXXXXXXXXX. .XooooooooooO. ", -" .XooooooooooO. .OOOOOOOOOOOO. ", -" .Xo.......XoO. .............. ", -" .Xo.++++o+XoO. @ ", -" .Xo.++++o+XoO. @ ", -" .Xo.++oo++XoO. @ ", -" .Xo.++++++XoO. @ ", -" .Xo.+o++++XoO. @ ", -" .Xo.++++++XoO. ..... ", -" .Xo.XXXXXXXoO. .XXX. ", -" .XooooooooooO.@@@@@@.X O. ", -" .Xo@ooo....oO. .OOO. ", -" .XooooooooooO. ..... ", -" .XooooooooooO. ", -" .OOOOOOOOOOOO. ", -" .............. ", -" "}; diff --git a/Demo/tix/bitmaps/optmenu.xpm b/Demo/tix/bitmaps/optmenu.xpm deleted file mode 100755 index 63bab81..0000000 --- a/Demo/tix/bitmaps/optmenu.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char * optmenu_xpm[] = { -"50 40 5 1", -" s None c None", -". c white", -"X c gray80", -"o c gray50", -"O c black", -" ", -" ", -" .............................. ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXOXOXXOXXOXXXXOOXXXXXXXXXXo ", -" .XXXOXOXXOXOXXXOXXOXXXXXXXXXXo ", -" .XXXXOXXOXXOXXXOXXXOXXXXXXXXXo ", -" .XXXXOXXXOXXOOXXOXOXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo.............o ", -" .............................o o ", -" ..XXXOXXXXXOXXXXXXXXOXXXXXXXOo o ", -" ..XXOXOXOXXOXOXXXOXXOXXXXXXXOo ...... o ", -" ..XXXOXXXOXXOXXXOXXXOXXXXXXXOo . o o ", -" ..XXOXXXOXXXOXOXXOXXOXXXXXXXOo . o o ", -" ..XXXXXXXXXXXXXXXXXXXXXXXXXXOo .ooooo o ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOo o ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo o ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXooooooooooooooo ", -" .XXXXOXXXXXOXXXXXXXXXXXXXXXXXo ", -" .XXXOXXXXXXXXXOXXXXXXXXXXXXXXo ", -" .XXXXOXXOXXOXOXOXXXXXXXXXXXXXo ", -" .XXXXXOXXOXOXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXOXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXOXOXXXXXXXOXOXXXXXOXXXXXXo ", -" .XXXXXOXOXOXXOXXXXXOXXOXXXXXXo ", -" .XXXXOXXOXOXOXXXOXOXOXXOXXXXXo ", -" .XXXOXXXXOXXOXXXOXXOXXXXOXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" oooooooooooooooooooooooooooooo ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/rightj.xbm b/Demo/tix/bitmaps/rightj.xbm deleted file mode 100755 index 1d438e0..0000000 --- a/Demo/tix/bitmaps/rightj.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define rightj_width 16 -#define rightj_height 16 -static unsigned char rightj_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdb, 0x00, 0x00, 0x70, 0xdb, - 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0xd8, 0xde, 0x00, 0x00, 0xc0, 0xdd, - 0x00, 0x00, 0xa0, 0xef, 0x00, 0x00, 0xd8, 0xde}; diff --git a/Demo/tix/bitmaps/select.xpm b/Demo/tix/bitmaps/select.xpm deleted file mode 100755 index 392e5a0..0000000 --- a/Demo/tix/bitmaps/select.xpm +++ /dev/null @@ -1,52 +0,0 @@ -/* XPM */ -static char * select_xpm[] = { -"50 40 9 1", -" s None c None", -". c black", -"X c gray95", -"o c gray50", -"O c gray70", -"+ c navy", -"@ c #000080800000", -"# c #808000000000", -"$ c white", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" .............................................. ", -" .XXXXXXXXXXooooooooooooXXXXXXXXXXXoXXXXXXXXXX. ", -" .X ooOOOOOOOOOOXX oX o. ", -" .X ooOOOOOOOOOOXX oX o. ", -" .X ++++ ooOOOOOOOOOOXX ... oX @ o. ", -" .X +++++ ooOOOOOOOOOOXX . . oX @@@ o. ", -" .X +++ + ooOOOOOOOOOOXX . . oX @ @ o. ", -" .X + + ooOO#####OOOXX . . oX @ @ o. ", -" .X + + ooOO#OOO##OOXX . oX @ @ o. ", -" .X + + ooO##OOOO##OXX . oX @ @ o. ", -" .X ++ ++ ooO###OOO#OOXX . oX @ @ o. ", -" .X +++++++ ooO#######OOXX . oX @ @ o. ", -" .X + + ooO##O#OO#OOXX . oX @ @ o. ", -" .X + ++ ooO##OOOOO#OXX . . oX @ @ o. ", -" .X + + ooOO#OOOOO#OXX . . oX @ @@ o. ", -" .X + ++ ooOO#OOOOO#OXX .... oX @@@@@ o. ", -" .X ooOO######OOXX oX o. ", -" .X ooOOOOOOOOOOXX $oX o. ", -" .XoooooooooooXXXXXXXXXXXoooooooooooXooooooooo. ", -" .............................................. ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/tix.gif b/Demo/tix/bitmaps/tix.gif Binary files differdeleted file mode 100755 index e7d51a0..0000000 --- a/Demo/tix/bitmaps/tix.gif +++ /dev/null diff --git a/Demo/tix/bitmaps/underline.xbm b/Demo/tix/bitmaps/underline.xbm deleted file mode 100755 index f07bb46..0000000 --- a/Demo/tix/bitmaps/underline.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define underline_width 16 -#define underline_height 16 -static unsigned char underline_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x38, 0x1c, - 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x70, 0x0e, - 0xf0, 0x0f, 0xe0, 0x07, 0x00, 0x00, 0xf8, 0x1f}; diff --git a/Demo/tix/grid.py b/Demo/tix/grid.py deleted file mode 100644 index 4268f07..0000000 --- a/Demo/tix/grid.py +++ /dev/null @@ -1,28 +0,0 @@ -### -import tkinter.tix as tk -from pprint import pprint - -r= tk.Tk() -r.title("test") - -l=tk.Label(r, name="a_label") -l.pack() - -class MyGrid(tk.Grid): - def __init__(self, *args, **kwargs): - kwargs['editnotify']= self.editnotify - tk.Grid.__init__(self, *args, **kwargs) - def editnotify(self, x, y): - return True - -g = MyGrid(r, name="a_grid", -selectunit="cell") -g.pack(fill=tk.BOTH) -for x in range(5): - for y in range(5): - g.set(x,y,text=str((x,y))) - -c = tk.Button(r, text="Close", command=r.destroy) -c.pack() - -tk.mainloop() diff --git a/Demo/tix/samples/Balloon.py b/Demo/tix/samples/Balloon.py deleted file mode 100755 index bc25a2e..0000000 --- a/Demo/tix/samples/Balloon.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixBalloon widget, which provides -# a interesting way to give help tips about elements in your user interface. -# Your can display the help message in a "balloon" and a status bar widget. -# - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - balloon = DemoBalloon(root) - balloon.mainloop() - balloon.destroy() - -class DemoBalloon: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - status = tkinter.tix.Label(w, width=40, relief=tkinter.tix.SUNKEN, bd=1) - status.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.Y, padx=2, pady=1) - - # Create two mysterious widgets that need balloon help - button1 = tkinter.tix.Button(w, text='Something Unexpected', - command=self.quitcmd) - button2 = tkinter.tix.Button(w, text='Something Else Unexpected') - button2['command'] = lambda w=button2: w.destroy() - button1.pack(side=tkinter.tix.TOP, expand=1) - button2.pack(side=tkinter.tix.TOP, expand=1) - - # Create the balloon widget and associate it with the widgets that we want - # to provide tips for: - b = tkinter.tix.Balloon(w, statusbar=status) - - b.bind_widget(button1, balloonmsg='Close Window', - statusmsg='Press this button to close this window') - b.bind_widget(button2, balloonmsg='Self-destruct button', - statusmsg='Press this button and it will destroy itself') - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - foundEvent = 1 - while self.exit < 0 and foundEvent > 0: - foundEvent = self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/BtnBox.py b/Demo/tix/samples/BtnBox.py deleted file mode 100755 index 3b9ee4b..0000000 --- a/Demo/tix/samples/BtnBox.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixButtonBox widget, which is a -# group of TK buttons. You can use it to manage the buttons in a dialog box, -# for example. -# - -import tkinter.tix - -def RunSample(w): - # Create the label on the top of the dialog box - # - top = tkinter.tix.Label(w, padx=20, pady=10, bd=1, relief=tkinter.tix.RAISED, - anchor=tkinter.tix.CENTER, text='This dialog box is\n a demonstration of the\n tixButtonBox widget') - - # Create the button box and add a few buttons in it. Set the - # -width of all the buttons to the same value so that they - # appear in the same size. - # - # Note that the -text, -underline, -command and -width options are all - # standard options of the button widgets. - # - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='OK', underline=0, width=5, - command=lambda w=w: w.destroy()) - box.add('close', text='Cancel', underline=0, width=5, - command=lambda w=w: w.destroy()) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/CmpImg.py b/Demo/tix/samples/CmpImg.py deleted file mode 100755 index ad49181..0000000 --- a/Demo/tix/samples/CmpImg.py +++ /dev/null @@ -1,196 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the compound images: it uses compound -# images to display a text string together with a pixmap inside -# buttons -# - -import tkinter.tix - -network_pixmap = """/* XPM */ -static char * netw_xpm[] = { -/* width height ncolors chars_per_pixel */ -"32 32 7 1", -/* colors */ -" s None c None", -". c #000000000000", -"X c white", -"o c #c000c000c000", -"O c #404040", -"+ c blue", -"@ c red", -/* pixels */ -" ", -" .............. ", -" .XXXXXXXXXXXX. ", -" .XooooooooooO. ", -" .Xo.......XoO. ", -" .Xo.++++o+XoO. ", -" .Xo.++++o+XoO. ", -" .Xo.++oo++XoO. ", -" .Xo.++++++XoO. ", -" .Xo.+o++++XoO. ", -" .Xo.++++++XoO. ", -" .Xo.XXXXXXXoO. ", -" .XooooooooooO. ", -" .Xo@ooo....oO. ", -" .............. .XooooooooooO. ", -" .XXXXXXXXXXXX. .XooooooooooO. ", -" .XooooooooooO. .OOOOOOOOOOOO. ", -" .Xo.......XoO. .............. ", -" .Xo.++++o+XoO. @ ", -" .Xo.++++o+XoO. @ ", -" .Xo.++oo++XoO. @ ", -" .Xo.++++++XoO. @ ", -" .Xo.+o++++XoO. @ ", -" .Xo.++++++XoO. ..... ", -" .Xo.XXXXXXXoO. .XXX. ", -" .XooooooooooO.@@@@@@.X O. ", -" .Xo@ooo....oO. .OOO. ", -" .XooooooooooO. ..... ", -" .XooooooooooO. ", -" .OOOOOOOOOOOO. ", -" .............. ", -" "}; -""" - -hard_disk_pixmap = """/* XPM */ -static char * drivea_xpm[] = { -/* width height ncolors chars_per_pixel */ -"32 32 5 1", -/* colors */ -" s None c None", -". c #000000000000", -"X c white", -"o c #c000c000c000", -"O c #800080008000", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" .......................... ", -" .XXXXXXXXXXXXXXXXXXXXXXXo. ", -" .XooooooooooooooooooooooO. ", -" .Xooooooooooooooooo..oooO. ", -" .Xooooooooooooooooo..oooO. ", -" .XooooooooooooooooooooooO. ", -" .Xoooooooo.......oooooooO. ", -" .Xoo...................oO. ", -" .Xoooooooo.......oooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .oOOOOOOOOOOOOOOOOOOOOOOO. ", -" .......................... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; -""" - -network_bitmap = """ -#define netw_width 32 -#define netw_height 32 -static unsigned char netw_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40, - 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52, - 0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50, - 0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50, - 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55, - 0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f, - 0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00, - 0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03, - 0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02, - 0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, - 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -""" - -hard_disk_bitmap = """ -#define drivea_width 32 -#define drivea_height 32 -static unsigned char drivea_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a, - 0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d, - 0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a, - 0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d, - 0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -""" - -def RunSample(w): - w.img0 = tkinter.tix.Image('pixmap', data=network_pixmap) - if not w.img0: - w.img0 = tkinter.tix.Image('bitmap', data=network_bitmap) - w.img1 = tkinter.tix.Image('pixmap', data=hard_disk_pixmap) - if not w.img0: - w.img1 = tkinter.tix.Image('bitmap', data=hard_disk_bitmap) - - hdd = tkinter.tix.Button(w, padx=4, pady=1, width=120) - net = tkinter.tix.Button(w, padx=4, pady=1, width=120) - - # Create the first image: we create a line, then put a string, - # a space and a image into this line, from left to right. - # The result: we have a one-line image that consists of three - # individual items - # - # The tk.calls should be methods in Tix ... - w.hdd_img = tkinter.tix.Image('compound', window=hdd) - w.hdd_img.tk.call(str(w.hdd_img), 'add', 'line') - w.hdd_img.tk.call(str(w.hdd_img), 'add', 'text', '-text', 'Hard Disk', - '-underline', '0') - w.hdd_img.tk.call(str(w.hdd_img), 'add', 'space', '-width', '7') - w.hdd_img.tk.call(str(w.hdd_img), 'add', 'image', '-image', w.img1) - - # Put this image into the first button - # - hdd['image'] = w.hdd_img - - # Next button - w.net_img = tkinter.tix.Image('compound', window=net) - w.net_img.tk.call(str(w.net_img), 'add', 'line') - w.net_img.tk.call(str(w.net_img), 'add', 'text', '-text', 'Network', - '-underline', '0') - w.net_img.tk.call(str(w.net_img), 'add', 'space', '-width', '7') - w.net_img.tk.call(str(w.net_img), 'add', 'image', '-image', w.img0) - - # Put this image into the first button - # - net['image'] = w.net_img - - close = tkinter.tix.Button(w, pady=1, text='Close', - command=lambda w=w: w.destroy()) - - hdd.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1) - net.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1) - close.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/ComboBox.py b/Demo/tix/samples/ComboBox.py deleted file mode 100755 index 80d78f2..0000000 --- a/Demo/tix/samples/ComboBox.py +++ /dev/null @@ -1,102 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixComboBox widget, which is close -# to the MS Window Combo Box control. -# -import tkinter.tix - -def RunSample(w): - global demo_month, demo_year - - top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED) - - demo_month = tkinter.tix.StringVar() - demo_year = tkinter.tix.StringVar() - - # $w.top.a is a drop-down combo box. It is not editable -- who wants - # to invent new months? - # - # [Hint] The -options switch sets the options of the subwidgets. - # [Hint] We set the label.width subwidget option of both comboboxes to - # be 10 so that their labels appear to be aligned. - # - a = tkinter.tix.ComboBox(top, label="Month: ", dropdown=1, - command=select_month, editable=0, variable=demo_month, - options='listbox.height 6 label.width 10 label.anchor e') - - # $w.top.b is a non-drop-down combo box. It is not editable: we provide - # four choices for the user, but he can enter an alternative year if he - # wants to. - # - # [Hint] Use the padY and anchor options of the label subwidget to - # align the label with the entry subwidget. - # [Hint] Notice that you should use padY (the NAME of the option) and not - # pady (the SWITCH of the option). - # - b = tkinter.tix.ComboBox(top, label="Year: ", dropdown=0, - command=select_year, editable=1, variable=demo_year, - options='listbox.height 4 label.padY 5 label.width 10 label.anchor ne') - - a.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - b.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - - a.insert(tkinter.tix.END, 'January') - a.insert(tkinter.tix.END, 'February') - a.insert(tkinter.tix.END, 'March') - a.insert(tkinter.tix.END, 'April') - a.insert(tkinter.tix.END, 'May') - a.insert(tkinter.tix.END, 'June') - a.insert(tkinter.tix.END, 'July') - a.insert(tkinter.tix.END, 'August') - a.insert(tkinter.tix.END, 'September') - a.insert(tkinter.tix.END, 'October') - a.insert(tkinter.tix.END, 'November') - a.insert(tkinter.tix.END, 'December') - - b.insert(tkinter.tix.END, '1992') - b.insert(tkinter.tix.END, '1993') - b.insert(tkinter.tix.END, '1994') - b.insert(tkinter.tix.END, '1995') - b.insert(tkinter.tix.END, '1996') - - # Use "tixSetSilent" to set the values of the combo box if you - # don't want your -command procedures (cbx:select_month and - # cbx:select_year) to be called. - # - a.set_silent('January') - b.set_silent('1995') - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=lambda w=w: ok_command(w)) - box.add('cancel', text='Cancel', underline=0, width=6, - command=lambda w=w: w.destroy()) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -def select_month(event=None): - # tixDemo:Status "Month = %s" % demo_month.get() - pass - -def select_year(event=None): - # tixDemo:Status "Year = %s" % demo_year.get() - pass - -def ok_command(w): - # tixDemo:Status "Month = %s, Year= %s" % (demo_month.get(), demo_year.get()) - w.destroy() - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/Control.py b/Demo/tix/samples/Control.py deleted file mode 100755 index fbc5e64..0000000 --- a/Demo/tix/samples/Control.py +++ /dev/null @@ -1,122 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixControl widget -- it is an -# entry widget with up/down arrow buttons. You can use the arrow buttons -# to adjust the value inside the entry widget. -# -# This example program uses three Control widgets. One lets you select -# integer values; one lets you select floating point values and the last -# one lets you select a few names. - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - control = DemoControl(root) - control.mainloop() - control.destroy() - -class DemoControl: - def __init__(self, w): - self.root = w - self.exit = -1 - - global demo_maker, demo_thrust, demo_num_engines - - demo_maker = tkinter.tix.StringVar() - demo_thrust = tkinter.tix.DoubleVar() - demo_num_engines = tkinter.tix.IntVar() - demo_maker.set('P&W') - demo_thrust.set(20000.0) - demo_num_engines.set(2) - - top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED) - - # $w.top.a allows only integer values - # - # [Hint] The -options switch sets the options of the subwidgets. - # [Hint] We set the label.width subwidget option of the Controls to - # be 16 so that their labels appear to be aligned. - # - a = tkinter.tix.Control(top, label='Number of Engines: ', integer=1, - variable=demo_num_engines, min=1, max=4, - options='entry.width 10 label.width 20 label.anchor e') - - b = tkinter.tix.Control(top, label='Thrust: ', integer=0, - min='10000.0', max='60000.0', step=500, - variable=demo_thrust, - options='entry.width 10 label.width 20 label.anchor e') - - c = tkinter.tix.Control(top, label='Engine Maker: ', value='P&W', - variable=demo_maker, - options='entry.width 10 label.width 20 label.anchor e') - - # We can't define these in the init because the widget 'c' doesn't - # exist yet and we need to reference it - c['incrcmd'] = lambda w=c: adjust_maker(w, 1) - c['decrcmd'] = lambda w=c: adjust_maker(w, -1) - c['validatecmd'] = lambda w=c: validate_maker(w) - - a.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - b.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - c.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=self.okcmd) - box.add('cancel', text='Cancel', underline=0, width=6, - command=self.quitcmd) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - - def okcmd (self): - # tixDemo:Status "Selected %d of %s engines each of thrust %d", (demo_num_engines.get(), demo_maker.get(), demo_thrust.get()) - self.quitcmd() - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -maker_list = ['P&W', 'GE', 'Rolls Royce'] - -def adjust_maker(w, inc): - i = maker_list.index(demo_maker.get()) - i = i + inc - if i >= len(maker_list): - i = 0 - elif i < 0: - i = len(maker_list) - 1 - - # In Tcl/Tix we should return the string maker_list[i]. We can't - # do that in Tkinter so we set the global variable. (This works). - demo_maker.set(maker_list[i]) - -def validate_maker(w): - try: - i = maker_list.index(demo_maker.get()) - except ValueError: - # Works here though. Why ? Beats me. - return maker_list[0] - # Works here though. Why ? Beats me. - return maker_list[i] - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/DirList.py b/Demo/tix/samples/DirList.py deleted file mode 100755 index 6d28ca3..0000000 --- a/Demo/tix/samples/DirList.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates the use of the tixDirList widget -- you can -# use it for the user to select a directory. For example, an installation -# program can use the tixDirList widget to ask the user to select the -# installation directory for an application. -# - -import tkinter.tix, os, copy -from tkinter.constants import * - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - dirlist = DemoDirList(root) - dirlist.mainloop() - dirlist.destroy() - -class DemoDirList: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # Create the tixDirList and the tixLabelEntry widgets on the on the top - # of the dialog box - - # bg = root.tk.eval('tix option get bg') - # adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0 - - top = tkinter.tix.Frame( w, relief=RAISED, bd=1) - - # Create the DirList widget. By default it will show the current - # directory - # - # - top.dir = tkinter.tix.DirList(top) - top.dir.hlist['width'] = 40 - - # When the user presses the ".." button, the selected directory - # is "transferred" into the entry widget - # - top.btn = tkinter.tix.Button(top, text = " >> ", pady = 0) - - # We use a LabelEntry to hold the installation directory. The user - # can choose from the DirList widget, or he can type in the directory - # manually - # - top.ent = tkinter.tix.LabelEntry(top, label="Installation Directory:", - labelside = 'top', - options = ''' - entry.width 40 - label.anchor w - ''') - - font = self.root.tk.eval('tix option get fixed_font') - # font = self.root.master.tix_option_get('fixed_font') - top.ent.entry['font'] = font - - self.dlist_dir = copy.copy(os.curdir) - # This should work setting the entry's textvariable - top.ent.entry['textvariable'] = self.dlist_dir - top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \ - self.copy_name(dir,ent) - - # top.ent.entry.insert(0,'tix'+repr(self)) - top.ent.entry.bind('<Return>', lambda self=self: self.okcmd () ) - - top.pack( expand='yes', fill='both', side=TOP) - top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT) - top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT) - top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT) - - # Use a ButtonBox to hold the buttons. - # - box = tkinter.tix.ButtonBox (w, orientation='horizontal') - box.add ('ok', text='Ok', underline=0, width=6, - command = lambda self=self: self.okcmd () ) - box.add ('cancel', text='Cancel', underline=0, width=6, - command = lambda self=self: self.quitcmd () ) - - box.pack( anchor='s', fill='x', side=BOTTOM) - - def copy_name (self, dir, ent): - # This should work as it is the entry's textvariable - self.dlist_dir = dir.cget('value') - # but it isn't so I'll do it manually - ent.entry.delete(0,'end') - ent.entry.insert(0, self.dlist_dir) - - def okcmd (self): - # tixDemo:Status "You have selected the directory" + self.dlist_dir - self.quitcmd() - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -# This "if" statement makes it possible to run this script file inside or -# outside of the main demo program "tixwidgets.py". -# -if __name__== '__main__' : - import tkinter.messagebox, traceback - - try: - root=tkinter.tix.Tk() - RunSample(root) - except: - t, v, tb = sys.exc_info() - text = "Error running the demo script:\n" - for line in traceback.format_exception(t,v,tb): - text = text + line + '\n' - d = tkinter.messagebox.showerror ( 'Tix Demo Error', text) diff --git a/Demo/tix/samples/DirTree.py b/Demo/tix/samples/DirTree.py deleted file mode 100755 index 5411ded..0000000 --- a/Demo/tix/samples/DirTree.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates the use of the tixDirTree widget -- you can -# use it for the user to select a directory. For example, an installation -# program can use the tixDirTree widget to ask the user to select the -# installation directory for an application. -# - -import tkinter.tix, os, copy -from tkinter.constants import * - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - dirtree = DemoDirTree(root) - dirtree.mainloop() - dirtree.destroy() - -class DemoDirTree: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # Create the tixDirTree and the tixLabelEntry widgets on the on the top - # of the dialog box - - # bg = root.tk.eval('tix option get bg') - # adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0 - - top = tkinter.tix.Frame( w, relief=RAISED, bd=1) - - # Create the DirTree widget. By default it will show the current - # directory - # - # - top.dir = tkinter.tix.DirTree(top) - top.dir.hlist['width'] = 40 - - # When the user presses the ".." button, the selected directory - # is "transferred" into the entry widget - # - top.btn = tkinter.tix.Button(top, text = " >> ", pady = 0) - - # We use a LabelEntry to hold the installation directory. The user - # can choose from the DirTree widget, or he can type in the directory - # manually - # - top.ent = tkinter.tix.LabelEntry(top, label="Installation Directory:", - labelside = 'top', - options = ''' - entry.width 40 - label.anchor w - ''') - - self.dlist_dir = copy.copy(os.curdir) - top.ent.entry['textvariable'] = self.dlist_dir - top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \ - self.copy_name(dir,ent) - - top.ent.entry.bind('<Return>', lambda self=self: self.okcmd () ) - - top.pack( expand='yes', fill='both', side=TOP) - top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT) - top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT) - top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT) - - # Use a ButtonBox to hold the buttons. - # - box = tkinter.tix.ButtonBox (w, orientation='horizontal') - box.add ('ok', text='Ok', underline=0, width=6, - command = lambda self=self: self.okcmd () ) - box.add ('cancel', text='Cancel', underline=0, width=6, - command = lambda self=self: self.quitcmd () ) - - box.pack( anchor='s', fill='x', side=BOTTOM) - - def copy_name (self, dir, ent): - # This should work as it is the entry's textvariable - self.dlist_dir = dir.cget('value') - # but it isn't so I'll do it manually - ent.entry.delete(0,'end') - ent.entry.insert(0, self.dlist_dir) - - def okcmd (self): - # tixDemo:Status "You have selected the directory" + self.dlist_dir - self.quitcmd() - - def quitcmd (self): - # tixDemo:Status "You have selected the directory" + self.dlist_dir - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -# This "if" statement makes it possible to run this script file inside or -# outside of the main demo program "tixwidgets.py". -# -if __name__== '__main__' : - root=tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/NoteBook.py b/Demo/tix/samples/NoteBook.py deleted file mode 100755 index d8b5fa8..0000000 --- a/Demo/tix/samples/NoteBook.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixNoteBook widget, which allows -# you to lay out your interface using a "notebook" metaphore -# -import tkinter.tix - -def RunSample(w): - global root - root = w - - # We use these options to set the sizes of the subwidgets inside the - # notebook, so that they are well-aligned on the screen. - prefix = tkinter.tix.OptionName(w) - if prefix: - prefix = '*'+prefix - else: - prefix = '' - w.option_add(prefix+'*TixControl*entry.width', 10) - w.option_add(prefix+'*TixControl*label.width', 18) - w.option_add(prefix+'*TixControl*label.anchor', tkinter.tix.E) - w.option_add(prefix+'*TixNoteBook*tagPadX', 8) - - # Create the notebook widget and set its backpagecolor to gray. - # Note that the -backpagecolor option belongs to the "nbframe" - # subwidget. - nb = tkinter.tix.NoteBook(w, name='nb', ipadx=6, ipady=6) - nb['bg'] = 'gray' - nb.nbframe['backpagecolor'] = 'gray' - - # Create the two tabs on the notebook. The -underline option - # puts a underline on the first character of the labels of the tabs. - # Keyboard accelerators will be defined automatically according - # to the underlined character. - nb.add('hard_disk', label="Hard Disk", underline=0) - nb.add('network', label="Network", underline=0) - - nb.pack(expand=1, fill=tkinter.tix.BOTH, padx=5, pady=5 ,side=tkinter.tix.TOP) - - #---------------------------------------- - # Create the first page - #---------------------------------------- - # Create two frames: one for the common buttons, one for the - # other widgets - # - tab=nb.hard_disk - f = tkinter.tix.Frame(tab) - common = tkinter.tix.Frame(tab) - - f.pack(side=tkinter.tix.LEFT, padx=2, pady=2, fill=tkinter.tix.BOTH, expand=1) - common.pack(side=tkinter.tix.RIGHT, padx=2, fill=tkinter.tix.Y) - - a = tkinter.tix.Control(f, value=12, label='Access time: ') - w = tkinter.tix.Control(f, value=400, label='Write Throughput: ') - r = tkinter.tix.Control(f, value=400, label='Read Throughput: ') - c = tkinter.tix.Control(f, value=1021, label='Capacity: ') - - a.pack(side=tkinter.tix.TOP, padx=20, pady=2) - w.pack(side=tkinter.tix.TOP, padx=20, pady=2) - r.pack(side=tkinter.tix.TOP, padx=20, pady=2) - c.pack(side=tkinter.tix.TOP, padx=20, pady=2) - - # Create the common buttons - createCommonButtons(common) - - #---------------------------------------- - # Create the second page - #---------------------------------------- - - tab = nb.network - - f = tkinter.tix.Frame(tab) - common = tkinter.tix.Frame(tab) - - f.pack(side=tkinter.tix.LEFT, padx=2, pady=2, fill=tkinter.tix.BOTH, expand=1) - common.pack(side=tkinter.tix.RIGHT, padx=2, fill=tkinter.tix.Y) - - a = tkinter.tix.Control(f, value=12, label='Access time: ') - w = tkinter.tix.Control(f, value=400, label='Write Throughput: ') - r = tkinter.tix.Control(f, value=400, label='Read Throughput: ') - c = tkinter.tix.Control(f, value=1021, label='Capacity: ') - u = tkinter.tix.Control(f, value=10, label='Users: ') - - a.pack(side=tkinter.tix.TOP, padx=20, pady=2) - w.pack(side=tkinter.tix.TOP, padx=20, pady=2) - r.pack(side=tkinter.tix.TOP, padx=20, pady=2) - c.pack(side=tkinter.tix.TOP, padx=20, pady=2) - u.pack(side=tkinter.tix.TOP, padx=20, pady=2) - - createCommonButtons(common) - -def doDestroy(): - global root - root.destroy() - -def createCommonButtons(master): - ok = tkinter.tix.Button(master, name='ok', text='OK', width=6, - command=doDestroy) - cancel = tkinter.tix.Button(master, name='cancel', - text='Cancel', width=6, - command=doDestroy) - - ok.pack(side=tkinter.tix.TOP, padx=2, pady=2) - cancel.pack(side=tkinter.tix.TOP, padx=2, pady=2) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/OptMenu.py b/Demo/tix/samples/OptMenu.py deleted file mode 100755 index d1dd46d..0000000 --- a/Demo/tix/samples/OptMenu.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixOptionMenu widget -- you can -# use it for the user to choose from a fixed set of options -# -import tkinter.tix - -options = {'text':'Plain Text', 'post':'PostScript', 'html':'HTML', - 'tex':'LaTeX', 'rtf':'Rich Text Format'} - -def RunSample(w): - global demo_opt_from, demo_opt_to - - demo_opt_from = tkinter.tix.StringVar() - demo_opt_to = tkinter.tix.StringVar() - - top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED) - - from_file = tkinter.tix.OptionMenu(top, label="From File Format : ", - variable=demo_opt_from, - options = 'label.width 19 label.anchor e menubutton.width 15') - - to_file = tkinter.tix.OptionMenu(top, label="To File Format : ", - variable=demo_opt_to, - options='label.width 19 label.anchor e menubutton.width 15') - - # Add the available options to the two OptionMenu widgets - # - # [Hint] You have to add the options first before you set the - # global variables "demo_opt_from" and "demo_opt_to". Otherwise - # the OptionMenu widget will complain about "unknown options"! - # - for opt in options.keys(): - from_file.add_command(opt, label=options[opt]) - to_file.add_command(opt, label=options[opt]) - - demo_opt_from.set('html') - demo_opt_to.set('post') - - from_file.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W, pady=3, padx=6) - to_file.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W, pady=3, padx=6) - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=lambda w=w: ok_command(w)) - box.add('cancel', text='Cancel', underline=0, width=6, - command=lambda w=w: w.destroy()) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -def ok_command(w): - # tixDemo:Status "Convert file from %s to %s" % ( demo_opt_from.get(), demo_opt_to.get()) - w.destroy() - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/PanedWin.py b/Demo/tix/samples/PanedWin.py deleted file mode 100755 index 1ffc470..0000000 --- a/Demo/tix/samples/PanedWin.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixPanedWindow widget. This program -# is a dummy news reader: the user can adjust the sizes of the list -# of artical names and the size of the text widget that shows the body -# of the article. - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - panedwin = DemoPanedwin(root) - panedwin.mainloop() - panedwin.destroy() - -class DemoPanedwin: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - group = tkinter.tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25') - group.entry.insert(0,'comp.lang.python') - pane = tkinter.tix.PanedWindow(w, orientation='vertical') - - p1 = pane.add('list', min=70, size=100) - p2 = pane.add('text', min=70) - list = tkinter.tix.ScrolledListBox(p1) - list.listbox['width'] = 80 - list.listbox['height'] = 5 - text = tkinter.tix.ScrolledText(p2) - text.text['width'] = 80 - text.text['height'] = 20 - - list.listbox.insert(tkinter.tix.END, " 12324 Re: Tkinter is good for your health") - list.listbox.insert(tkinter.tix.END, "+ 12325 Re: Tkinter is good for your health") - list.listbox.insert(tkinter.tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, " 12327 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, " 12329 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)") - - text.text['bg'] = list.listbox['bg'] - text.text['wrap'] = 'none' - text.text.insert(tkinter.tix.END, """ - Mon, 19 Jun 1995 11:39:52 comp.lang.python Thread 34 of 220 - Lines 353 A new way to put text and bitmaps together iNo responses - ioi@blue.seas.upenn.edu Ioi K. Lam at University of Pennsylvania - - Hi, - - I have implemented a new image type called "compound". It allows you - to glue together a bunch of bitmaps, images and text strings together - to form a bigger image. Then you can use this image with widgets that - support the -image option. For example, you can display a text string string - together with a bitmap, at the same time, inside a TK button widget. - """) - text.text['state'] = 'disabled' - - list.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6) - text.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6) - - group.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH) - pane.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH, expand=1) - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=self.quitcmd) - box.add('cancel', text='Cancel', underline=0, width=6, - command=self.quitcmd) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/PopMenu.py b/Demo/tix/samples/PopMenu.py deleted file mode 100755 index cb75d85..0000000 --- a/Demo/tix/samples/PopMenu.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates the use of the tixPopupMenu widget. -# -import tkinter.tix - -def RunSample(w): - # We create the frame and the button, then we'll bind the PopupMenu - # to both widgets. The result is, when you press the right mouse - # button over $w.top or $w.top.but, the PopupMenu will come up. - # - top = tkinter.tix.Frame(w, relief=tkinter.tix.RAISED, bd=1) - but = tkinter.tix.Button(top, text='Press the right mouse button over this button or its surrounding area') - but.pack(expand=1, fill=tkinter.tix.BOTH, padx=50, pady=50) - - p = tkinter.tix.PopupMenu(top, title='Popup Test') - p.bind_widget(top) - p.bind_widget(but) - - # Set the entries inside the PopupMenu widget. - # [Hint] You have to manipulate the "menu" subwidget. - # $w.top.p itself is NOT a menu widget. - # [Hint] Watch carefully how the sub-menu is created - # - p.menu.add_command(label='Desktop', underline=0) - p.menu.add_command(label='Select', underline=0) - p.menu.add_command(label='Find', underline=0) - p.menu.add_command(label='System', underline=1) - p.menu.add_command(label='Help', underline=0) - m1 = tkinter.tix.Menu(p.menu) - m1.add_command(label='Hello') - p.menu.add_cascade(label='More', menu=m1) - - but.pack(side=tkinter.tix.TOP, padx=40, pady=50) - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=lambda w=w: w.destroy()) - box.add('cancel', text='Cancel', underline=0, width=6, - command=lambda w=w: w.destroy()) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/SHList1.py b/Demo/tix/samples/SHList1.py deleted file mode 100755 index bf46020..0000000 --- a/Demo/tix/samples/SHList1.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates the use of the tixScrolledHList widget. -# - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - shlist = DemoSHList(root) - shlist.mainloop() - shlist.destroy() - -class DemoSHList: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # We create the frame and the ScrolledHList widget - # at the top of the dialog box - # - top = tkinter.tix.Frame( w, relief=tkinter.tix.RAISED, bd=1) - - # Put a simple hierachy into the HList (two levels). Use colors and - # separator widgets (frames) to make the list look fancy - # - top.a = tkinter.tix.ScrolledHList(top) - top.a.pack( expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.tix.TOP) - - # This is our little relational database - # - bosses = [ - ('jeff', 'Jeff Waxman'), - ('john', 'John Lee'), - ('peter', 'Peter Kenson') - ] - - employees = [ - ('alex', 'john', 'Alex Kellman'), - ('alan', 'john', 'Alan Adams'), - ('andy', 'peter', 'Andreas Crawford'), - ('doug', 'jeff', 'Douglas Bloom'), - ('jon', 'peter', 'Jon Baraki'), - ('chris', 'jeff', 'Chris Geoffrey'), - ('chuck', 'jeff', 'Chuck McLean') - ] - - hlist=top.a.hlist - - # Let configure the appearance of the HList subwidget - # - hlist.config( separator='.', width=25, drawbranch=0, indent=10) - - count=0 - for boss,name in bosses : - if count : - f=tkinter.tix.Frame(hlist, name='sep%d' % count, height=2, width=150, - bd=2, relief=tkinter.tix.SUNKEN ) - - hlist.add_child( itemtype=tkinter.tix.WINDOW, - window=f, state=tkinter.tix.DISABLED ) - - hlist.add(boss, itemtype=tkinter.tix.TEXT, text=name) - count = count+1 - - - for person,boss,name in employees : - # '.' is the separator character we chose above - # - key= boss + '.' + person - # ^^^^ ^^^^^^ - # parent entryPath / child's name - - hlist.add( key, text=name ) - - # [Hint] Make sure the keys (e.g. 'boss.person') you choose - # are unique names. If you cannot be sure of this (because of - # the structure of your database, e.g.) you can use the - # "add_child" command instead: - # - # hlist.addchild( boss, text=name) - # ^^^^ - # parent entryPath - - - # Use a ButtonBox to hold the buttons. - # - box= tkinter.tix.ButtonBox(top, orientation=tkinter.tix.HORIZONTAL ) - box.add( 'ok', text='Ok', underline=0, width=6, - command = self.okcmd) - - box.add( 'cancel', text='Cancel', underline=0, width=6, - command = self.quitcmd) - - box.pack( side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack( side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1 ) - - def okcmd (self): - self.quitcmd() - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - - -# This "if" statement makes it possible to run this script file inside or -# outside of the main demo program "tixwidgets.py". -# -if __name__== '__main__' : - root=tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/SHList2.py b/Demo/tix/samples/SHList2.py deleted file mode 100755 index 370c765..0000000 --- a/Demo/tix/samples/SHList2.py +++ /dev/null @@ -1,168 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidget": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates how to use multiple columns and multiple styles -# in the tixHList widget -# -# In a tixHList widget, you can have one ore more columns. -# - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - shlist = DemoSHList(root) - shlist.mainloop() - shlist.destroy() - -class DemoSHList: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # We create the frame and the ScrolledHList widget - # at the top of the dialog box - # - top = tkinter.tix.Frame( w, relief=tkinter.tix.RAISED, bd=1) - - # Put a simple hierachy into the HList (two levels). Use colors and - # separator widgets (frames) to make the list look fancy - # - top.a = tkinter.tix.ScrolledHList(top, options='hlist.columns 3 hlist.header 1' ) - top.a.pack( expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.tix.TOP) - - hlist=top.a.hlist - - # Create the title for the HList widget - # >> Notice that we have set the hlist.header subwidget option to true - # so that the header is displayed - # - - boldfont=hlist.tk.call('tix','option','get','bold_font') - - # First some styles for the headers - style={} - style['header'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist, - anchor=tkinter.tix.CENTER, padx=8, pady=2, font = boldfont ) - - hlist.header_create(0, itemtype=tkinter.tix.TEXT, text='Name', - style=style['header']) - hlist.header_create(1, itemtype=tkinter.tix.TEXT, text='Position', - style=style['header']) - - # Notice that we use 3 columns in the hlist widget. This way when the user - # expands the windows wide, the right side of the header doesn't look - # chopped off. The following line ensures that the 3 column header is - # not shown unless the hlist window is wider than its contents. - # - hlist.column_width(2,0) - - # This is our little relational database - # - boss = ('doe', 'John Doe', 'Director') - - managers = [ - ('jeff', 'Jeff Waxman', 'Manager'), - ('john', 'John Lee', 'Manager'), - ('peter', 'Peter Kenson', 'Manager') - ] - - employees = [ - ('alex', 'john', 'Alex Kellman', 'Clerk'), - ('alan', 'john', 'Alan Adams', 'Clerk'), - ('andy', 'peter', 'Andreas Crawford', 'Salesman'), - ('doug', 'jeff', 'Douglas Bloom', 'Clerk'), - ('jon', 'peter', 'Jon Baraki', 'Salesman'), - ('chris', 'jeff', 'Chris Geoffrey', 'Clerk'), - ('chuck', 'jeff', 'Chuck McLean', 'Cleaner') - ] - - style['mgr_name'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist) - - style['mgr_posn'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, padx=8, refwindow=hlist) - - style['empl_name'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist) - - style['empl_posn'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, padx=8, refwindow=hlist) - - # Let configure the appearance of the HList subwidget - # - hlist.config(separator='.', width=25, drawbranch=0, indent=10) - hlist.column_width(0, chars=20) - - # Create the boss - # - hlist.add ('.', itemtype=tkinter.tix.TEXT, text=boss[1], - style=style['mgr_name']) - hlist.item_create('.', 1, itemtype=tkinter.tix.TEXT, text=boss[2], - style=style['mgr_posn']) - - # Create the managers - # - - for key,name,posn in managers : - e= '.'+ key - hlist.add(e, itemtype=tkinter.tix.TEXT, text=name, - style=style['mgr_name']) - hlist.item_create(e, 1, itemtype=tkinter.tix.TEXT, text=posn, - style=style['mgr_posn']) - - - for key,mgr,name,posn in employees : - # "." is the separator character we chose above - - entrypath = '.' + mgr + '.' + key - - # ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ - # parent entryPath / child's name - - hlist.add(entrypath, text=name, style=style['empl_name']) - hlist.item_create(entrypath, 1, itemtype=tkinter.tix.TEXT, - text = posn, style = style['empl_posn'] ) - - - # Use a ButtonBox to hold the buttons. - # - box= tkinter.tix.ButtonBox(top, orientation=tkinter.tix.HORIZONTAL ) - box.add( 'ok', text='Ok', underline=0, width=6, - command = self.okcmd ) - - box.add( 'cancel', text='Cancel', underline=0, width=6, - command = self.quitcmd ) - - box.pack( side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack( side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1 ) - - def okcmd (self): - self.quitcmd() - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - - -# This "if" statement makes it possible to run this script file inside or -# outside of the main demo program "tixwidgets.py". -# -if __name__== '__main__' : - root=tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/Tree.py b/Demo/tix/samples/Tree.py deleted file mode 100755 index e46ff60..0000000 --- a/Demo/tix/samples/Tree.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates how to use the TixTree widget to display -# dynamic hierachical data (the files in the Unix file system) -# - -import tkinter.tix, os - -def RunSample(w): - top = tkinter.tix.Frame(w, relief=tkinter.tix.RAISED, bd=1) - tree = tkinter.tix.Tree(top, options='separator "/"') - tree.pack(expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.tix.LEFT) - tree['opencmd'] = lambda dir=None, w=tree: opendir(w, dir) - - # The / directory is added in the "open" mode. The user can open it - # and then browse its subdirectories ... - adddir(tree, "/") - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, command=w.destroy, width=6) - box.add('cancel', text='Cancel', underline=0, command=w.destroy, width=6) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -def adddir(tree, dir): - if dir == '/': - text = '/' - else: - text = os.path.basename(dir) - tree.hlist.add(dir, itemtype=tkinter.tix.IMAGETEXT, text=text, - image=tree.tk.call('tix', 'getimage', 'folder')) - try: - os.listdir(dir) - tree.setmode(dir, 'open') - except os.error: - # No read permission ? - pass - -# This function is called whenever the user presses the (+) indicator or -# double clicks on a directory whose mode is "open". It loads the files -# inside that directory into the Tree widget. -# -# Note we didn't specify the closecmd option for the Tree widget, so it -# performs the default action when the user presses the (-) indicator or -# double clicks on a directory whose mode is "close": hide all of its child -# entries -def opendir(tree, dir): - entries = tree.hlist.info_children(dir) - if entries: - # We have already loaded this directory. Let's just - # show all the child entries - # - # Note: since we load the directory only once, it will not be - # refreshed if the you add or remove files from this - # directory. - # - for entry in entries: - tree.hlist.show_entry(entry) - files = os.listdir(dir) - for file in files: - if os.path.isdir(dir + '/' + file): - adddir(tree, dir + '/' + file) - else: - tree.hlist.add(dir + '/' + file, itemtype=tkinter.tix.IMAGETEXT, text=file, - image=tree.tk.call('tix', 'getimage', 'file')) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/tixwidgets.py b/Demo/tix/tixwidgets.py deleted file mode 100644 index 42bcedc..0000000 --- a/Demo/tix/tixwidgets.py +++ /dev/null @@ -1,1002 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# tixwidgets.py -- -# -# For Tix, see http://tix.sourceforge.net -# -# This is a demo program of some of the Tix widgets available in Python. -# If you have installed Python & Tix properly, you can execute this as -# -# % python tixwidgets.py -# - -import os, os.path, sys, tkinter.tix -from tkinter.constants import * -import traceback, tkinter.messagebox - -TCL_DONT_WAIT = 1<<1 -TCL_WINDOW_EVENTS = 1<<2 -TCL_FILE_EVENTS = 1<<3 -TCL_TIMER_EVENTS = 1<<4 -TCL_IDLE_EVENTS = 1<<5 -TCL_ALL_EVENTS = 0 - -class Demo: - def __init__(self, top): - self.root = top - self.exit = -1 - - self.dir = None # script directory - self.balloon = None # balloon widget - self.useBalloons = tkinter.tix.StringVar() - self.useBalloons.set('0') - self.statusbar = None # status bar widget - self.welmsg = None # Msg widget - self.welfont = '' # font name - self.welsize = '' # font size - - progname = sys.argv[0] - dirname = os.path.dirname(progname) - if dirname and dirname != os.curdir: - self.dir = dirname - index = -1 - for i in range(len(sys.path)): - p = sys.path[i] - if p in ("", os.curdir): - index = i - if index >= 0: - sys.path[index] = dirname - else: - sys.path.insert(0, dirname) - else: - self.dir = os.getcwd() - sys.path.insert(0, self.dir+'/samples') - - def MkMainMenu(self): - top = self.root - w = tkinter.tix.Frame(top, bd=2, relief=RAISED) - file = tkinter.tix.Menubutton(w, text='File', underline=0, takefocus=0) - help = tkinter.tix.Menubutton(w, text='Help', underline=0, takefocus=0) - file.pack(side=LEFT) - help.pack(side=RIGHT) - fm = tkinter.tix.Menu(file, tearoff=0) - file['menu'] = fm - hm = tkinter.tix.Menu(help, tearoff=0) - help['menu'] = hm - - fm.add_command(label='Exit', underline=1, - command = lambda self=self: self.quitcmd () ) - hm.add_checkbutton(label='BalloonHelp', underline=0, command=ToggleHelp, - variable=self.useBalloons) - # The trace variable option doesn't seem to work, instead I use 'command' - #w.tk.call('trace', 'variable', self.useBalloons, 'w', ToggleHelp)) - - return w - - def MkMainNotebook(self): - top = self.root - w = tkinter.tix.NoteBook(top, ipadx=5, ipady=5, options=""" - tagPadX 6 - tagPadY 4 - borderWidth 2 - """) - # This may be required if there is no *Background option - top['bg'] = w['bg'] - - w.add('wel', label='Welcome', underline=0, - createcmd=lambda w=w, name='wel': MkWelcome(w, name)) - w.add('cho', label='Choosers', underline=0, - createcmd=lambda w=w, name='cho': MkChoosers(w, name)) - w.add('scr', label='Scrolled Widgets', underline=0, - createcmd=lambda w=w, name='scr': MkScroll(w, name)) - w.add('mgr', label='Manager Widgets', underline=0, - createcmd=lambda w=w, name='mgr': MkManager(w, name)) - w.add('dir', label='Directory List', underline=0, - createcmd=lambda w=w, name='dir': MkDirList(w, name)) - w.add('exp', label='Run Sample Programs', underline=0, - createcmd=lambda w=w, name='exp': MkSample(w, name)) - return w - - def MkMainStatus(self): - global demo - top = self.root - - w = tkinter.tix.Frame(top, relief=tkinter.tix.RAISED, bd=1) - demo.statusbar = tkinter.tix.Label(w, relief=tkinter.tix.SUNKEN, bd=1) - demo.statusbar.form(padx=3, pady=3, left=0, right='%70') - return w - - def build(self): - root = self.root - z = root.winfo_toplevel() - z.wm_title('Tix Widget Demonstration') - if z.winfo_screenwidth() <= 800: - z.geometry('790x590+10+10') - else: - z.geometry('890x640+10+10') - demo.balloon = tkinter.tix.Balloon(root) - frame1 = self.MkMainMenu() - frame2 = self.MkMainNotebook() - frame3 = self.MkMainStatus() - frame1.pack(side=TOP, fill=X) - frame3.pack(side=BOTTOM, fill=X) - frame2.pack(side=TOP, expand=1, fill=BOTH, padx=4, pady=4) - demo.balloon['statusbar'] = demo.statusbar - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # To show Tcl errors - uncomment this to see the listbox bug. - # Tkinter defines a Tcl tkerror procedure that in effect - # silences all background Tcl error reporting. - # root.tk.eval('if {[info commands tkerror] != ""} {rename tkerror pytkerror}') - def quitcmd (self): - """Quit our mainloop. It is up to you to call root.destroy() after.""" - self.exit = 0 - - def loop(self): - """This is an explict replacement for _tkinter mainloop() - It lets you catch keyboard interrupts easier, and avoids - the 20 msec. dead sleep() which burns a constant CPU.""" - while self.exit < 0: - # There are 2 whiles here. The outer one lets you continue - # after a ^C interrupt. - try: - # This is the replacement for _tkinter mainloop() - # It blocks waiting for the next Tcl event using select. - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - except SystemExit: - # Tkinter uses SystemExit to exit - #print 'Exit' - self.exit = 1 - return - except KeyboardInterrupt: - if tkinter.messagebox.askquestion ('Interrupt', 'Really Quit?') == 'yes': - # self.tk.eval('exit') - self.exit = 1 - return - continue - except: - # Otherwise it's some other error - be nice and say why - t, v, tb = sys.exc_info() - text = "" - for line in traceback.format_exception(t,v,tb): - text += line + '\n' - try: tkinter.messagebox.showerror ('Error', text) - except: pass - self.exit = 1 - raise SystemExit(1) - - def destroy (self): - self.root.destroy() - -def RunMain(root): - global demo - - demo = Demo(root) - - demo.build() - demo.loop() - demo.destroy() - -# Tabs -def MkWelcome(nb, name): - w = nb.page(name) - bar = MkWelcomeBar(w) - text = MkWelcomeText(w) - bar.pack(side=TOP, fill=X, padx=2, pady=2) - text.pack(side=TOP, fill=BOTH, expand=1) - -def MkWelcomeBar(top): - global demo - - w = tkinter.tix.Frame(top, bd=2, relief=tkinter.tix.GROOVE) - b1 = tkinter.tix.ComboBox(w, command=lambda w=top: MainTextFont(w)) - b2 = tkinter.tix.ComboBox(w, command=lambda w=top: MainTextFont(w)) - b1.entry['width'] = 15 - b1.slistbox.listbox['height'] = 3 - b2.entry['width'] = 4 - b2.slistbox.listbox['height'] = 3 - - demo.welfont = b1 - demo.welsize = b2 - - b1.insert(tkinter.tix.END, 'Courier') - b1.insert(tkinter.tix.END, 'Helvetica') - b1.insert(tkinter.tix.END, 'Lucida') - b1.insert(tkinter.tix.END, 'Times Roman') - - b2.insert(tkinter.tix.END, '8') - b2.insert(tkinter.tix.END, '10') - b2.insert(tkinter.tix.END, '12') - b2.insert(tkinter.tix.END, '14') - b2.insert(tkinter.tix.END, '18') - - b1.pick(1) - b2.pick(3) - - b1.pack(side=tkinter.tix.LEFT, padx=4, pady=4) - b2.pack(side=tkinter.tix.LEFT, padx=4, pady=4) - - demo.balloon.bind_widget(b1, msg='Choose\na font', - statusmsg='Choose a font for this page') - demo.balloon.bind_widget(b2, msg='Point size', - statusmsg='Choose the font size for this page') - return w - -def MkWelcomeText(top): - global demo - - w = tkinter.tix.ScrolledWindow(top, scrollbar='auto') - win = w.window - text = 'Welcome to TIX in Python' - title = tkinter.tix.Label(win, - bd=0, width=30, anchor=tkinter.tix.N, text=text) - msg = tkinter.tix.Message(win, - bd=0, width=400, anchor=tkinter.tix.N, - text='Tix is a set of mega-widgets based on TK. This program \ -demonstrates the widgets in the Tix widget set. You can choose the pages \ -in this window to look at the corresponding widgets. \n\n\ -To quit this program, choose the "File | Exit" command.\n\n\ -For more information, see http://tix.sourceforge.net.') - title.pack(expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10) - msg.pack(expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10) - demo.welmsg = msg - return w - -def MainTextFont(w): - global demo - - if not demo.welmsg: - return - font = demo.welfont['value'] - point = demo.welsize['value'] - if font == 'Times Roman': - font = 'times' - fontstr = '%s %s' % (font, point) - demo.welmsg['font'] = fontstr - -def ToggleHelp(): - if demo.useBalloons.get() == '1': - demo.balloon['state'] = 'both' - else: - demo.balloon['state'] = 'none' - -def MkChoosers(nb, name): - w = nb.page(name) - options = "label.padX 4" - - til = tkinter.tix.LabelFrame(w, label='Chooser Widgets', options=options) - cbx = tkinter.tix.LabelFrame(w, label='tixComboBox', options=options) - ctl = tkinter.tix.LabelFrame(w, label='tixControl', options=options) - sel = tkinter.tix.LabelFrame(w, label='tixSelect', options=options) - opt = tkinter.tix.LabelFrame(w, label='tixOptionMenu', options=options) - fil = tkinter.tix.LabelFrame(w, label='tixFileEntry', options=options) - fbx = tkinter.tix.LabelFrame(w, label='tixFileSelectBox', options=options) - tbr = tkinter.tix.LabelFrame(w, label='Tool Bar', options=options) - - MkTitle(til.frame) - MkCombo(cbx.frame) - MkControl(ctl.frame) - MkSelect(sel.frame) - MkOptMenu(opt.frame) - MkFileEnt(fil.frame) - MkFileBox(fbx.frame) - MkToolBar(tbr.frame) - - # First column: comBox and selector - cbx.form(top=0, left=0, right='%33') - sel.form(left=0, right='&'+str(cbx), top=cbx) - opt.form(left=0, right='&'+str(cbx), top=sel, bottom=-1) - - # Second column: title .. etc - til.form(left=cbx, top=0,right='%66') - ctl.form(left=cbx, right='&'+str(til), top=til) - fil.form(left=cbx, right='&'+str(til), top=ctl) - tbr.form(left=cbx, right='&'+str(til), top=fil, bottom=-1) - - # - # Third column: file selection - fbx.form(right=-1, top=0, left='%66') - -def MkCombo(w): - options="label.width %d label.anchor %s entry.width %d" % (10, tkinter.tix.E, 14) - - static = tkinter.tix.ComboBox(w, label='Static', editable=0, options=options) - editable = tkinter.tix.ComboBox(w, label='Editable', editable=1, options=options) - history = tkinter.tix.ComboBox(w, label='History', editable=1, history=1, - anchor=tkinter.tix.E, options=options) - static.insert(tkinter.tix.END, 'January') - static.insert(tkinter.tix.END, 'February') - static.insert(tkinter.tix.END, 'March') - static.insert(tkinter.tix.END, 'April') - static.insert(tkinter.tix.END, 'May') - static.insert(tkinter.tix.END, 'June') - static.insert(tkinter.tix.END, 'July') - static.insert(tkinter.tix.END, 'August') - static.insert(tkinter.tix.END, 'September') - static.insert(tkinter.tix.END, 'October') - static.insert(tkinter.tix.END, 'November') - static.insert(tkinter.tix.END, 'December') - - editable.insert(tkinter.tix.END, 'Angola') - editable.insert(tkinter.tix.END, 'Bangladesh') - editable.insert(tkinter.tix.END, 'China') - editable.insert(tkinter.tix.END, 'Denmark') - editable.insert(tkinter.tix.END, 'Ecuador') - - history.insert(tkinter.tix.END, '/usr/bin/ksh') - history.insert(tkinter.tix.END, '/usr/local/lib/python') - history.insert(tkinter.tix.END, '/var/adm') - - static.pack(side=tkinter.tix.TOP, padx=5, pady=3) - editable.pack(side=tkinter.tix.TOP, padx=5, pady=3) - history.pack(side=tkinter.tix.TOP, padx=5, pady=3) - -states = ['Bengal', 'Delhi', 'Karnataka', 'Tamil Nadu'] - -def spin_cmd(w, inc): - idx = states.index(demo_spintxt.get()) + inc - if idx < 0: - idx = len(states) - 1 - elif idx >= len(states): - idx = 0 -# following doesn't work. -# return states[idx] - demo_spintxt.set(states[idx]) # this works - -def spin_validate(w): - global states, demo_spintxt - - try: - i = states.index(demo_spintxt.get()) - except ValueError: - return states[0] - return states[i] - # why this procedure works as opposed to the previous one beats me. - -def MkControl(w): - global demo_spintxt - - options="label.width %d label.anchor %s entry.width %d" % (10, tkinter.tix.E, 13) - - demo_spintxt = tkinter.tix.StringVar() - demo_spintxt.set(states[0]) - simple = tkinter.tix.Control(w, label='Numbers', options=options) - spintxt = tkinter.tix.Control(w, label='States', variable=demo_spintxt, - options=options) - spintxt['incrcmd'] = lambda w=spintxt: spin_cmd(w, 1) - spintxt['decrcmd'] = lambda w=spintxt: spin_cmd(w, -1) - spintxt['validatecmd'] = lambda w=spintxt: spin_validate(w) - - simple.pack(side=tkinter.tix.TOP, padx=5, pady=3) - spintxt.pack(side=tkinter.tix.TOP, padx=5, pady=3) - -def MkSelect(w): - options = "label.anchor %s" % tkinter.tix.CENTER - - sel1 = tkinter.tix.Select(w, label='Mere Mortals', allowzero=1, radio=1, - orientation=tkinter.tix.VERTICAL, - labelside=tkinter.tix.TOP, - options=options) - sel2 = tkinter.tix.Select(w, label='Geeks', allowzero=1, radio=0, - orientation=tkinter.tix.VERTICAL, - labelside= tkinter.tix.TOP, - options=options) - - sel1.add('eat', text='Eat') - sel1.add('work', text='Work') - sel1.add('play', text='Play') - sel1.add('party', text='Party') - sel1.add('sleep', text='Sleep') - - sel2.add('eat', text='Eat') - sel2.add('prog1', text='Program') - sel2.add('prog2', text='Program') - sel2.add('prog3', text='Program') - sel2.add('sleep', text='Sleep') - - sel1.pack(side=tkinter.tix.LEFT, padx=5, pady=3, fill=tkinter.tix.X) - sel2.pack(side=tkinter.tix.LEFT, padx=5, pady=3, fill=tkinter.tix.X) - -def MkOptMenu(w): - options='menubutton.width 15 label.anchor %s' % tkinter.tix.E - - m = tkinter.tix.OptionMenu(w, label='File Format : ', options=options) - m.add_command('text', label='Plain Text') - m.add_command('post', label='PostScript') - m.add_command('format', label='Formatted Text') - m.add_command('html', label='HTML') - m.add_command('sep') - m.add_command('tex', label='LaTeX') - m.add_command('rtf', label='Rich Text Format') - - m.pack(fill=tkinter.tix.X, padx=5, pady=3) - -def MkFileEnt(w): - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='Press the "open file" icon button and a TixFileSelectDialog will popup.') - ent = tkinter.tix.FileEntry(w, label='Select a file : ') - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - ent.pack(side=tkinter.tix.TOP, fill=tkinter.tix.X, padx=3, pady=3) - -def MkFileBox(w): - """The FileSelectBox is a Motif-style box with various enhancements. - For example, you can adjust the size of the two listboxes - and your past selections are recorded. - """ - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The Tix FileSelectBox is a Motif-style box with various enhancements. For example, you can adjust the size of the two listboxes and your past selections are recorded.') - box = tkinter.tix.FileSelectBox(w) - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - box.pack(side=tkinter.tix.TOP, fill=tkinter.tix.X, padx=3, pady=3) - -def MkToolBar(w): - """The Select widget is also good for arranging buttons in a tool bar. - """ - global demo - - options='frame.borderWidth 1' - - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The Select widget is also good for arranging buttons in a tool bar.') - bar = tkinter.tix.Frame(w, bd=2, relief=tkinter.tix.RAISED) - font = tkinter.tix.Select(w, allowzero=1, radio=0, label='', options=options) - para = tkinter.tix.Select(w, allowzero=0, radio=1, label='', options=options) - - font.add('bold', bitmap='@' + demo.dir + '/bitmaps/bold.xbm') - font.add('italic', bitmap='@' + demo.dir + '/bitmaps/italic.xbm') - font.add('underline', bitmap='@' + demo.dir + '/bitmaps/underline.xbm') - font.add('capital', bitmap='@' + demo.dir + '/bitmaps/capital.xbm') - - para.add('left', bitmap='@' + demo.dir + '/bitmaps/leftj.xbm') - para.add('right', bitmap='@' + demo.dir + '/bitmaps/rightj.xbm') - para.add('center', bitmap='@' + demo.dir + '/bitmaps/centerj.xbm') - para.add('justify', bitmap='@' + demo.dir + '/bitmaps/justify.xbm') - - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - bar.pack(side=tkinter.tix.TOP, fill=tkinter.tix.X, padx=3, pady=3) - font.pack({'in':bar}, side=tkinter.tix.LEFT, padx=3, pady=3) - para.pack({'in':bar}, side=tkinter.tix.LEFT, padx=3, pady=3) - -def MkTitle(w): - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='There are many types of "chooser" widgets that allow the user to input different types of information') - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - -def MkScroll(nb, name): - w = nb.page(name) - options='label.padX 4' - - sls = tkinter.tix.LabelFrame(w, label='Tix.ScrolledListBox', options=options) - swn = tkinter.tix.LabelFrame(w, label='Tix.ScrolledWindow', options=options) - stx = tkinter.tix.LabelFrame(w, label='Tix.ScrolledText', options=options) - - MkSList(sls.frame) - MkSWindow(swn.frame) - MkSText(stx.frame) - - sls.form(top=0, left=0, right='%33', bottom=-1) - swn.form(top=0, left=sls, right='%66', bottom=-1) - stx.form(top=0, left=swn, right=-1, bottom=-1) - - -def MkSList(w): - """This TixScrolledListBox is configured so that it uses scrollbars - only when it is necessary. Use the handles to resize the listbox and - watch the scrollbars automatically appear and disappear. """ - top = tkinter.tix.Frame(w, width=300, height=330) - bot = tkinter.tix.Frame(w) - msg = tkinter.tix.Message(top, - relief=tkinter.tix.FLAT, width=200, anchor=tkinter.tix.N, - text='This TixScrolledListBox is configured so that it uses scrollbars only when it is necessary. Use the handles to resize the listbox and watch the scrollbars automatically appear and disappear.') - - list = tkinter.tix.ScrolledListBox(top, scrollbar='auto') - list.place(x=50, y=150, width=120, height=80) - list.listbox.insert(tkinter.tix.END, 'Alabama') - list.listbox.insert(tkinter.tix.END, 'California') - list.listbox.insert(tkinter.tix.END, 'Montana') - list.listbox.insert(tkinter.tix.END, 'New Jersey') - list.listbox.insert(tkinter.tix.END, 'New York') - list.listbox.insert(tkinter.tix.END, 'Pennsylvania') - list.listbox.insert(tkinter.tix.END, 'Washington') - - rh = tkinter.tix.ResizeHandle(top, bg='black', - relief=tkinter.tix.RAISED, - handlesize=8, gridded=1, minwidth=50, minheight=30) - btn = tkinter.tix.Button(bot, text='Reset', command=lambda w=rh, x=list: SList_reset(w,x)) - top.propagate(0) - msg.pack(fill=tkinter.tix.X) - btn.pack(anchor=tkinter.tix.CENTER) - top.pack(expand=1, fill=tkinter.tix.BOTH) - bot.pack(fill=tkinter.tix.BOTH) - list.bind('<Map>', func=lambda arg=0, rh=rh, list=list: - list.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(list))) - -def SList_reset(rh, list): - list.place(x=50, y=150, width=120, height=80) - list.update() - rh.attach_widget(list) - -def MkSWindow(w): - """The ScrolledWindow widget allows you to scroll any kind of Tk - widget. It is more versatile than a scrolled canvas widget. - """ - global demo - - text = 'The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.' - - file = os.path.join(demo.dir, 'bitmaps', 'tix.gif') - if not os.path.isfile(file): - text += ' (Image missing)' - - top = tkinter.tix.Frame(w, width=330, height=330) - bot = tkinter.tix.Frame(w) - msg = tkinter.tix.Message(top, - relief=tkinter.tix.FLAT, width=200, anchor=tkinter.tix.N, - text=text) - - win = tkinter.tix.ScrolledWindow(top, scrollbar='auto') - - image1 = win.window.image_create('photo', file=file) - lbl = tkinter.tix.Label(win.window, image=image1) - lbl.pack(expand=1, fill=tkinter.tix.BOTH) - - win.place(x=30, y=150, width=190, height=120) - - rh = tkinter.tix.ResizeHandle(top, bg='black', - relief=tkinter.tix.RAISED, - handlesize=8, gridded=1, minwidth=50, minheight=30) - btn = tkinter.tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SWindow_reset(w,x)) - top.propagate(0) - msg.pack(fill=tkinter.tix.X) - btn.pack(anchor=tkinter.tix.CENTER) - top.pack(expand=1, fill=tkinter.tix.BOTH) - bot.pack(fill=tkinter.tix.BOTH) - - win.bind('<Map>', func=lambda arg=0, rh=rh, win=win: - win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win))) - -def SWindow_reset(rh, win): - win.place(x=30, y=150, width=190, height=120) - win.update() - rh.attach_widget(win) - -def MkSText(w): - """The TixScrolledWindow widget allows you to scroll any kind of Tk - widget. It is more versatile than a scrolled canvas widget.""" - top = tkinter.tix.Frame(w, width=330, height=330) - bot = tkinter.tix.Frame(w) - msg = tkinter.tix.Message(top, - relief=tkinter.tix.FLAT, width=200, anchor=tkinter.tix.N, - text='The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.') - - win = tkinter.tix.ScrolledText(top, scrollbar='auto') - win.text['wrap'] = 'none' - win.text.insert(tkinter.tix.END, '''When -scrollbar is set to "auto", the -scrollbars are shown only when needed. -Additional modifiers can be used to force a -scrollbar to be shown or hidden. For example, -"auto -y" means the horizontal scrollbar -should be shown when needed but the vertical -scrollbar should always be hidden; -"auto +x" means the vertical scrollbar -should be shown when needed but the horizontal -scrollbar should always be shown, and so on.''' -) - win.place(x=30, y=150, width=190, height=100) - - rh = tkinter.tix.ResizeHandle(top, bg='black', - relief=tkinter.tix.RAISED, - handlesize=8, gridded=1, minwidth=50, minheight=30) - btn = tkinter.tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SText_reset(w,x)) - top.propagate(0) - msg.pack(fill=tkinter.tix.X) - btn.pack(anchor=tkinter.tix.CENTER) - top.pack(expand=1, fill=tkinter.tix.BOTH) - bot.pack(fill=tkinter.tix.BOTH) - win.bind('<Map>', func=lambda arg=0, rh=rh, win=win: - win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win))) - -def SText_reset(rh, win): - win.place(x=30, y=150, width=190, height=120) - win.update() - rh.attach_widget(win) - -def MkManager(nb, name): - w = nb.page(name) - options='label.padX 4' - - pane = tkinter.tix.LabelFrame(w, label='Tix.PanedWindow', options=options) - note = tkinter.tix.LabelFrame(w, label='Tix.NoteBook', options=options) - - MkPanedWindow(pane.frame) - MkNoteBook(note.frame) - - pane.form(top=0, left=0, right=note, bottom=-1) - note.form(top=0, right=-1, bottom=-1) - -def MkPanedWindow(w): - """The PanedWindow widget allows the user to interactively manipulate - the sizes of several panes. The panes can be arranged either vertically - or horizontally. - """ - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The PanedWindow widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally.') - group = tkinter.tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25') - group.entry.insert(0,'comp.lang.python') - pane = tkinter.tix.PanedWindow(w, orientation='vertical') - - p1 = pane.add('list', min=70, size=100) - p2 = pane.add('text', min=70) - list = tkinter.tix.ScrolledListBox(p1) - text = tkinter.tix.ScrolledText(p2) - - list.listbox.insert(tkinter.tix.END, " 12324 Re: Tkinter is good for your health") - list.listbox.insert(tkinter.tix.END, "+ 12325 Re: Tkinter is good for your health") - list.listbox.insert(tkinter.tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, " 12327 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, " 12329 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)") - - text.text['bg'] = list.listbox['bg'] - text.text['wrap'] = 'none' - text.text.insert(tkinter.tix.END, """ -Mon, 19 Jun 1995 11:39:52 comp.lang.python Thread 34 of 220 -Lines 353 A new way to put text and bitmaps together iNo responses -ioi@blue.seas.upenn.edu Ioi K. Lam at University of Pennsylvania - -Hi, - -I have implemented a new image type called "compound". It allows you -to glue together a bunch of bitmaps, images and text strings together -to form a bigger image. Then you can use this image with widgets that -support the -image option. For example, you can display a text string string -together with a bitmap, at the same time, inside a TK button widget. -""") - list.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6) - text.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6) - - msg.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH) - group.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH) - pane.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH, expand=1) - -def MkNoteBook(w): - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The NoteBook widget allows you to layout a complex interface into individual pages.') - # prefix = Tix.OptionName(w) - # if not prefix: prefix = '' - # w.option_add('*' + prefix + '*TixNoteBook*tagPadX', 8) - options = "entry.width %d label.width %d label.anchor %s" % (10, 18, tkinter.tix.E) - - nb = tkinter.tix.NoteBook(w, ipadx=6, ipady=6, options=options) - nb.add('hard_disk', label="Hard Disk", underline=0) - nb.add('network', label="Network", underline=0) - - # Frame for the buttons that are present on all pages - common = tkinter.tix.Frame(nb.hard_disk) - common.pack(side=tkinter.tix.RIGHT, padx=2, pady=2, fill=tkinter.tix.Y) - CreateCommonButtons(common) - - # Widgets belonging only to this page - a = tkinter.tix.Control(nb.hard_disk, value=12, label='Access Time: ') - w = tkinter.tix.Control(nb.hard_disk, value=400, label='Write Throughput: ') - r = tkinter.tix.Control(nb.hard_disk, value=400, label='Read Throughput: ') - c = tkinter.tix.Control(nb.hard_disk, value=1021, label='Capacity: ') - a.pack(side=tkinter.tix.TOP, padx=20, pady=2) - w.pack(side=tkinter.tix.TOP, padx=20, pady=2) - r.pack(side=tkinter.tix.TOP, padx=20, pady=2) - c.pack(side=tkinter.tix.TOP, padx=20, pady=2) - - common = tkinter.tix.Frame(nb.network) - common.pack(side=tkinter.tix.RIGHT, padx=2, pady=2, fill=tkinter.tix.Y) - CreateCommonButtons(common) - - a = tkinter.tix.Control(nb.network, value=12, label='Access Time: ') - w = tkinter.tix.Control(nb.network, value=400, label='Write Throughput: ') - r = tkinter.tix.Control(nb.network, value=400, label='Read Throughput: ') - c = tkinter.tix.Control(nb.network, value=1021, label='Capacity: ') - u = tkinter.tix.Control(nb.network, value=10, label='Users: ') - a.pack(side=tkinter.tix.TOP, padx=20, pady=2) - w.pack(side=tkinter.tix.TOP, padx=20, pady=2) - r.pack(side=tkinter.tix.TOP, padx=20, pady=2) - c.pack(side=tkinter.tix.TOP, padx=20, pady=2) - u.pack(side=tkinter.tix.TOP, padx=20, pady=2) - - msg.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH) - nb.pack(side=tkinter.tix.TOP, padx=5, pady=5, fill=tkinter.tix.BOTH, expand=1) - -def CreateCommonButtons(f): - ok = tkinter.tix.Button(f, text='OK', width = 6) - cancel = tkinter.tix.Button(f, text='Cancel', width = 6) - ok.pack(side=tkinter.tix.TOP, padx=2, pady=2) - cancel.pack(side=tkinter.tix.TOP, padx=2, pady=2) - -def MkDirList(nb, name): - w = nb.page(name) - options = "label.padX 4" - - dir = tkinter.tix.LabelFrame(w, label='Tix.DirList', options=options) - fsbox = tkinter.tix.LabelFrame(w, label='Tix.ExFileSelectBox', options=options) - MkDirListWidget(dir.frame) - MkExFileWidget(fsbox.frame) - dir.form(top=0, left=0, right='%40', bottom=-1) - fsbox.form(top=0, left='%40', right=-1, bottom=-1) - -def MkDirListWidget(w): - """The TixDirList widget gives a graphical representation of the file - system directory and makes it easy for the user to choose and access - directories. - """ - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The Tix DirList widget gives a graphical representation of the file system directory and makes it easy for the user to choose and access directories.') - dirlist = tkinter.tix.DirList(w, options='hlist.padY 1 hlist.width 25 hlist.height 16') - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - dirlist.pack(side=tkinter.tix.TOP, padx=3, pady=3) - -def MkExFileWidget(w): - """The TixExFileSelectBox widget is more user friendly than the Motif - style FileSelectBox. """ - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The Tix ExFileSelectBox widget is more user friendly than the Motif style FileSelectBox.') - # There's a bug in the ComboBoxes - the scrolledlistbox is destroyed - box = tkinter.tix.ExFileSelectBox(w, bd=2, relief=tkinter.tix.RAISED) - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - box.pack(side=tkinter.tix.TOP, padx=3, pady=3) - -### -### List of all the demos we want to show off -comments = {'widget' : 'Widget Demos', 'image' : 'Image Demos'} -samples = {'Balloon' : 'Balloon', - 'Button Box' : 'BtnBox', - 'Combo Box' : 'ComboBox', - 'Compound Image' : 'CmpImg', - 'Directory List' : 'DirList', - 'Directory Tree' : 'DirTree', - 'Control' : 'Control', - 'Notebook' : 'NoteBook', - 'Option Menu' : 'OptMenu', - 'Paned Window' : 'PanedWin', - 'Popup Menu' : 'PopMenu', - 'ScrolledHList (1)' : 'SHList1', - 'ScrolledHList (2)' : 'SHList2', - 'Tree (dynamic)' : 'Tree' -} - -# There are still a lot of demos to be translated: -## set root { -## {d "File Selectors" file } -## {d "Hierachical ListBox" hlist } -## {d "Tabular ListBox" tlist {c tixTList}} -## {d "Grid Widget" grid {c tixGrid}} -## {d "Manager Widgets" manager } -## {d "Scrolled Widgets" scroll } -## {d "Miscellaneous Widgets" misc } -## {d "Image Types" image } -## } -## -## set image { -## {d "Compound Image" cmpimg } -## {d "XPM Image" xpm {i pixmap}} -## } -## -## set cmpimg { -##done {f "In Buttons" CmpImg.tcl } -## {f "In NoteBook" CmpImg2.tcl } -## {f "Notebook Color Tabs" CmpImg4.tcl } -## {f "Icons" CmpImg3.tcl } -## } -## -## set xpm { -## {f "In Button" Xpm.tcl {i pixmap}} -## {f "In Menu" Xpm1.tcl {i pixmap}} -## } -## -## set file { -##added {f DirList DirList.tcl } -##added {f DirTree DirTree.tcl } -## {f DirSelectDialog DirDlg.tcl } -## {f ExFileSelectDialog EFileDlg.tcl } -## {f FileSelectDialog FileDlg.tcl } -## {f FileEntry FileEnt.tcl } -## } -## -## set hlist { -## {f HList HList1.tcl } -## {f CheckList ChkList.tcl {c tixCheckList}} -##done {f "ScrolledHList (1)" SHList.tcl } -##done {f "ScrolledHList (2)" SHList2.tcl } -##done {f Tree Tree.tcl } -##done {f "Tree (Dynamic)" DynTree.tcl {v win}} -## } -## -## set tlist { -## {f "ScrolledTList (1)" STList1.tcl {c tixTList}} -## {f "ScrolledTList (2)" STList2.tcl {c tixTList}} -## } -## global tcl_platform -## # This demo hangs windows -## if {$tcl_platform(platform) != "windows"} { -##na lappend tlist {f "TList File Viewer" STList3.tcl {c tixTList}} -## } -## -## set grid { -##na {f "Simple Grid" SGrid0.tcl {c tixGrid}} -##na {f "ScrolledGrid" SGrid1.tcl {c tixGrid}} -##na {f "Editable Grid" EditGrid.tcl {c tixGrid}} -## } -## -## set scroll { -## {f ScrolledListBox SListBox.tcl } -## {f ScrolledText SText.tcl } -## {f ScrolledWindow SWindow.tcl } -##na {f "Canvas Object View" CObjView.tcl {c tixCObjView}} -## } -## -## set manager { -## {f ListNoteBook ListNBK.tcl } -##done {f NoteBook NoteBook.tcl } -##done {f PanedWindow PanedWin.tcl } -## } -## -## set misc { -##done {f Balloon Balloon.tcl } -##done {f ButtonBox BtnBox.tcl } -##done {f ComboBox ComboBox.tcl } -##done {f Control Control.tcl } -## {f LabelEntry LabEntry.tcl } -## {f LabelFrame LabFrame.tcl } -## {f Meter Meter.tcl {c tixMeter}} -##done {f OptionMenu OptMenu.tcl } -##done {f PopupMenu PopMenu.tcl } -## {f Select Select.tcl } -## {f StdButtonBox StdBBox.tcl } -## } -## - -stypes = {} -stypes['widget'] = ['Balloon', 'Button Box', 'Combo Box', 'Control', - 'Directory List', 'Directory Tree', - 'Notebook', 'Option Menu', 'Popup Menu', 'Paned Window', - 'ScrolledHList (1)', 'ScrolledHList (2)', 'Tree (dynamic)'] -stypes['image'] = ['Compound Image'] - -def MkSample(nb, name): - w = nb.page(name) - options = "label.padX 4" - - pane = tkinter.tix.PanedWindow(w, orientation='horizontal') - pane.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH) - f1 = pane.add('list', expand='1') - f2 = pane.add('text', expand='5') - f1['relief'] = 'flat' - f2['relief'] = 'flat' - - lab = tkinter.tix.LabelFrame(f1, label='Select a sample program:') - lab.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=5, pady=5) - lab1 = tkinter.tix.LabelFrame(f2, label='Source:') - lab1.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=5, pady=5) - - slb = tkinter.tix.Tree(lab.frame, options='hlist.width 20') - slb.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=5) - - stext = tkinter.tix.ScrolledText(lab1.frame, name='stext') - font = root.tk.eval('tix option get fixed_font') - stext.text.config(font=font) - - frame = tkinter.tix.Frame(lab1.frame, name='frame') - - run = tkinter.tix.Button(frame, text='Run ...', name='run') - view = tkinter.tix.Button(frame, text='View Source ...', name='view') - run.pack(side=tkinter.tix.LEFT, expand=0, fill=tkinter.tix.NONE) - view.pack(side=tkinter.tix.LEFT, expand=0, fill=tkinter.tix.NONE) - - stext.text['bg'] = slb.hlist['bg'] - stext.text['state'] = 'disabled' - stext.text['wrap'] = 'none' - stext.text['width'] = 80 - - frame.pack(side=tkinter.tix.BOTTOM, expand=0, fill=tkinter.tix.X, padx=7) - stext.pack(side=tkinter.tix.TOP, expand=0, fill=tkinter.tix.BOTH, padx=7) - - slb.hlist['separator'] = '.' - slb.hlist['width'] = 25 - slb.hlist['drawbranch'] = 0 - slb.hlist['indent'] = 10 - slb.hlist['wideselect'] = 1 - slb.hlist['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run') - slb.hlist['browsecmd'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'browse') - - run['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run') - view['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'view') - - for type in ['widget', 'image']: - if type != 'widget': - x = tkinter.tix.Frame(slb.hlist, bd=2, height=2, width=150, - relief=tkinter.tix.SUNKEN, bg=slb.hlist['bg']) - slb.hlist.add_child(itemtype=tkinter.tix.WINDOW, window=x, state='disabled') - x = slb.hlist.add_child(itemtype=tkinter.tix.TEXT, state='disabled', - text=comments[type]) - for key in stypes[type]: - slb.hlist.add_child(x, itemtype=tkinter.tix.TEXT, data=key, - text=key) - slb.hlist.selection_clear() - - run['state'] = 'disabled' - view['state'] = 'disabled' - -def Sample_Action(w, slb, stext, run, view, action): - global demo - - hlist = slb.hlist - anchor = hlist.info_anchor() - if not anchor: - run['state'] = 'disabled' - view['state'] = 'disabled' - elif not hlist.info_parent(anchor): - # a comment - return - - run['state'] = 'normal' - view['state'] = 'normal' - key = hlist.info_data(anchor) - title = key - prog = samples[key] - - if action == 'run': - exec('import ' + prog) - w = tkinter.tix.Toplevel() - w.title(title) - rtn = eval(prog + '.RunSample') - rtn(w) - elif action == 'view': - w = tkinter.tix.Toplevel() - w.title('Source view: ' + title) - LoadFile(w, demo.dir + '/samples/' + prog + '.py') - elif action == 'browse': - ReadFile(stext.text, demo.dir + '/samples/' + prog + '.py') - -def LoadFile(w, fname): - global root - b = tkinter.tix.Button(w, text='Close', command=w.destroy) - t = tkinter.tix.ScrolledText(w) - # b.form(left=0, bottom=0, padx=4, pady=4) - # t.form(left=0, bottom=b, right='-0', top=0) - t.pack() - b.pack() - - font = root.tk.eval('tix option get fixed_font') - t.text.config(font=font) - t.text['bd'] = 2 - t.text['wrap'] = 'none' - - ReadFile(t.text, fname) - -def ReadFile(w, fname): - old_state = w['state'] - w['state'] = 'normal' - w.delete('0.0', tkinter.tix.END) - - try: - f = open(fname) - lines = f.readlines() - for s in lines: - w.insert(tkinter.tix.END, s) - f.close() - finally: -# w.see('1.0') - w['state'] = old_state - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunMain(root) diff --git a/Demo/tkinter/README b/Demo/tkinter/README deleted file mode 100644 index c9f18df..0000000 --- a/Demo/tkinter/README +++ /dev/null @@ -1,11 +0,0 @@ -Several collections of example code for Tkinter. - -See the toplevel README for an explanation of the difference between -Tkinter and _tkinter, how to enable the Python Tk interface, and where -to get Matt Conway's lifesaver document. - -Subdirectories: - -guido my original example set (fairly random collection) -matt Matt Conway's examples, to go with his lifesaver document -ttk Examples using the ttk module diff --git a/Demo/tkinter/guido/attr_dialog.py b/Demo/tkinter/guido/attr_dialog.py deleted file mode 100644 index 229a558..0000000 --- a/Demo/tkinter/guido/attr_dialog.py +++ /dev/null @@ -1,460 +0,0 @@ - -# The options of a widget are described by the following attributes -# of the Pack and Widget dialogs: -# -# Dialog.current: {name: value} -# -- changes during Widget's lifetime -# -# Dialog.options: {name: (default, klass)} -# -- depends on widget class only -# -# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'} -# -- totally static, though different between PackDialog and WidgetDialog -# (but even that could be unified) - -from tkinter import * - - -class Option: - - varclass = StringVar # May be overridden - - def __init__(self, dialog, option): - self.dialog = dialog - self.option = option - self.master = dialog.top - self.default, self.klass = dialog.options[option] - self.var = self.varclass(self.master) - self.frame = Frame(self.master) - self.frame.pack(fill=X) - self.label = Label(self.frame, text=(option + ":")) - self.label.pack(side=LEFT) - self.update() - self.addoption() - - def refresh(self): - self.dialog.refresh() - self.update() - - def update(self): - try: - self.current = self.dialog.current[self.option] - except KeyError: - self.current = self.default - self.var.set(self.current) - - def set(self, e=None): # Should be overridden - pass - - -class BooleanOption(Option): - - varclass = BooleanVar - - def addoption(self): - self.button = Checkbutton(self.frame, - text='on/off', - onvalue=1, - offvalue=0, - variable=self.var, - relief=RAISED, - borderwidth=2, - command=self.set) - self.button.pack(side=RIGHT) - - -class EnumOption(Option): - - def addoption(self): - self.button = Menubutton(self.frame, - textvariable=self.var, - relief=RAISED, borderwidth=2) - self.button.pack(side=RIGHT) - self.menu = Menu(self.button) - self.button['menu'] = self.menu - for v in self.dialog.classes[self.klass]: - self.menu.add_radiobutton( - label=v, - variable=self.var, - value=v, - command=self.set) - - -class StringOption(Option): - - def addoption(self): - self.entry = Entry(self.frame, - textvariable=self.var, - width=10, - relief=SUNKEN, - borderwidth=2) - self.entry.pack(side=RIGHT, fill=X, expand=1) - self.entry.bind('<Return>', self.set) - - -class ReadonlyOption(Option): - - def addoption(self): - self.label = Label(self.frame, textvariable=self.var, - anchor=E) - self.label.pack(side=RIGHT) - - -class Dialog: - - def __init__(self, master): - self.master = master - self.fixclasses() - self.refresh() - self.top = Toplevel(self.master) - self.top.title(self.__class__.__name__) - self.top.minsize(1, 1) - self.addchoices() - - def refresh(self): pass # Must override - - def fixclasses(self): pass # May override - - def addchoices(self): - self.choices = {} - list = [] - for k, dc in self.options.items(): - list.append((k, dc)) - list.sort() - for k, (d, c) in list: - try: - cl = self.classes[c] - except KeyError: - cl = 'unknown' - if type(cl) is tuple: - cl = self.enumoption - elif cl == 'boolean': - cl = self.booleanoption - elif cl == 'readonly': - cl = self.readonlyoption - else: - cl = self.stringoption - self.choices[k] = cl(self, k) - - # Must override: - options = {} - classes = {} - - # May override: - booleanoption = BooleanOption - stringoption = StringOption - enumoption = EnumOption - readonlyoption = ReadonlyOption - - -class PackDialog(Dialog): - - def __init__(self, widget): - self.widget = widget - Dialog.__init__(self, widget) - - def refresh(self): - self.current = self.widget.info() - self.current['.class'] = self.widget.winfo_class() - self.current['.name'] = self.widget._w - - class packoption: # Mix-in class - def set(self, e=None): - self.current = self.var.get() - try: - self.dialog.widget.pack(**{self.option: self.current}) - except TclError as msg: - print(msg) - self.refresh() - - class booleanoption(packoption, BooleanOption): pass - class enumoption(packoption, EnumOption): pass - class stringoption(packoption, StringOption): pass - class readonlyoption(packoption, ReadonlyOption): pass - - options = { - '.class': (None, 'Class'), - '.name': (None, 'Name'), - 'after': (None, 'Widget'), - 'anchor': ('center', 'Anchor'), - 'before': (None, 'Widget'), - 'expand': ('no', 'Boolean'), - 'fill': ('none', 'Fill'), - 'in': (None, 'Widget'), - 'ipadx': (0, 'Pad'), - 'ipady': (0, 'Pad'), - 'padx': (0, 'Pad'), - 'pady': (0, 'Pad'), - 'side': ('top', 'Side'), - } - - classes = { - 'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER), - 'Boolean': 'boolean', - 'Class': 'readonly', - 'Expand': 'boolean', - 'Fill': (NONE, X, Y, BOTH), - 'Name': 'readonly', - 'Pad': 'pixel', - 'Side': (TOP, RIGHT, BOTTOM, LEFT), - 'Widget': 'readonly', - } - -class RemotePackDialog(PackDialog): - - def __init__(self, master, app, widget): - self.master = master - self.app = app - self.widget = widget - self.refresh() - self.top = Toplevel(self.master) - self.top.title(self.app + ' PackDialog') - self.top.minsize(1, 1) - self.addchoices() - - def refresh(self): - try: - words = self.master.tk.splitlist( - self.master.send(self.app, - 'pack', - 'info', - self.widget)) - except TclError as msg: - print(msg) - return - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - dict[key] = value - dict['.class'] = self.master.send(self.app, - 'winfo', - 'class', - self.widget) - dict['.name'] = self.widget - self.current = dict - - class remotepackoption: # Mix-in class - def set(self, e=None): - self.current = self.var.get() - try: - self.dialog.master.send( - self.dialog.app, - 'pack', - 'config', - self.dialog.widget, - '-'+self.option, - self.dialog.master.tk.merge( - self.current)) - except TclError as msg: - print(msg) - self.refresh() - - class booleanoption(remotepackoption, BooleanOption): pass - class enumoption(remotepackoption, EnumOption): pass - class stringoption(remotepackoption, StringOption): pass - class readonlyoption(remotepackoption, ReadonlyOption): pass - - -class WidgetDialog(Dialog): - - def __init__(self, widget): - self.widget = widget - self.klass = widget.winfo_class() - Dialog.__init__(self, widget) - - def fixclasses(self): - if self.klass in self.addclasses: - classes = {} - for c in (self.classes, - self.addclasses[self.klass]): - for k in c.keys(): - classes[k] = c[k] - self.classes = classes - - def refresh(self): - self.configuration = self.widget.config() - self.update() - self.current['.class'] = self.widget.winfo_class() - self.current['.name'] = self.widget._w - - def update(self): - self.current = {} - self.options = {} - for k, v in self.configuration.items(): - if len(v) > 4: - self.current[k] = v[4] - self.options[k] = v[3], v[2] # default, klass - self.options['.class'] = (None, 'Class') - self.options['.name'] = (None, 'Name') - - class widgetoption: # Mix-in class - def set(self, e=None): - self.current = self.var.get() - try: - self.dialog.widget[self.option] = self.current - except TclError as msg: - print(msg) - self.refresh() - - class booleanoption(widgetoption, BooleanOption): pass - class enumoption(widgetoption, EnumOption): pass - class stringoption(widgetoption, StringOption): pass - class readonlyoption(widgetoption, ReadonlyOption): pass - - # Universal classes - classes = { - 'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER), - 'Aspect': 'integer', - 'Background': 'color', - 'Bitmap': 'bitmap', - 'BorderWidth': 'pixel', - 'Class': 'readonly', - 'CloseEnough': 'double', - 'Command': 'command', - 'Confine': 'boolean', - 'Cursor': 'cursor', - 'CursorWidth': 'pixel', - 'DisabledForeground': 'color', - 'ExportSelection': 'boolean', - 'Font': 'font', - 'Foreground': 'color', - 'From': 'integer', - 'Geometry': 'geometry', - 'Height': 'pixel', - 'InsertWidth': 'time', - 'Justify': (LEFT, CENTER, RIGHT), - 'Label': 'string', - 'Length': 'pixel', - 'MenuName': 'widget', - 'Name': 'readonly', - 'OffTime': 'time', - 'OnTime': 'time', - 'Orient': (HORIZONTAL, VERTICAL), - 'Pad': 'pixel', - 'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE), - 'RepeatDelay': 'time', - 'RepeatInterval': 'time', - 'ScrollCommand': 'command', - 'ScrollIncrement': 'pixel', - 'ScrollRegion': 'rectangle', - 'ShowValue': 'boolean', - 'SetGrid': 'boolean', - 'Sliderforeground': 'color', - 'SliderLength': 'pixel', - 'Text': 'string', - 'TickInterval': 'integer', - 'To': 'integer', - 'Underline': 'index', - 'Variable': 'variable', - 'Value': 'string', - 'Width': 'pixel', - 'Wrap': (NONE, CHAR, WORD), - } - - # Classes that (may) differ per widget type - _tristate = {'State': (NORMAL, ACTIVE, DISABLED)} - _bistate = {'State': (NORMAL, DISABLED)} - addclasses = { - 'Button': _tristate, - 'Radiobutton': _tristate, - 'Checkbutton': _tristate, - 'Entry': _bistate, - 'Text': _bistate, - 'Menubutton': _tristate, - 'Slider': _bistate, - } - - -class RemoteWidgetDialog(WidgetDialog): - - def __init__(self, master, app, widget): - self.app = app - self.widget = widget - self.klass = master.send(self.app, - 'winfo', - 'class', - self.widget) - Dialog.__init__(self, master) - - def refresh(self): - try: - items = self.master.tk.splitlist( - self.master.send(self.app, - self.widget, - 'config')) - except TclError as msg: - print(msg) - return - dict = {} - for item in items: - words = self.master.tk.splitlist(item) - key = words[0][1:] - value = (key,) + words[1:] - dict[key] = value - self.configuration = dict - self.update() - self.current['.class'] = self.klass - self.current['.name'] = self.widget - - class remotewidgetoption: # Mix-in class - def set(self, e=None): - self.current = self.var.get() - try: - self.dialog.master.send( - self.dialog.app, - self.dialog.widget, - 'config', - '-'+self.option, - self.current) - except TclError as msg: - print(msg) - self.refresh() - - class booleanoption(remotewidgetoption, BooleanOption): pass - class enumoption(remotewidgetoption, EnumOption): pass - class stringoption(remotewidgetoption, StringOption): pass - class readonlyoption(remotewidgetoption, ReadonlyOption): pass - - -def test(): - import sys - root = Tk() - root.minsize(1, 1) - if sys.argv[1:]: - remotetest(root, sys.argv[1]) - else: - frame = Frame(root, name='frame') - frame.pack(expand=1, fill=BOTH) - button = Button(frame, name='button', text='button') - button.pack(expand=1) - canvas = Canvas(frame, name='canvas') - canvas.pack() - fpd = PackDialog(frame) - fwd = WidgetDialog(frame) - bpd = PackDialog(button) - bwd = WidgetDialog(button) - cpd = PackDialog(canvas) - cwd = WidgetDialog(canvas) - root.mainloop() - -def remotetest(root, app): - from listtree import listtree - list = listtree(root, app) - list.bind('<Any-Double-1>', opendialogs) - list.app = app # Pass it on to handler - -def opendialogs(e): - list = e.widget - sel = list.curselection() - for i in sel: - item = list.get(i) - widget = item.split()[0] - RemoteWidgetDialog(list, list.app, widget) - if widget == '.': continue - try: - RemotePackDialog(list, list.app, widget) - except TclError as msg: - print(msg) - -test() diff --git a/Demo/tkinter/guido/brownian.py b/Demo/tkinter/guido/brownian.py deleted file mode 100644 index 7ab3e67..0000000 --- a/Demo/tkinter/guido/brownian.py +++ /dev/null @@ -1,50 +0,0 @@ -# Brownian motion -- an example of a multi-threaded Tkinter program. - -from tkinter import * -import random -import threading -import time -import sys - -WIDTH = 400 -HEIGHT = 300 -SIGMA = 10 -BUZZ = 2 -RADIUS = 2 -LAMBDA = 10 -FILL = 'red' - -stop = 0 # Set when main loop exits - -def particle(canvas): - r = RADIUS - x = random.gauss(WIDTH/2.0, SIGMA) - y = random.gauss(HEIGHT/2.0, SIGMA) - p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL) - while not stop: - dx = random.gauss(0, BUZZ) - dy = random.gauss(0, BUZZ) - dt = random.expovariate(LAMBDA) - try: - canvas.move(p, dx, dy) - except TclError: - break - time.sleep(dt) - -def main(): - global stop - root = Tk() - canvas = Canvas(root, width=WIDTH, height=HEIGHT) - canvas.pack(fill='both', expand=1) - np = 30 - if sys.argv[1:]: - np = int(sys.argv[1]) - for i in range(np): - t = threading.Thread(target=particle, args=(canvas,)) - t.start() - try: - root.mainloop() - finally: - stop = 1 - -main() diff --git a/Demo/tkinter/guido/brownian2.py b/Demo/tkinter/guido/brownian2.py deleted file mode 100644 index dc1d43a..0000000 --- a/Demo/tkinter/guido/brownian2.py +++ /dev/null @@ -1,55 +0,0 @@ -# Brownian motion -- an example of a NON multi-threaded Tkinter program ;) -# By Michele Simoniato, inspired by brownian.py - -from tkinter import * -import random -import sys - -WIDTH = 400 -HEIGHT = 300 -SIGMA = 10 -BUZZ = 2 -RADIUS = 2 -LAMBDA = 10 -FILL = 'red' - -stop = 0 # Set when main loop exits -root = None # main window - -def particle(canvas): # particle = iterator over the moves - r = RADIUS - x = random.gauss(WIDTH/2.0, SIGMA) - y = random.gauss(HEIGHT/2.0, SIGMA) - p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL) - while not stop: - dx = random.gauss(0, BUZZ) - dy = random.gauss(0, BUZZ) - try: - canvas.move(p, dx, dy) - except TclError: - break - else: - yield None - -def move(particle): # move the particle at random time - particle.next() - dt = random.expovariate(LAMBDA) - root.after(int(dt*1000), move, particle) - -def main(): - global root, stop - root = Tk() - canvas = Canvas(root, width=WIDTH, height=HEIGHT) - canvas.pack(fill='both', expand=1) - np = 30 - if sys.argv[1:]: - np = int(sys.argv[1]) - for i in range(np): # start the dance - move(particle(canvas)) - try: - root.mainloop() - finally: - stop = 1 - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/canvasevents.py b/Demo/tkinter/guido/canvasevents.py deleted file mode 100644 index ffeb0ca..0000000 --- a/Demo/tkinter/guido/canvasevents.py +++ /dev/null @@ -1,264 +0,0 @@ -#! /usr/bin/env python - -from tkinter import * - - -# Since Canvas.Group is no longer present, the following class reproduces -# a subset of the old Group class that is used by this app. - -class Group: - def __init__(self, canvas, tag=None): - if tag is None: - tag = 'Group%d' % id(self) - - self.tag = self.id = tag - self.canvas = canvas - self.canvas.dtag(self.tag) - - def __str__(self): - return self.tag - - def _do(self, cmd, *args): - return self.canvas.tk.call(self.canvas._w, cmd, self.tag, *args) - - def addtag_withtag(self, tagOrId): - self._do('addtag', 'withtag', tagOrId) - - def bind(self, sequence=None, command=None, add=None): - return self.canvas.tag_bind(self.id, sequence, command, add) - - def move(self, x_amount, y_amount): - self._do('move', x_amount, y_amount) - - def dtag(self, tagToDelete=None): - self._do('dtag', tagToDelete) - - def tkraise(self, aboveThis=None): - self._do('raise', aboveThis) - - -class Object: - - """Base class for composite graphical objects. - - Objects belong to a canvas, and can be moved around on the canvas. - They also belong to at most one ``pile'' of objects, and can be - transferred between piles (or removed from their pile). - - Objects have a canonical ``x, y'' position which is moved when the - object is moved. Where the object is relative to this position - depends on the object; for simple objects, it may be their center. - - Objects have mouse sensitivity. They can be clicked, dragged and - double-clicked. The behavior may actually determined by the pile - they are in. - - All instance attributes are public since the derived class may - need them. - """ - - def __init__(self, canvas, x=0, y=0, fill='red', text='object'): - self.canvas = canvas - self.x = x - self.y = y - self.pile = None - self.group = Group(self.canvas) - self.createitems(fill, text) - - def __str__(self): - return str(self.group) - - def createitems(self, fill, text): - self.__oval = self.canvas.create_oval(self.x - 20, self.y - 10, - self.x + 20, self.y + 20, fill=fill, width=3) - self.group.addtag_withtag(self.__oval) - self.__text = self.canvas.create_text(self.x, self.y, text=text) - self.group.addtag_withtag(self.__text) - - def moveby(self, dx, dy): - if dx == dy == 0: - return - self.group.move(dx, dy) - self.x = self.x + dx - self.y = self.y + dy - - def moveto(self, x, y): - self.moveby(x - self.x, y - self.y) - - def transfer(self, pile): - if self.pile: - self.pile.delete(self) - self.pile = None - self.pile = pile - if self.pile: - self.pile.add(self) - - def tkraise(self): - self.group.tkraise() - - -class Bottom(Object): - """An object to serve as the bottom of a pile.""" - - def createitems(self, *args): - self.__oval = self.canvas.create_oval(self.x - 20, self.y - 10, - self.x + 20, self.y + 10, fill='gray', outline='') - self.group.addtag_withtag(self.__oval) - - -class Pile: - """A group of graphical objects.""" - - def __init__(self, canvas, x, y, tag=None): - self.canvas = canvas - self.x = x - self.y = y - self.objects = [] - self.bottom = Bottom(self.canvas, self.x, self.y) - self.group = Group(self.canvas, tag=tag) - self.group.addtag_withtag(self.bottom.group) - self.bindhandlers() - - def bindhandlers(self): - self.group.bind('<1>', self.clickhandler) - self.group.bind('<Double-1>', self.doubleclickhandler) - - def add(self, object): - self.objects.append(object) - self.group.addtag_withtag(object.group) - self.position(object) - - def delete(self, object): - object.group.dtag(self.group) - self.objects.remove(object) - - def position(self, object): - object.tkraise() - i = self.objects.index(object) - object.moveto(self.x + i*4, self.y + i*8) - - def clickhandler(self, event): - pass - - def doubleclickhandler(self, event): - pass - - -class MovingPile(Pile): - - def bindhandlers(self): - Pile.bindhandlers(self) - self.group.bind('<B1-Motion>', self.motionhandler) - self.group.bind('<ButtonRelease-1>', self.releasehandler) - - movethis = None - - def clickhandler(self, event): - tags = self.canvas.gettags('current') - for i in range(len(self.objects)): - o = self.objects[i] - if o.group.tag in tags: - break - else: - self.movethis = None - return - self.movethis = self.objects[i:] - for o in self.movethis: - o.tkraise() - self.lastx = event.x - self.lasty = event.y - - doubleclickhandler = clickhandler - - def motionhandler(self, event): - if not self.movethis: - return - dx = event.x - self.lastx - dy = event.y - self.lasty - self.lastx = event.x - self.lasty = event.y - for o in self.movethis: - o.moveby(dx, dy) - - def releasehandler(self, event): - objects = self.movethis - if not objects: - return - self.movethis = None - self.finishmove(objects) - - def finishmove(self, objects): - for o in objects: - self.position(o) - - -class Pile1(MovingPile): - - x = 50 - y = 50 - tag = 'p1' - - def __init__(self, demo): - self.demo = demo - MovingPile.__init__(self, self.demo.canvas, self.x, self.y, self.tag) - - def doubleclickhandler(self, event): - try: - o = self.objects[-1] - except IndexError: - return - o.transfer(self.other()) - MovingPile.doubleclickhandler(self, event) - - def other(self): - return self.demo.p2 - - def finishmove(self, objects): - o = objects[0] - p = self.other() - x, y = o.x, o.y - if (x-p.x)**2 + (y-p.y)**2 < (x-self.x)**2 + (y-self.y)**2: - for o in objects: - o.transfer(p) - else: - MovingPile.finishmove(self, objects) - -class Pile2(Pile1): - - x = 150 - y = 50 - tag = 'p2' - - def other(self): - return self.demo.p1 - - -class Demo: - - def __init__(self, master): - self.master = master - self.canvas = Canvas(master, - width=200, height=200, - background='yellow', - relief=SUNKEN, borderwidth=2) - self.canvas.pack(expand=1, fill=BOTH) - self.p1 = Pile1(self) - self.p2 = Pile2(self) - o1 = Object(self.canvas, fill='red', text='o1') - o2 = Object(self.canvas, fill='green', text='o2') - o3 = Object(self.canvas, fill='light blue', text='o3') - o1.transfer(self.p1) - o2.transfer(self.p1) - o3.transfer(self.p2) - - -# Main function, run when invoked as a stand-alone Python program. - -def main(): - root = Tk() - demo = Demo(root) - root.protocol('WM_DELETE_WINDOW', root.quit) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/dialog.py b/Demo/tkinter/guido/dialog.py deleted file mode 100755 index 2a4a939..0000000 --- a/Demo/tkinter/guido/dialog.py +++ /dev/null @@ -1,108 +0,0 @@ -#! /usr/bin/env python - -# A Python function that generates dialog boxes with a text message, -# optional bitmap, and any number of buttons. -# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270. - -from tkinter import * -import sys - - -def dialog(master, title, text, bitmap, default, *args): - - # 1. Create the top-level window and divide it into top - # and bottom parts. - - w = Toplevel(master, class_='Dialog') - w.title(title) - w.iconname('Dialog') - - top = Frame(w, relief=RAISED, borderwidth=1) - top.pack(side=TOP, fill=BOTH) - bot = Frame(w, relief=RAISED, borderwidth=1) - bot.pack(side=BOTTOM, fill=BOTH) - - # 2. Fill the top part with the bitmap and message. - - msg = Message(top, width='3i', text=text) - msg.pack(side=RIGHT, expand=1, fill=BOTH, padx='3m', pady='3m') - if bitmap: - bm = Label(top, bitmap=bitmap) - bm.pack(side=LEFT, padx='3m', pady='3m') - - # 3. Create a row of buttons at the bottom of the dialog. - - var = IntVar() - buttons = [] - i = 0 - for but in args: - b = Button(bot, text=but, command=lambda v=var,i=i: v.set(i)) - buttons.append(b) - if i == default: - bd = Frame(bot, relief=SUNKEN, borderwidth=1) - bd.pack(side=LEFT, expand=1, padx='3m', pady='2m') - b.lift() - b.pack (in_=bd, side=LEFT, - padx='2m', pady='2m', ipadx='2m', ipady='1m') - else: - b.pack (side=LEFT, expand=1, - padx='3m', pady='3m', ipadx='2m', ipady='1m') - i = i+1 - - # 4. Set up a binding for <Return>, if there's a default, - # set a grab, and claim the focus too. - - if default >= 0: - w.bind('<Return>', - lambda e, b=buttons[default], v=var, i=default: - (b.flash(), - v.set(i))) - - oldFocus = w.focus_get() - w.grab_set() - w.focus_set() - - # 5. Wait for the user to respond, then restore the focus - # and return the index of the selected button. - - w.waitvar(var) - w.destroy() - if oldFocus: oldFocus.focus_set() - return var.get() - -# The rest is the test program. - -def go(): - i = dialog(mainWidget, - 'Not Responding', - "The file server isn't responding right now; " - "I'll keep trying.", - '', - -1, - 'OK') - print('pressed button', i) - i = dialog(mainWidget, - 'File Modified', - 'File "tcl.h" has been modified since ' - 'the last time it was saved. ' - 'Do you want to save it before exiting the application?', - 'warning', - 0, - 'Save File', - 'Discard Changes', - 'Return To Editor') - print('pressed button', i) - -def test(): - import sys - global mainWidget - mainWidget = Frame() - Pack.config(mainWidget) - start = Button(mainWidget, text='Press Here To Start', command=go) - start.pack() - endit = Button(mainWidget, text="Exit", command=sys.exit) - endit.pack(fill=BOTH) - mainWidget.mainloop() - -if __name__ == '__main__': - test() diff --git a/Demo/tkinter/guido/electrons.py b/Demo/tkinter/guido/electrons.py deleted file mode 100755 index b5c9ec0..0000000 --- a/Demo/tkinter/guido/electrons.py +++ /dev/null @@ -1,91 +0,0 @@ -#! /usr/bin/env python - -# Simulate "electrons" migrating across the screen. -# An optional bitmap file in can be in the background. -# -# Usage: electrons [n [bitmapfile]] -# -# n is the number of electrons to animate; default is 30. -# -# The bitmap file can be any X11 bitmap file (look in -# /usr/include/X11/bitmaps for samples); it is displayed as the -# background of the animation. Default is no bitmap. - -from tkinter import * -import random - - -# The graphical interface -class Electrons: - - # Create our objects - def __init__(self, n, bitmap = None): - self.n = n - self.tk = tk = Tk() - self.canvas = c = Canvas(tk) - c.pack() - width, height = tk.getint(c['width']), tk.getint(c['height']) - - # Add background bitmap - if bitmap: - self.bitmap = c.create_bitmap(width/2, height/2, - bitmap=bitmap, - foreground='blue') - - self.pieces = [] - x1, y1, x2, y2 = 10,70,14,74 - for i in range(n): - p = c.create_oval(x1, y1, x2, y2, fill='red') - self.pieces.append(p) - y1, y2 = y1 +2, y2 + 2 - self.tk.update() - - def random_move(self, n): - c = self.canvas - for p in self.pieces: - x = random.choice(range(-2,4)) - y = random.choice(range(-3,4)) - c.move(p, x, y) - self.tk.update() - - # Run -- allow 500 movemens - def run(self): - try: - for i in range(500): - self.random_move(self.n) - except TclError: - try: - self.tk.destroy() - except TclError: - pass - - -# Main program -def main(): - import sys - - # First argument is number of electrons, default 30 - if sys.argv[1:]: - n = int(sys.argv[1]) - else: - n = 30 - - # Second argument is bitmap file, default none - if sys.argv[2:]: - bitmap = sys.argv[2] - # Reverse meaning of leading '@' compared to Tk - if bitmap[0] == '@': bitmap = bitmap[1:] - else: bitmap = '@' + bitmap - else: - bitmap = None - - # Create the graphical objects... - h = Electrons(n, bitmap) - - # ...and run! - h.run() - - -# Call main when run as script -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/hanoi.py b/Demo/tkinter/guido/hanoi.py deleted file mode 100755 index 34a0bba..0000000 --- a/Demo/tkinter/guido/hanoi.py +++ /dev/null @@ -1,154 +0,0 @@ -# Animated Towers of Hanoi using Tk with optional bitmap file in -# background. -# -# Usage: tkhanoi [n [bitmapfile]] -# -# n is the number of pieces to animate; default is 4, maximum 15. -# -# The bitmap file can be any X11 bitmap file (look in -# /usr/include/X11/bitmaps for samples); it is displayed as the -# background of the animation. Default is no bitmap. - -# This uses Steen Lumholt's Tk interface -from tkinter import * - - -# Basic Towers-of-Hanoi algorithm: move n pieces from a to b, using c -# as temporary. For each move, call report() -def hanoi(n, a, b, c, report): - if n <= 0: return - hanoi(n-1, a, c, b, report) - report(n, a, b) - hanoi(n-1, c, b, a, report) - - -# The graphical interface -class Tkhanoi: - - # Create our objects - def __init__(self, n, bitmap = None): - self.n = n - self.tk = tk = Tk() - self.canvas = c = Canvas(tk) - c.pack() - width, height = tk.getint(c['width']), tk.getint(c['height']) - - # Add background bitmap - if bitmap: - self.bitmap = c.create_bitmap(width//2, height//2, - bitmap=bitmap, - foreground='blue') - - # Generate pegs - pegwidth = 10 - pegheight = height//2 - pegdist = width//3 - x1, y1 = (pegdist-pegwidth)//2, height*1//3 - x2, y2 = x1+pegwidth, y1+pegheight - self.pegs = [] - p = c.create_rectangle(x1, y1, x2, y2, fill='black') - self.pegs.append(p) - x1, x2 = x1+pegdist, x2+pegdist - p = c.create_rectangle(x1, y1, x2, y2, fill='black') - self.pegs.append(p) - x1, x2 = x1+pegdist, x2+pegdist - p = c.create_rectangle(x1, y1, x2, y2, fill='black') - self.pegs.append(p) - self.tk.update() - - # Generate pieces - pieceheight = pegheight//16 - maxpiecewidth = pegdist*2//3 - minpiecewidth = 2*pegwidth - self.pegstate = [[], [], []] - self.pieces = {} - x1, y1 = (pegdist-maxpiecewidth)//2, y2-pieceheight-2 - x2, y2 = x1+maxpiecewidth, y1+pieceheight - dx = (maxpiecewidth-minpiecewidth) // (2*max(1, n-1)) - for i in range(n, 0, -1): - p = c.create_rectangle(x1, y1, x2, y2, fill='red') - self.pieces[i] = p - self.pegstate[0].append(i) - x1, x2 = x1 + dx, x2-dx - y1, y2 = y1 - pieceheight-2, y2-pieceheight-2 - self.tk.update() - self.tk.after(25) - - # Run -- never returns - def run(self): - while 1: - hanoi(self.n, 0, 1, 2, self.report) - hanoi(self.n, 1, 2, 0, self.report) - hanoi(self.n, 2, 0, 1, self.report) - hanoi(self.n, 0, 2, 1, self.report) - hanoi(self.n, 2, 1, 0, self.report) - hanoi(self.n, 1, 0, 2, self.report) - - # Reporting callback for the actual hanoi function - def report(self, i, a, b): - if self.pegstate[a][-1] != i: raise RuntimeError # Assertion - del self.pegstate[a][-1] - p = self.pieces[i] - c = self.canvas - - # Lift the piece above peg a - ax1, ay1, ax2, ay2 = c.bbox(self.pegs[a]) - while 1: - x1, y1, x2, y2 = c.bbox(p) - if y2 < ay1: break - c.move(p, 0, -1) - self.tk.update() - - # Move it towards peg b - bx1, by1, bx2, by2 = c.bbox(self.pegs[b]) - newcenter = (bx1+bx2)//2 - while 1: - x1, y1, x2, y2 = c.bbox(p) - center = (x1+x2)//2 - if center == newcenter: break - if center > newcenter: c.move(p, -1, 0) - else: c.move(p, 1, 0) - self.tk.update() - - # Move it down on top of the previous piece - pieceheight = y2-y1 - newbottom = by2 - pieceheight*len(self.pegstate[b]) - 2 - while 1: - x1, y1, x2, y2 = c.bbox(p) - if y2 >= newbottom: break - c.move(p, 0, 1) - self.tk.update() - - # Update peg state - self.pegstate[b].append(i) - - -# Main program -def main(): - import sys - - # First argument is number of pegs, default 4 - if sys.argv[1:]: - n = int(sys.argv[1]) - else: - n = 4 - - # Second argument is bitmap file, default none - if sys.argv[2:]: - bitmap = sys.argv[2] - # Reverse meaning of leading '@' compared to Tk - if bitmap[0] == '@': bitmap = bitmap[1:] - else: bitmap = '@' + bitmap - else: - bitmap = None - - # Create the graphical objects... - h = Tkhanoi(n, bitmap) - - # ...and run! - h.run() - - -# Call main when run as script -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/hello.py b/Demo/tkinter/guido/hello.py deleted file mode 100755 index f10fb7a..0000000 --- a/Demo/tkinter/guido/hello.py +++ /dev/null @@ -1,17 +0,0 @@ -# Display hello, world in a button; clicking it quits the program - -import sys -from tkinter import * - -def main(): - root = Tk() - button = Button(root) - button['text'] = 'Hello, world' - button['command'] = quit_callback # See below - button.pack() - root.mainloop() - -def quit_callback(): - sys.exit(0) - -main() diff --git a/Demo/tkinter/guido/imagedraw.py b/Demo/tkinter/guido/imagedraw.py deleted file mode 100755 index a168831..0000000 --- a/Demo/tkinter/guido/imagedraw.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Draw on top of an image""" - -from tkinter import * -import sys - -def main(): - filename = sys.argv[1] - root = Tk() - img = PhotoImage(file=filename) - w, h = img.width(), img.height() - canv = Canvas(root, width=w, height=h) - canv.create_image(0, 0, anchor=NW, image=img) - canv.pack() - canv.bind('<Button-1>', blob) - root.mainloop() - -def blob(event): - x, y = event.x, event.y - canv = event.widget - r = 5 - canv.create_oval(x-r, y-r, x+r, y+r, fill='red', outline="") - -main() diff --git a/Demo/tkinter/guido/imageview.py b/Demo/tkinter/guido/imageview.py deleted file mode 100755 index 276858a..0000000 --- a/Demo/tkinter/guido/imageview.py +++ /dev/null @@ -1,12 +0,0 @@ -from tkinter import * -import sys - -def main(): - filename = sys.argv[1] - root = Tk() - img = PhotoImage(file=filename) - label = Label(root, image=img) - label.pack() - root.mainloop() - -main() diff --git a/Demo/tkinter/guido/kill.py b/Demo/tkinter/guido/kill.py deleted file mode 100755 index 36caba6..0000000 --- a/Demo/tkinter/guido/kill.py +++ /dev/null @@ -1,98 +0,0 @@ -#! /usr/bin/env python -# Tkinter interface to Linux `kill' command. - -from tkinter import * -from string import splitfields -from string import split -import subprocess -import os - -class BarButton(Menubutton): - def __init__(self, master=None, **cnf): - Menubutton.__init__(self, master, **cnf) - self.pack(side=LEFT) - self.menu = Menu(self, name='menu') - self['menu'] = self.menu - -class Kill(Frame): - # List of (name, option, pid_column) - format_list = [('Default', '', 0), - ('Long', '-l', 2), - ('User', '-u', 1), - ('Jobs', '-j', 1), - ('Signal', '-s', 1), - ('Memory', '-m', 0), - ('VM', '-v', 0), - ('Hex', '-X', 0)] - def kill(self, selected): - c = self.format_list[self.format.get()][2] - pid = split(selected)[c] - os.system('kill -9 ' + pid) - self.do_update() - def do_update(self): - name, option, column = self.format_list[self.format.get()] - s = subprocess.getoutput('ps -w ' + option) - list = splitfields(s, '\n') - self.header.set(list[0]) - del list[0] - y = self.frame.vscroll.get()[0] - self.frame.list.delete(0, AtEnd()) - for line in list: - self.frame.list.insert(0, line) - self.frame.list.yview(int(y)) - def do_motion(self, e): - e.widget.select_clear(0, END) - e.widget.select_set(e.widget.nearest(e.y)) - def do_leave(self, e): - e.widget.select_clear(0, END) - def do_1(self, e): - self.kill(e.widget.get(e.widget.nearest(e.y))) - def __init__(self, master=None, **cnf): - Frame.__init__(self, master, cnf) - self.pack(expand=1, fill=BOTH) - self.bar = Frame(self, name='bar', relief=RAISED, - borderwidth=2) - self.bar.pack(fill=X) - self.bar.file = BarButton(self.bar, text='File') - self.bar.file.menu.add_command( - label='Quit', command=self.quit) - self.bar.view = BarButton(self.bar, text='View') - self.format = IntVar(self) - self.format.set(2) - for num in range(len(self.format_list)): - self.bar.view.menu.add_radiobutton( - label=self.format_list[num][0], - command=self.do_update, - variable=self.format, - value=num) - #self.bar.view.menu.add_separator() - #XXX ... - self.bar.tk_menuBar(self.bar.file, self.bar.view) - self.frame = Frame(self, relief=RAISED, borderwidth=2) - self.frame.pack(expand=1, fill=BOTH) - self.header = StringVar(self) - self.frame.label = Label(self.frame, relief=FLAT, anchor=NW, - borderwidth=0, - textvariable=self.header) - self.frame.label.pack(fill=X) - self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL) - self.frame.list = Listbox(self.frame, relief=SUNKEN, - selectbackground='#eed5b7', - selectborderwidth=0, - yscroll=self.frame.vscroll.set) - self.frame.vscroll['command'] = self.frame.list.yview - self.frame.vscroll.pack(side=RIGHT, fill=Y) - self.frame.list.pack(expand=1, fill=BOTH) - self.update = Button(self, text="Update", - command=self.do_update) - self.update.pack(expand=1, fill=X) - self.frame.list.bind('<Motion>', self.do_motion) - self.frame.list.bind('<Leave>', self.do_leave) - self.frame.list.bind('<1>', self.do_1) - self.do_update() - -if __name__ == '__main__': - kill = Kill(None, borderwidth=5) - kill.winfo_toplevel().title('Tkinter Process Killer') - kill.winfo_toplevel().minsize(1, 1) - kill.mainloop() diff --git a/Demo/tkinter/guido/listtree.py b/Demo/tkinter/guido/listtree.py deleted file mode 100755 index 8db5b60..0000000 --- a/Demo/tkinter/guido/listtree.py +++ /dev/null @@ -1,34 +0,0 @@ -# List a remote app's widget tree (names and classes only) - -import sys - -from tkinter import * - -def listtree(master, app): - list = Listbox(master, name='list') - list.pack(expand=1, fill=BOTH) - listnodes(list, app, '.', 0) - return list - -def listnodes(list, app, widget, level): - klass = list.send(app, 'winfo', 'class', widget) - list.insert(END, '%s (%s)' % (widget, klass)) - children = list.tk.splitlist( - list.send(app, 'winfo', 'children', widget)) - for c in children: - listnodes(list, app, c, level+1) - -def main(): - if not sys.argv[1:]: - sys.stderr.write('Usage: listtree appname\n') - sys.exit(2) - app = sys.argv[1] - tk = Tk() - tk.minsize(1, 1) - f = Frame(tk, name='f') - f.pack(expand=1, fill=BOTH) - list = listtree(f, app) - tk.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/manpage.py b/Demo/tkinter/guido/manpage.py deleted file mode 100644 index 750c675..0000000 --- a/Demo/tkinter/guido/manpage.py +++ /dev/null @@ -1,215 +0,0 @@ -# Widget to display a man page - -import os -import re -import sys - -from tkinter import * -from tkinter.font import Font -from tkinter.scrolledtext import ScrolledText - -# XXX Recognizing footers is system dependent -# (This one works for IRIX 5.2 and Solaris 2.2) -footerprog = re.compile( - '^ Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n') -emptyprog = re.compile('^[ \t]*\n') -ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n') - - -class EditableManPage(ScrolledText): - """Basic Man Page class -- does not disable editing.""" - - def __init__(self, master=None, **cnf): - ScrolledText.__init__(self, master, **cnf) - - bold = Font(font=self['font']).copy() - bold.config(weight='bold') - italic = Font(font=self['font']).copy() - italic.config(slant='italic') - - # Define tags for formatting styles - self.tag_config('X', underline=1) - self.tag_config('!', font=bold) - self.tag_config('_', font=italic) - - # Set state to idle - self.fp = None - self.lineno = 0 - - def busy(self): - """Test whether we are busy parsing a file.""" - return self.fp != None - - def kill(self): - """Ensure we're not busy.""" - if self.busy(): - self._endparser() - - def asyncparsefile(self, fp): - """Parse a file, in the background.""" - self._startparser(fp) - self.tk.createfilehandler(fp, READABLE, - self._filehandler) - - parsefile = asyncparsefile # Alias - - def _filehandler(self, fp, mask): - """I/O handler used by background parsing.""" - nextline = self.fp.readline() - if not nextline: - self._endparser() - return - self._parseline(nextline) - - def syncparsefile(self, fp): - """Parse a file, now (cannot be aborted).""" - self._startparser(fp) - while True: - nextline = fp.readline() - if not nextline: - break - self._parseline(nextline) - self._endparser() - - def _startparser(self, fp): - """Initialize parsing from a particular file -- must not be busy.""" - if self.busy(): - raise RuntimeError('startparser: still busy') - fp.fileno() # Test for file-ness - self.fp = fp - self.lineno = 0 - self.ok = 0 - self.empty = 0 - self.buffer = None - savestate = self['state'] - self['state'] = NORMAL - self.delete('1.0', END) - self['state'] = savestate - - def _endparser(self): - """End parsing -- must be busy, need not be at EOF.""" - if not self.busy(): - raise RuntimeError('endparser: not busy') - if self.buffer: - self._parseline('') - try: - self.tk.deletefilehandler(self.fp) - except TclError: - pass - self.fp.close() - self.fp = None - del self.ok, self.empty, self.buffer - - def _parseline(self, nextline): - """Parse a single line.""" - if not self.buffer: - # Save this line -- we need one line read-ahead - self.buffer = nextline - return - if emptyprog.match(self.buffer): - # Buffered line was empty -- set a flag - self.empty = 1 - self.buffer = nextline - return - textline = self.buffer - if ulprog.match(nextline): - # Next line is properties for buffered line - propline = nextline - self.buffer = None - else: - # Next line is read-ahead - propline = None - self.buffer = nextline - if not self.ok: - # First non blank line after footer must be header - # -- skip that too - self.ok = 1 - self.empty = 0 - return - if footerprog.match(textline): - # Footer -- start skipping until next non-blank line - self.ok = 0 - self.empty = 0 - return - savestate = self['state'] - self['state'] = NORMAL - if TkVersion >= 4.0: - self.mark_set('insert', 'end-1c') - else: - self.mark_set('insert', END) - if self.empty: - # One or more previous lines were empty - # -- insert one blank line in the text - self._insert_prop('\n') - self.lineno = self.lineno + 1 - self.empty = 0 - if not propline: - # No properties - self._insert_prop(textline) - else: - # Search for properties - p = '' - j = 0 - for i in range(min(len(propline), len(textline))): - if propline[i] != p: - if j < i: - self._insert_prop(textline[j:i], p) - j = i - p = propline[i] - self._insert_prop(textline[j:]) - self.lineno = self.lineno + 1 - self['state'] = savestate - - def _insert_prop(self, str, prop = ' '): - """Insert a string at the end, with at most one property (tag).""" - here = self.index(AtInsert()) - self.insert(AtInsert(), str) - if TkVersion <= 4.0: - tags = self.tag_names(here) - for tag in tags: - self.tag_remove(tag, here, AtInsert()) - if prop != ' ': - self.tag_add(prop, here, AtInsert()) - - -class ReadonlyManPage(EditableManPage): - """Readonly Man Page class -- disables editing, otherwise the same.""" - - def __init__(self, master=None, **cnf): - cnf['state'] = DISABLED - EditableManPage.__init__(self, master, **cnf) - -# Alias -ManPage = ReadonlyManPage - -# usage: ManPage [manpage]; or ManPage [-f] file -# -f means that the file is nroff -man output run through ul -i -def main(): - # XXX This directory may be different on your system - MANDIR = '' - DEFAULTPAGE = 'Tcl' - formatted = 0 - if sys.argv[1:] and sys.argv[1] == '-f': - formatted = 1 - del sys.argv[1] - if sys.argv[1:]: - name = sys.argv[1] - else: - name = DEFAULTPAGE - if not formatted: - if name[-2:-1] != '.': - name = name + '.n' - name = os.path.join(MANDIR, name) - root = Tk() - root.minsize(1, 1) - manpage = ManPage(root, relief=SUNKEN, borderwidth=2) - manpage.pack(expand=1, fill=BOTH) - if formatted: - fp = open(name, 'r') - else: - fp = os.popen('nroff -man -c %s | ul -i' % name, 'r') - manpage.parsefile(fp) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/mbox.py b/Demo/tkinter/guido/mbox.py deleted file mode 100755 index 754a312..0000000 --- a/Demo/tkinter/guido/mbox.py +++ /dev/null @@ -1,286 +0,0 @@ -#! /usr/bin/env python - -# Scan MH folder, display results in window - -import os -import re -import sys -import getopt -import mailbox -from tkinter import * - -from dialog import dialog - -MBOXPATH = os.environ['HOME'] + '/Mail' - -def main(): - global root, tk, top, mid, bot - global folderbox, foldermenu, scanbox, scanmenu, viewer - global folder, seq - global mh, mhf - - # Parse command line options - - folder = 'inbox' - seq = 'all' - try: - opts, args = getopt.getopt(sys.argv[1:], '') - except getopt.error as msg: - print(msg) - sys.exit(2) - for arg in args: - if arg[:1] == '+': - folder = arg[1:] - else: - seq = arg - - # Initialize MH - - mh = mailbox.MH(MBOXPATH) - mhf = mh.get_folder(folder) - - # Build widget hierarchy - - root = Tk() - tk = root.tk - - top = Frame(root) - top.pack({'expand': 1, 'fill': 'both'}) - - # Build right part: folder list - - right = Frame(top) - right.pack({'fill': 'y', 'side': 'right'}) - - folderbar = Scrollbar(right, {'relief': 'sunken', 'bd': 2}) - folderbar.pack({'fill': 'y', 'side': 'right'}) - - folderbox = Listbox(right, {'exportselection': 0}) - folderbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'}) - - foldermenu = Menu(root) - foldermenu.add('command', - {'label': 'Open Folder', - 'command': open_folder}) - foldermenu.add('separator') - foldermenu.add('command', - {'label': 'Quit', - 'command': 'exit'}) - foldermenu.bind('<ButtonRelease-3>', folder_unpost) - - folderbox['yscrollcommand'] = (folderbar, 'set') - folderbar['command'] = (folderbox, 'yview') - folderbox.bind('<Double-1>', open_folder, 1) - folderbox.bind('<3>', folder_post) - - # Build left part: scan list - - left = Frame(top) - left.pack({'expand': 1, 'fill': 'both', 'side': 'left'}) - - scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2}) - scanbar.pack({'fill': 'y', 'side': 'right'}) - - scanbox = Listbox(left, {'font': 'fixed'}) - scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'}) - - scanmenu = Menu(root) - scanmenu.add('command', - {'label': 'Open Message', - 'command': open_message}) - scanmenu.add('command', - {'label': 'Remove Message', - 'command': remove_message}) - scanmenu.add('command', - {'label': 'Refile Message', - 'command': refile_message}) - scanmenu.add('separator') - scanmenu.add('command', - {'label': 'Quit', - 'command': 'exit'}) - scanmenu.bind('<ButtonRelease-3>', scan_unpost) - - scanbox['yscrollcommand'] = (scanbar, 'set') - scanbar['command'] = (scanbox, 'yview') - scanbox.bind('<Double-1>', open_message) - scanbox.bind('<3>', scan_post) - - # Separator between middle and bottom part - - rule2 = Frame(root, {'bg': 'black'}) - rule2.pack({'fill': 'x'}) - - # Build bottom part: current message - - bot = Frame(root) - bot.pack({'expand': 1, 'fill': 'both'}) - # - viewer = None - - # Window manager commands - - root.minsize(800, 1) # Make window resizable - - # Fill folderbox with text - - setfolders() - - # Fill scanbox with text - - rescan() - - # Enter mainloop - - root.mainloop() - -def folder_post(e): - x, y = e.x_root, e.y_root - foldermenu.post(x - 10, y - 10) - foldermenu.grab_set() - -def folder_unpost(e): - tk.call('update', 'idletasks') - foldermenu.grab_release() - foldermenu.unpost() - foldermenu.invoke('active') - -def scan_post(e): - x, y = e.x_root, e.y_root - scanmenu.post(x - 10, y - 10) - scanmenu.grab_set() - -def scan_unpost(e): - tk.call('update', 'idletasks') - scanmenu.grab_release() - scanmenu.unpost() - scanmenu.invoke('active') - -scanparser = re.compile('^ *([0-9]+)') - -def open_folder(e=None): - global folder, mhf - sel = folderbox.curselection() - if len(sel) != 1: - if len(sel) > 1: - msg = "Please open one folder at a time" - else: - msg = "Please select a folder to open" - dialog(root, "Can't Open Folder", msg, "", 0, "OK") - return - i = sel[0] - folder = folderbox.get(i) - mhf = mh.get_folder(folder) - rescan() - -def open_message(e=None): - global viewer - sel = scanbox.curselection() - if len(sel) != 1: - if len(sel) > 1: - msg = "Please open one message at a time" - else: - msg = "Please select a message to open" - dialog(root, "Can't Open Message", msg, "", 0, "OK") - return - cursor = scanbox['cursor'] - scanbox['cursor'] = 'watch' - tk.call('update', 'idletasks') - i = sel[0] - line = scanbox.get(i) - m = scanparser.match(line) - if m: - num = int(m.group(1)) - m = mhf.get_message(num) - if viewer: viewer.destroy() - from mimeviewer import MimeViewer - viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m) - viewer.pack() - viewer.show() - scanbox['cursor'] = cursor - -def interestingheader(header): - return header != 'received' - -def remove_message(e=None): - itop = scanbox.nearest(0) - sel = scanbox.curselection() - if not sel: - dialog(root, "No Message To Remove", - "Please select a message to remove", "", 0, "OK") - return - todo = [] - for i in sel: - line = scanbox.get(i) - m = scanparser.match(line) - if m: - toremove = int(m.group(1)) - todo.append(toremove) - mhf.remove(toremove) - rescan() - fixfocus(min(todo), itop) - -lastrefile = '' -tofolder = None -def refile_message(e=None): - global lastrefile, tofolder - itop = scanbox.nearest(0) - sel = scanbox.curselection() - if not sel: - dialog(root, "No Message To Refile", - "Please select a message to refile", "", 0, "OK") - return - foldersel = folderbox.curselection() - if len(foldersel) != 1: - if not foldersel: - msg = "Please select a folder to refile to" - else: - msg = "Please select exactly one folder to refile to" - dialog(root, "No Folder To Refile", msg, "", 0, "OK") - return - refileto = folderbox.get(foldersel[0]) - todo = [] - for i in sel: - line = scanbox.get(i) - m = scanparser.match(line) - if m: - todo.append(int(m.group(1))) - if lastrefile != refileto or not tofolder: - lastrefile = refileto - tofolder = None - tofolder = mh.get_folder(lastrefile) - mhf.refilemessages(todo, tofolder) - rescan() - fixfocus(min(todo), itop) - -def fixfocus(near, itop): - n = scanbox.size() - for i in range(n): - line = scanbox.get(repr(i)) - m = scanparser.match(line) - if m: - num = int(m.group(1)) - if num >= near: - break - else: - i = 'end' - scanbox.yview(itop) - -def setfolders(): - folderbox.delete(0, 'end') - for fn in mh.list_folders(): - folderbox.insert('end', fn) - -def rescan(): - global viewer - if viewer: - viewer.destroy() - viewer = None - scanbox.delete(0, 'end') - for line in scanfolder(folder, seq): - scanbox.insert('end', line) - -def scanfolder(folder = 'inbox', sequence = 'all'): - return [line[:-1] for line in - os.popen('scan +%s %s' % (folder, sequence), 'r').readlines()] - -main() diff --git a/Demo/tkinter/guido/mimeviewer.py b/Demo/tkinter/guido/mimeviewer.py deleted file mode 100755 index babed8f..0000000 --- a/Demo/tkinter/guido/mimeviewer.py +++ /dev/null @@ -1,159 +0,0 @@ -#! /usr/bin/env python3 - -# View a single MIME multipart message. -# Display each part as a box. - -import os -import sys -import getopt -import mailbox -from tkinter import * -from tkinter.scrolledtext import ScrolledText - -MBOXPATH = os.environ['HOME'] + '/Mail' - -class Error(Exception): - pass - -def getcurrent(self): - """Return the current message. Raise Error when there is none.""" - seqs = self.get_sequences() - try: - return max(seqs['cur']) - except (ValueError, KeyError): - raise Error("no cur message") - - -class MimeViewer: - def __init__(self, parent, title, msg): - self.title = title - self.msg = msg - self.frame = Frame(parent, {'relief': 'raised', 'bd': 2}) - self.frame.packing = {'expand': 0, 'fill': 'both'} - self.button = Checkbutton(self.frame, - {'text': title, - 'command': self.toggle}) - self.button.pack({'anchor': 'w'}) - headertext = [] - for item in msg.items(): - headertext.append("%s: %s" % item) - headertext = '\n'.join(headertext) - height = countlines(headertext, 4) - if height: - self.htext = ScrolledText(self.frame, - {'height': height, - 'width': 80, - 'wrap': 'none', - 'relief': 'raised', - 'bd': 2}) - self.htext.packing = {'expand': 1, 'fill': 'both', - 'after': self.button} - self.htext.insert('end', headertext) - else: - self.htext = Frame(self.frame, - {'relief': 'raised', 'bd': 2}) - self.htext.packing = {'side': 'top', - 'ipady': 2, - 'fill': 'x', - 'after': self.button} - body = msg.get_payload() - if type(body) == str: - self.pad = None - height = countlines(body, 10) - if height: - self.btext = ScrolledText(self.frame, - {'height': height, - 'width': 80, - 'wrap': 'none', - 'relief': 'raised', - 'bd': 2}) - self.btext.packing = {'expand': 1, - 'fill': 'both'} - self.btext.insert('end', body) - else: - self.btext = None - self.parts = None - else: - self.pad = Frame(self.frame, - {'relief': 'flat', 'bd': 2}) - self.pad.packing = {'side': 'left', 'ipadx': 10, - 'fill': 'y', 'after': self.htext} - self.parts = [] - for i in range(len(body)): - p = MimeViewer(self.frame, - '%s.%d' % (title, i+1), - body[i]) - self.parts.append(p) - self.btext = None - self.collapsed = 1 - def pack(self): - self.frame.pack(self.frame.packing) - def destroy(self): - self.frame.destroy() - def show(self): - if self.collapsed: - self.button.invoke() - def toggle(self): - if self.collapsed: - self.explode() - else: - self.collapse() - def collapse(self): - self.collapsed = 1 - for comp in self.htext, self.btext, self.pad: - if comp: - comp.forget() - if self.parts: - for part in self.parts: - part.frame.forget() - self.frame.pack({'expand': 0}) - def explode(self): - self.collapsed = 0 - for comp in self.htext, self.btext, self.pad: - if comp: comp.pack(comp.packing) - if self.parts: - for part in self.parts: - part.pack() - self.frame.pack({'expand': 1}) - -def countlines(str, limit): - i = 0 - n = 0 - while n < limit: - i = str.find('\n', i) - if i < 0: break - n = n+1 - i = i+1 - return n - -def main(): - opts, args = getopt.getopt(sys.argv[1:], '') - for o, a in opts: - pass - message = None - folder = 'inbox' - for arg in args: - if arg[:1] == '+': - folder = arg[1:] - else: - message = int(arg) - - mh = mailbox.MH(MBOXPATH) - f = mh.get_folder(folder) - if message is None: - message = getcurrent(f) - m = mailbox.MHMessage(f.get(message)) - - root = Tk() - tk = root.tk - - top = MimeViewer(root, '+%s/%d' % (folder, message), m) - top.pack() - top.show() - - root.minsize(1, 1) - - tk.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/newmenubardemo.py b/Demo/tkinter/guido/newmenubardemo.py deleted file mode 100644 index 51c4e64..0000000 --- a/Demo/tkinter/guido/newmenubardemo.py +++ /dev/null @@ -1,47 +0,0 @@ -#! /usr/bin/env python - -"""Play with the new Tk 8.0 toplevel menu option.""" - -from tkinter import * - -class App: - - def __init__(self, master): - self.master = master - - self.menubar = Menu(self.master) - - self.filemenu = Menu(self.menubar) - - self.filemenu.add_command(label="New") - self.filemenu.add_command(label="Open...") - self.filemenu.add_command(label="Close") - self.filemenu.add_separator() - self.filemenu.add_command(label="Quit", command=self.master.quit) - - self.editmenu = Menu(self.menubar) - - self.editmenu.add_command(label="Cut") - self.editmenu.add_command(label="Copy") - self.editmenu.add_command(label="Paste") - - self.helpmenu = Menu(self.menubar, name='help') - - self.helpmenu.add_command(label="About...") - - self.menubar.add_cascade(label="File", menu=self.filemenu) - self.menubar.add_cascade(label="Edit", menu=self.editmenu) - self.menubar.add_cascade(label="Help", menu=self.helpmenu) - - self.top = Toplevel(menu=self.menubar) - - # Rest of app goes here... - -def main(): - root = Tk() - root.withdraw() - app = App(root) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/optionmenu.py b/Demo/tkinter/guido/optionmenu.py deleted file mode 100644 index 1e72aa5..0000000 --- a/Demo/tkinter/guido/optionmenu.py +++ /dev/null @@ -1,27 +0,0 @@ -# option menu sample (Fredrik Lundh, September 1997) - -from tkinter import * - -root = Tk() - -# -# standard usage - -var1 = StringVar() -var1.set("One") # default selection - -menu1 = OptionMenu(root, var1, "One", "Two", "Three") -menu1.pack() - -# -# initialize from a sequence - -CHOICES = "Aah", "Bee", "Cee", "Dee", "Eff" - -var2 = StringVar() -var2.set(CHOICES[0]) - -menu2 = OptionMenu(root, var2, *CHOICES) -menu2.pack() - -root.mainloop() diff --git a/Demo/tkinter/guido/paint.py b/Demo/tkinter/guido/paint.py deleted file mode 100644 index 65f2353..0000000 --- a/Demo/tkinter/guido/paint.py +++ /dev/null @@ -1,60 +0,0 @@ -""""Paint program by Dave Michell. - -Subject: tkinter "paint" example -From: Dave Mitchell <davem@magnet.com> -To: python-list@cwi.nl -Date: Fri, 23 Jan 1998 12:18:05 -0500 (EST) - - Not too long ago (last week maybe?) someone posted a request -for an example of a paint program using Tkinter. Try as I might -I can't seem to find it in the archive, so i'll just post mine -here and hope that the person who requested it sees this! - - All this does is put up a canvas and draw a smooth black line -whenever you have the mouse button down, but hopefully it will -be enough to start with.. It would be easy enough to add some -options like other shapes or colors... - - yours, - dave mitchell - davem@magnet.com -""" - -from tkinter import * - -"""paint.py: not exactly a paint program.. just a smooth line drawing demo.""" - -b1 = "up" -xold, yold = None, None - -def main(): - root = Tk() - drawing_area = Canvas(root) - drawing_area.pack() - drawing_area.bind("<Motion>", motion) - drawing_area.bind("<ButtonPress-1>", b1down) - drawing_area.bind("<ButtonRelease-1>", b1up) - root.mainloop() - -def b1down(event): - global b1 - b1 = "down" # you only want to draw when the button is down - # because "Motion" events happen -all the time- - -def b1up(event): - global b1, xold, yold - b1 = "up" - xold = None # reset the line when you let go of the button - yold = None - -def motion(event): - if b1 == "down": - global xold, yold - if xold is not None and yold is not None: - event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE) - # here's where you draw it. smooth. neat. - xold = event.x - yold = event.y - -if __name__ == "__main__": - main() diff --git a/Demo/tkinter/guido/rmt.py b/Demo/tkinter/guido/rmt.py deleted file mode 100755 index 350d60b..0000000 --- a/Demo/tkinter/guido/rmt.py +++ /dev/null @@ -1,159 +0,0 @@ -#! /usr/bin/env python - -# A Python program implementing rmt, an application for remotely -# controlling other Tk applications. -# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.5-8, pp. 273-276. - -# Note that because of forward references in the original, we -# sometimes delay bindings until after the corresponding procedure is -# defined. We also introduce names for some unnamed code blocks in -# the original because of restrictions on lambda forms in Python. - -# XXX This should be written in a more Python-like style!!! - -from tkinter import * -import sys - -# 1. Create basic application structure: menu bar on top of -# text widget, scrollbar on right. - -root = Tk() -tk = root.tk -mBar = Frame(root, relief=RAISED, borderwidth=2) -mBar.pack(fill=X) - -f = Frame(root) -f.pack(expand=1, fill=BOTH) -s = Scrollbar(f, relief=FLAT) -s.pack(side=RIGHT, fill=Y) -t = Text(f, relief=RAISED, borderwidth=2, yscrollcommand=s.set, setgrid=1) -t.pack(side=LEFT, fill=BOTH, expand=1) -t.tag_config('bold') -s['command'] = t.yview - -root.title('Tk Remote Controller') -root.iconname('Tk Remote') - -# 2. Create menu button and menus. - -file = Menubutton(mBar, text='File', underline=0) -file.pack(side=LEFT) -file_m = Menu(file) -file['menu'] = file_m -file_m_apps = Menu(file_m, tearoff=0) -file_m.add_cascade(label='Select Application', underline=0, - menu=file_m_apps) -file_m.add_command(label='Quit', underline=0, command=sys.exit) - -# 3. Create bindings for text widget to allow commands to be -# entered and information to be selected. New characters -# can only be added at the end of the text (can't ever move -# insertion point). - -def single1(e): - x = e.x - y = e.y - t.setvar('tk_priv(selectMode)', 'char') - t.mark_set('anchor', At(x, y)) - # Should focus W -t.bind('<1>', single1) - -def double1(e): - x = e.x - y = e.y - t.setvar('tk_priv(selectMode)', 'word') - t.tk_textSelectTo(At(x, y)) -t.bind('<Double-1>', double1) - -def triple1(e): - x = e.x - y = e.y - t.setvar('tk_priv(selectMode)', 'line') - t.tk_textSelectTo(At(x, y)) -t.bind('<Triple-1>', triple1) - -def returnkey(e): - t.insert(AtInsert(), '\n') - invoke() -t.bind('<Return>', returnkey) - -def controlv(e): - t.insert(AtInsert(), t.selection_get()) - t.yview_pickplace(AtInsert()) - if t.index(AtInsert())[-2:] == '.0': - invoke() -t.bind('<Control-v>', controlv) - -# 4. Procedure to backspace over one character, as long as -# the character isn't part of the prompt. - -def backspace(e): - if t.index('promptEnd') != t.index('insert - 1 char'): - t.delete('insert - 1 char', AtInsert()) - t.yview_pickplace(AtInsert()) -t.bind('<BackSpace>', backspace) -t.bind('<Control-h>', backspace) -t.bind('<Delete>', backspace) - - -# 5. Procedure that's invoked when return is typed: if -# there's not yet a complete command (e.g. braces are open) -# then do nothing. Otherwise, execute command (locally or -# remotely), output the result or error message, and issue -# a new prompt. - -def invoke(): - cmd = t.get('promptEnd + 1 char', AtInsert()) - if t.getboolean(tk.call('info', 'complete', cmd)): # XXX - if app == root.winfo_name(): - msg = tk.call('eval', cmd) # XXX - else: - msg = t.send(app, cmd) - if msg: - t.insert(AtInsert(), msg + '\n') - prompt() - t.yview_pickplace(AtInsert()) - -def prompt(): - t.insert(AtInsert(), app + ': ') - t.mark_set('promptEnd', 'insert - 1 char') - t.tag_add('bold', 'insert linestart', 'promptEnd') - -# 6. Procedure to select a new application. Also changes -# the prompt on the current command line to reflect the new -# name. - -def newApp(appName): - global app - app = appName - t.delete('promptEnd linestart', 'promptEnd') - t.insert('promptEnd', appName + ':') - t.tag_add('bold', 'promptEnd linestart', 'promptEnd') - -def fillAppsMenu(): - file_m_apps.add('command') - file_m_apps.delete(0, 'last') - names = root.winfo_interps() - names = list(names) # convert tuple to list - names.sort() - for name in names: - try: - root.send(name, 'winfo name .') - except TclError: - # Inoperative window -- ignore it - pass - else: - file_m_apps.add_command( - label=name, - command=lambda name=name: newApp(name)) - -file_m_apps['postcommand'] = fillAppsMenu -mBar.tk_menuBar(file) - -# 7. Miscellaneous initialization. - -app = root.winfo_name() -prompt() -t.focus() - -root.mainloop() diff --git a/Demo/tkinter/guido/shell_window.py b/Demo/tkinter/guido/shell_window.py deleted file mode 100644 index c5a0401..0000000 --- a/Demo/tkinter/guido/shell_window.py +++ /dev/null @@ -1,146 +0,0 @@ -import os -import sys -from tkinter import * -from tkinter.scrolledtext import ScrolledText -from tkinter.dialog import Dialog -import signal - -BUFSIZE = 512 - -class ShellWindow(ScrolledText): - - def __init__(self, master=None, shell=None, **cnf): - if not shell: - try: - shell = os.environ['SHELL'] - except KeyError: - shell = '/bin/sh' - shell = shell + ' -i' - args = shell.split() - shell = args[0] - - ScrolledText.__init__(self, master, **cnf) - self.pos = '1.0' - self.bind('<Return>', self.inputhandler) - self.bind('<Control-c>', self.sigint) - self.bind('<Control-t>', self.sigterm) - self.bind('<Control-k>', self.sigkill) - self.bind('<Control-d>', self.sendeof) - - self.pid, self.fromchild, self.tochild = spawn(shell, args) - self.tk.createfilehandler(self.fromchild, READABLE, - self.outputhandler) - - def outputhandler(self, file, mask): - data = os.read(file, BUFSIZE).decode() - if not data: - self.tk.deletefilehandler(file) - pid, sts = os.waitpid(self.pid, 0) - print('pid', pid, 'status', sts) - self.pid = None - detail = sts>>8 - cause = sts & 0xff - if cause == 0: - msg = "exit status %d" % detail - else: - msg = "killed by signal %d" % (cause & 0x7f) - if cause & 0x80: - msg = msg + " -- core dumped" - Dialog(self.master, - text=msg, - title="Exit status", - bitmap='warning', - default=0, - strings=('OK',)) - return - self.insert(END, data) - self.pos = self.index("end - 1 char") - self.yview_pickplace(END) - - def inputhandler(self, *args): - if not self.pid: - self.no_process() - return "break" - self.insert(END, "\n") - line = self.get(self.pos, "end - 1 char") - self.pos = self.index(END) - os.write(self.tochild, line.encode()) - return "break" - - def sendeof(self, *args): - if not self.pid: - self.no_process() - return "break" - os.close(self.tochild) - return "break" - - def sendsig(self, sig): - if not self.pid: - self.no_process() - return "break" - os.kill(self.pid, sig) - return "break" - - def sigint(self, *args): - return self.sendsig(signal.SIGINT) - - def sigquit(self, *args): - return self.sendsig(signal.SIGQUIT) - - def sigterm(self, *args): - return self.sendsig(signal.SIGTERM) - - def sigkill(self, *args): - return self.sendsig(signal.SIGKILL) - - def no_process(self): - Dialog(self.master, - text="No active process", - title="No process", - bitmap='error', - default=0, - strings=('OK',)) - -MAXFD = 100 # Max number of file descriptors (os.getdtablesize()???) - -def spawn(prog, args): - p2cread, p2cwrite = os.pipe() - c2pread, c2pwrite = os.pipe() - pid = os.fork() - if pid == 0: - # Child - for i in 0, 1, 2: - try: - os.close(i) - except os.error: - pass - if os.dup(p2cread) != 0: - sys.stderr.write('popen2: bad read dup\n') - if os.dup(c2pwrite) != 1: - sys.stderr.write('popen2: bad write dup\n') - if os.dup(c2pwrite) != 2: - sys.stderr.write('popen2: bad write dup\n') - os.closerange(3, MAXFD) - try: - os.execvp(prog, args) - finally: - sys.stderr.write('execvp failed\n') - os._exit(1) - os.close(p2cread) - os.close(c2pwrite) - return pid, c2pread, p2cwrite - -def test(): - shell = ' '.join(sys.argv[1: ]) - root = Tk() - root.minsize(1, 1) - if shell: - w = ShellWindow(root, shell=shell) - else: - w = ShellWindow(root) - w.pack(expand=1, fill=BOTH) - w.focus_set() - w.tk.mainloop() - -if __name__ == '__main__': - test() diff --git a/Demo/tkinter/guido/solitaire.py b/Demo/tkinter/guido/solitaire.py deleted file mode 100755 index 43106e1..0000000 --- a/Demo/tkinter/guido/solitaire.py +++ /dev/null @@ -1,626 +0,0 @@ -#! /usr/bin/env python - -"""Solitaire game, much like the one that comes with MS Windows. - -Limitations: - -- No cute graphical images for the playing cards faces or backs. -- No scoring or timer. -- No undo. -- No option to turn 3 cards at a time. -- No keyboard shortcuts. -- Less fancy animation when you win. -- The determination of which stack you drag to is more relaxed. - -Apology: - -I'm not much of a card player, so my terminology in these comments may -at times be a little unusual. If you have suggestions, please let me -know! - -""" - -# Imports - -import random - -from tkinter import * -from canvasevents import Group - - -# Constants determining the size and lay-out of cards and stacks. We -# work in a "grid" where each card/stack is surrounded by MARGIN -# pixels of space on each side, so adjacent stacks are separated by -# 2*MARGIN pixels. OFFSET is the offset used for displaying the -# face down cards in the row stacks. - -CARDWIDTH = 100 -CARDHEIGHT = 150 -MARGIN = 10 -XSPACING = CARDWIDTH + 2*MARGIN -YSPACING = CARDHEIGHT + 4*MARGIN -OFFSET = 5 - -# The background color, green to look like a playing table. The -# standard green is way too bright, and dark green is way to dark, so -# we use something in between. (There are a few more colors that -# could be customized, but they are less controversial.) - -BACKGROUND = '#070' - - -# Suits and colors. The values of the symbolic suit names are the -# strings used to display them (you change these and VALNAMES to -# internationalize the game). The COLOR dictionary maps suit names to -# colors (red and black) which must be Tk color names. The keys() of -# the COLOR dictionary conveniently provides us with a list of all -# suits (in arbitrary order). - -HEARTS = 'Heart' -DIAMONDS = 'Diamond' -CLUBS = 'Club' -SPADES = 'Spade' - -RED = 'red' -BLACK = 'black' - -COLOR = {} -for s in (HEARTS, DIAMONDS): - COLOR[s] = RED -for s in (CLUBS, SPADES): - COLOR[s] = BLACK - -ALLSUITS = list(COLOR.keys()) -NSUITS = len(ALLSUITS) - - -# Card values are 1-13. We also define symbolic names for the picture -# cards. ALLVALUES is a list of all card values. - -ACE = 1 -JACK = 11 -QUEEN = 12 -KING = 13 -ALLVALUES = range(1, 14) # (one more than the highest value) -NVALUES = len(ALLVALUES) - - -# VALNAMES is a list that maps a card value to string. It contains a -# dummy element at index 0 so it can be indexed directly with the card -# value. - -VALNAMES = ["", "A"] + list(map(str, range(2, 11))) + ["J", "Q", "K"] - - -# Solitaire constants. The only one I can think of is the number of -# row stacks. - -NROWS = 7 - - -# The rest of the program consists of class definitions. These are -# further described in their documentation strings. - - -class Card: - - """A playing card. - - A card doesn't record to which stack it belongs; only the stack - records this (it turns out that we always know this from the - context, and this saves a ``double update'' with potential for - inconsistencies). - - Public methods: - - moveto(x, y) -- move the card to an absolute position - moveby(dx, dy) -- move the card by a relative offset - tkraise() -- raise the card to the top of its stack - showface(), showback() -- turn the card face up or down & raise it - - Public read-only instance variables: - - suit, value, color -- the card's suit, value and color - face_shown -- true when the card is shown face up, else false - - Semi-public read-only instance variables (XXX should be made - private): - - group -- the Canvas.Group representing the card - x, y -- the position of the card's top left corner - - Private instance variables: - - __back, __rect, __text -- the canvas items making up the card - - (To show the card face up, the text item is placed in front of - rect and the back is placed behind it. To show it face down, this - is reversed. The card is created face down.) - - """ - - def __init__(self, suit, value, canvas): - """Card constructor. - - Arguments are the card's suit and value, and the canvas widget. - - The card is created at position (0, 0), with its face down - (adding it to a stack will position it according to that - stack's rules). - - """ - self.suit = suit - self.value = value - self.color = COLOR[suit] - self.face_shown = 0 - - self.x = self.y = 0 - self.canvas = canvas - self.group = Group(canvas) - - text = "%s %s" % (VALNAMES[value], suit) - self.__text = canvas.create_text(CARDWIDTH // 2, 0, anchor=N, - fill=self.color, text=text) - self.group.addtag_withtag(self.__text) - - self.__rect = canvas.create_rectangle(0, 0, CARDWIDTH, CARDHEIGHT, - outline='black', fill='white') - self.group.addtag_withtag(self.__rect) - - self.__back = canvas.create_rectangle(MARGIN, MARGIN, - CARDWIDTH - MARGIN, - CARDHEIGHT - MARGIN, - outline='black', fill='blue') - self.group.addtag_withtag(self.__back) - - def __repr__(self): - """Return a string for debug print statements.""" - return "Card(%r, %r)" % (self.suit, self.value) - - def moveto(self, x, y): - """Move the card to absolute position (x, y).""" - self.moveby(x - self.x, y - self.y) - - def moveby(self, dx, dy): - """Move the card by (dx, dy).""" - self.x = self.x + dx - self.y = self.y + dy - self.group.move(dx, dy) - - def tkraise(self): - """Raise the card above all other objects in its canvas.""" - self.group.tkraise() - - def showface(self): - """Turn the card's face up.""" - self.tkraise() - self.canvas.tag_raise(self.__rect) - self.canvas.tag_raise(self.__text) - self.face_shown = 1 - - def showback(self): - """Turn the card's face down.""" - self.tkraise() - self.canvas.tag_raise(self.__rect) - self.canvas.tag_raise(self.__back) - self.face_shown = 0 - - -class Stack: - - """A generic stack of cards. - - This is used as a base class for all other stacks (e.g. the deck, - the suit stacks, and the row stacks). - - Public methods: - - add(card) -- add a card to the stack - delete(card) -- delete a card from the stack - showtop() -- show the top card (if any) face up - deal() -- delete and return the top card, or None if empty - - Method that subclasses may override: - - position(card) -- move the card to its proper (x, y) position - - The default position() method places all cards at the stack's - own (x, y) position. - - userclickhandler(), userdoubleclickhandler() -- called to do - subclass specific things on single and double clicks - - The default user (single) click handler shows the top card - face up. The default user double click handler calls the user - single click handler. - - usermovehandler(cards) -- called to complete a subpile move - - The default user move handler moves all moved cards back to - their original position (by calling the position() method). - - Private methods: - - clickhandler(event), doubleclickhandler(event), - motionhandler(event), releasehandler(event) -- event handlers - - The default event handlers turn the top card of the stack with - its face up on a (single or double) click, and also support - moving a subpile around. - - startmoving(event) -- begin a move operation - finishmoving() -- finish a move operation - - """ - - def __init__(self, x, y, game=None): - """Stack constructor. - - Arguments are the stack's nominal x and y position (the top - left corner of the first card placed in the stack), and the - game object (which is used to get the canvas; subclasses use - the game object to find other stacks). - - """ - self.x = x - self.y = y - self.game = game - self.cards = [] - self.group = Group(self.game.canvas) - self.group.bind('<1>', self.clickhandler) - self.group.bind('<Double-1>', self.doubleclickhandler) - self.group.bind('<B1-Motion>', self.motionhandler) - self.group.bind('<ButtonRelease-1>', self.releasehandler) - self.makebottom() - - def makebottom(self): - pass - - def __repr__(self): - """Return a string for debug print statements.""" - return "%s(%d, %d)" % (self.__class__.__name__, self.x, self.y) - - # Public methods - - def add(self, card): - self.cards.append(card) - card.tkraise() - self.position(card) - self.group.addtag_withtag(card.group) - - def delete(self, card): - self.cards.remove(card) - card.group.dtag(self.group) - - def showtop(self): - if self.cards: - self.cards[-1].showface() - - def deal(self): - if not self.cards: - return None - card = self.cards[-1] - self.delete(card) - return card - - # Subclass overridable methods - - def position(self, card): - card.moveto(self.x, self.y) - - def userclickhandler(self): - self.showtop() - - def userdoubleclickhandler(self): - self.userclickhandler() - - def usermovehandler(self, cards): - for card in cards: - self.position(card) - - # Event handlers - - def clickhandler(self, event): - self.finishmoving() # In case we lost an event - self.userclickhandler() - self.startmoving(event) - - def motionhandler(self, event): - self.keepmoving(event) - - def releasehandler(self, event): - self.keepmoving(event) - self.finishmoving() - - def doubleclickhandler(self, event): - self.finishmoving() # In case we lost an event - self.userdoubleclickhandler() - self.startmoving(event) - - # Move internals - - moving = None - - def startmoving(self, event): - self.moving = None - tags = self.game.canvas.gettags('current') - for i in range(len(self.cards)): - card = self.cards[i] - if card.group.tag in tags: - break - else: - return - if not card.face_shown: - return - self.moving = self.cards[i:] - self.lastx = event.x - self.lasty = event.y - for card in self.moving: - card.tkraise() - - def keepmoving(self, event): - if not self.moving: - return - dx = event.x - self.lastx - dy = event.y - self.lasty - self.lastx = event.x - self.lasty = event.y - if dx or dy: - for card in self.moving: - card.moveby(dx, dy) - - def finishmoving(self): - cards = self.moving - self.moving = None - if cards: - self.usermovehandler(cards) - - -class Deck(Stack): - - """The deck is a stack with support for shuffling. - - New methods: - - fill() -- create the playing cards - shuffle() -- shuffle the playing cards - - A single click moves the top card to the game's open deck and - moves it face up; if we're out of cards, it moves the open deck - back to the deck. - - """ - - def makebottom(self): - bottom = self.game.canvas.create_rectangle(self.x, self.y, - self.x + CARDWIDTH, self.y + CARDHEIGHT, outline='black', - fill=BACKGROUND) - self.group.addtag_withtag(bottom) - - def fill(self): - for suit in ALLSUITS: - for value in ALLVALUES: - self.add(Card(suit, value, self.game.canvas)) - - def shuffle(self): - n = len(self.cards) - newcards = [] - for i in randperm(n): - newcards.append(self.cards[i]) - self.cards = newcards - - def userclickhandler(self): - opendeck = self.game.opendeck - card = self.deal() - if not card: - while 1: - card = opendeck.deal() - if not card: - break - self.add(card) - card.showback() - else: - self.game.opendeck.add(card) - card.showface() - - -def randperm(n): - """Function returning a random permutation of range(n).""" - r = list(range(n)) - x = [] - while r: - i = random.choice(r) - x.append(i) - r.remove(i) - return x - - -class OpenStack(Stack): - - def acceptable(self, cards): - return 0 - - def usermovehandler(self, cards): - card = cards[0] - stack = self.game.closeststack(card) - if not stack or stack is self or not stack.acceptable(cards): - Stack.usermovehandler(self, cards) - else: - for card in cards: - self.delete(card) - stack.add(card) - self.game.wincheck() - - def userdoubleclickhandler(self): - if not self.cards: - return - card = self.cards[-1] - if not card.face_shown: - self.userclickhandler() - return - for s in self.game.suits: - if s.acceptable([card]): - self.delete(card) - s.add(card) - self.game.wincheck() - break - - -class SuitStack(OpenStack): - - def makebottom(self): - bottom = self.game.canvas.create_rectangle(self.x, self.y, - self.x + CARDWIDTH, self.y + CARDHEIGHT, outline='black', fill='') - - def userclickhandler(self): - pass - - def userdoubleclickhandler(self): - pass - - def acceptable(self, cards): - if len(cards) != 1: - return 0 - card = cards[0] - if not self.cards: - return card.value == ACE - topcard = self.cards[-1] - return card.suit == topcard.suit and card.value == topcard.value + 1 - - -class RowStack(OpenStack): - - def acceptable(self, cards): - card = cards[0] - if not self.cards: - return card.value == KING - topcard = self.cards[-1] - if not topcard.face_shown: - return 0 - return card.color != topcard.color and card.value == topcard.value - 1 - - def position(self, card): - y = self.y - for c in self.cards: - if c == card: - break - if c.face_shown: - y = y + 2*MARGIN - else: - y = y + OFFSET - card.moveto(self.x, y) - - -class Solitaire: - - def __init__(self, master): - self.master = master - - self.canvas = Canvas(self.master, - background=BACKGROUND, - highlightthickness=0, - width=NROWS*XSPACING, - height=3*YSPACING + 20 + MARGIN) - self.canvas.pack(fill=BOTH, expand=TRUE) - - self.dealbutton = Button(self.canvas, - text="Deal", - highlightthickness=0, - background=BACKGROUND, - activebackground="green", - command=self.deal) - self.canvas.create_window(MARGIN, 3 * YSPACING + 20, - window=self.dealbutton, anchor=SW) - - x = MARGIN - y = MARGIN - - self.deck = Deck(x, y, self) - - x = x + XSPACING - self.opendeck = OpenStack(x, y, self) - - x = x + XSPACING - self.suits = [] - for i in range(NSUITS): - x = x + XSPACING - self.suits.append(SuitStack(x, y, self)) - - x = MARGIN - y = y + YSPACING - - self.rows = [] - for i in range(NROWS): - self.rows.append(RowStack(x, y, self)) - x = x + XSPACING - - self.openstacks = [self.opendeck] + self.suits + self.rows - - self.deck.fill() - self.deal() - - def wincheck(self): - for s in self.suits: - if len(s.cards) != NVALUES: - return - self.win() - self.deal() - - def win(self): - """Stupid animation when you win.""" - cards = [] - for s in self.openstacks: - cards = cards + s.cards - while cards: - card = random.choice(cards) - cards.remove(card) - self.animatedmoveto(card, self.deck) - - def animatedmoveto(self, card, dest): - for i in range(10, 0, -1): - dx, dy = (dest.x-card.x)//i, (dest.y-card.y)//i - card.moveby(dx, dy) - self.master.update_idletasks() - - def closeststack(self, card): - closest = None - cdist = 999999999 - # Since we only compare distances, - # we don't bother to take the square root. - for stack in self.openstacks: - dist = (stack.x - card.x)**2 + (stack.y - card.y)**2 - if dist < cdist: - closest = stack - cdist = dist - return closest - - def deal(self): - self.reset() - self.deck.shuffle() - for i in range(NROWS): - for r in self.rows[i:]: - card = self.deck.deal() - r.add(card) - for r in self.rows: - r.showtop() - - def reset(self): - for stack in self.openstacks: - while 1: - card = stack.deal() - if not card: - break - self.deck.add(card) - card.showback() - - -# Main function, run when invoked as a stand-alone Python program. - -def main(): - root = Tk() - game = Solitaire(root) - root.protocol('WM_DELETE_WINDOW', root.quit) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/sortvisu.py b/Demo/tkinter/guido/sortvisu.py deleted file mode 100644 index 326baec..0000000 --- a/Demo/tkinter/guido/sortvisu.py +++ /dev/null @@ -1,636 +0,0 @@ -#! /usr/bin/env python - -"""Sorting algorithms visualizer using Tkinter. - -This module is comprised of three ``components'': - -- an array visualizer with methods that implement basic sorting -operations (compare, swap) as well as methods for ``annotating'' the -sorting algorithm (e.g. to show the pivot element); - -- a number of sorting algorithms (currently quicksort, insertion sort, -selection sort and bubble sort, as well as a randomization function), -all using the array visualizer for its basic operations and with calls -to its annotation methods; - -- and a ``driver'' class which can be used as a Grail applet or as a -stand-alone application. - -""" - -from tkinter import * -import random - - -XGRID = 10 -YGRID = 10 -WIDTH = 6 - - -class Array: - - class Cancelled(BaseException): - pass - - def __init__(self, master, data=None): - self.master = master - self.frame = Frame(self.master) - self.frame.pack(fill=X) - self.label = Label(self.frame) - self.label.pack() - self.canvas = Canvas(self.frame) - self.canvas.pack() - self.report = Label(self.frame) - self.report.pack() - self.left = self.canvas.create_line(0, 0, 0, 0) - self.right = self.canvas.create_line(0, 0, 0, 0) - self.pivot = self.canvas.create_line(0, 0, 0, 0) - self.items = [] - self.size = self.maxvalue = 0 - if data: - self.setdata(data) - - def setdata(self, data): - olditems = self.items - self.items = [] - for item in olditems: - item.delete() - self.size = len(data) - self.maxvalue = max(data) - self.canvas.config(width=(self.size+1)*XGRID, - height=(self.maxvalue+1)*YGRID) - for i in range(self.size): - self.items.append(ArrayItem(self, i, data[i])) - self.reset("Sort demo, size %d" % self.size) - - speed = "normal" - - def setspeed(self, speed): - self.speed = speed - - def destroy(self): - self.frame.destroy() - - in_mainloop = 0 - stop_mainloop = 0 - - def cancel(self): - self.stop_mainloop = 1 - if self.in_mainloop: - self.master.quit() - - def step(self): - if self.in_mainloop: - self.master.quit() - - def wait(self, msecs): - if self.speed == "fastest": - msecs = 0 - elif self.speed == "fast": - msecs = msecs//10 - elif self.speed == "single-step": - msecs = 1000000000 - if not self.stop_mainloop: - self.master.update() - id = self.master.after(msecs, self.master.quit) - self.in_mainloop = 1 - self.master.mainloop() - self.master.after_cancel(id) - self.in_mainloop = 0 - if self.stop_mainloop: - self.stop_mainloop = 0 - self.message("Cancelled") - raise Array.Cancelled - - def getsize(self): - return self.size - - def show_partition(self, first, last): - for i in range(self.size): - item = self.items[i] - if first <= i < last: - self.canvas.itemconfig(item, fill='red') - else: - self.canvas.itemconfig(item, fill='orange') - self.hide_left_right_pivot() - - def hide_partition(self): - for i in range(self.size): - item = self.items[i] - self.canvas.itemconfig(item, fill='red') - self.hide_left_right_pivot() - - def show_left(self, left): - if not 0 <= left < self.size: - self.hide_left() - return - x1, y1, x2, y2 = self.items[left].position() -## top, bot = HIRO - self.canvas.coords(self.left, (x1 - 2, 0, x1 - 2, 9999)) - self.master.update() - - def show_right(self, right): - if not 0 <= right < self.size: - self.hide_right() - return - x1, y1, x2, y2 = self.items[right].position() - self.canvas.coords(self.right, (x2 + 2, 0, x2 + 2, 9999)) - self.master.update() - - def hide_left_right_pivot(self): - self.hide_left() - self.hide_right() - self.hide_pivot() - - def hide_left(self): - self.canvas.coords(self.left, (0, 0, 0, 0)) - - def hide_right(self): - self.canvas.coords(self.right, (0, 0, 0, 0)) - - def show_pivot(self, pivot): - x1, y1, x2, y2 = self.items[pivot].position() - self.canvas.coords(self.pivot, (0, y1 - 2, 9999, y1 - 2)) - - def hide_pivot(self): - self.canvas.coords(self.pivot, (0, 0, 0, 0)) - - def swap(self, i, j): - if i == j: return - self.countswap() - item = self.items[i] - other = self.items[j] - self.items[i], self.items[j] = other, item - item.swapwith(other) - - def compare(self, i, j): - self.countcompare() - item = self.items[i] - other = self.items[j] - return item.compareto(other) - - def reset(self, msg): - self.ncompares = 0 - self.nswaps = 0 - self.message(msg) - self.updatereport() - self.hide_partition() - - def message(self, msg): - self.label.config(text=msg) - - def countswap(self): - self.nswaps = self.nswaps + 1 - self.updatereport() - - def countcompare(self): - self.ncompares = self.ncompares + 1 - self.updatereport() - - def updatereport(self): - text = "%d cmps, %d swaps" % (self.ncompares, self.nswaps) - self.report.config(text=text) - - -class ArrayItem: - - def __init__(self, array, index, value): - self.array = array - self.index = index - self.value = value - self.canvas = array.canvas - x1, y1, x2, y2 = self.position() - self.item_id = array.canvas.create_rectangle(x1, y1, x2, y2, - fill='red', outline='black', width=1) - self.canvas.tag_bind(self.item_id, '<Button-1>', self.mouse_down) - self.canvas.tag_bind(self.item_id, '<Button1-Motion>', self.mouse_move) - self.canvas.tag_bind(self.item_id, '<ButtonRelease-1>', self.mouse_up) - - def delete(self): - item_id = self.item_id - self.array = None - self.item_id = None - self.canvas.delete(item_id) - - def mouse_down(self, event): - self.lastx = event.x - self.lasty = event.y - self.origx = event.x - self.origy = event.y - self.canvas.tag_raise(self.item_id) - - def mouse_move(self, event): - self.canvas.move(self.item_id, - event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - def mouse_up(self, event): - i = self.nearestindex(event.x) - if i >= self.array.getsize(): - i = self.array.getsize() - 1 - if i < 0: - i = 0 - other = self.array.items[i] - here = self.index - self.array.items[here], self.array.items[i] = other, self - self.index = i - x1, y1, x2, y2 = self.position() - self.canvas.coords(self.item_id, (x1, y1, x2, y2)) - other.setindex(here) - - def setindex(self, index): - nsteps = steps(self.index, index) - if not nsteps: return - if self.array.speed == "fastest": - nsteps = 0 - oldpts = self.position() - self.index = index - newpts = self.position() - trajectory = interpolate(oldpts, newpts, nsteps) - self.canvas.tag_raise(self.item_id) - for pts in trajectory: - self.canvas.coords(self.item_id, pts) - self.array.wait(50) - - def swapwith(self, other): - nsteps = steps(self.index, other.index) - if not nsteps: return - if self.array.speed == "fastest": - nsteps = 0 - myoldpts = self.position() - otheroldpts = other.position() - self.index, other.index = other.index, self.index - mynewpts = self.position() - othernewpts = other.position() - myfill = self.canvas.itemcget(self.item_id, 'fill') - otherfill = self.canvas.itemcget(other.item_id, 'fill') - self.canvas.itemconfig(self.item_id, fill='green') - self.canvas.itemconfig(other.item_id, fill='yellow') - self.array.master.update() - if self.array.speed == "single-step": - self.canvas.coords(self.item_id, mynewpts) - self.canvas.coords(other.item_id, othernewpts) - self.array.master.update() - self.canvas.itemconfig(self.item_id, fill=myfill) - self.canvas.itemconfig(other.item_id, fill=otherfill) - self.array.wait(0) - return - mytrajectory = interpolate(myoldpts, mynewpts, nsteps) - othertrajectory = interpolate(otheroldpts, othernewpts, nsteps) - if self.value > other.value: - self.canvas.tag_raise(self.item_id) - self.canvas.tag_raise(other.item_id) - else: - self.canvas.tag_raise(other.item_id) - self.canvas.tag_raise(self.item_id) - try: - for i in range(len(mytrajectory)): - mypts = mytrajectory[i] - otherpts = othertrajectory[i] - self.canvas.coords(self.item_id, mypts) - self.canvas.coords(other.item_id, otherpts) - self.array.wait(50) - finally: - mypts = mytrajectory[-1] - otherpts = othertrajectory[-1] - self.canvas.coords(self.item_id, mypts) - self.canvas.coords(other.item_id, otherpts) - self.canvas.itemconfig(self.item_id, fill=myfill) - self.canvas.itemconfig(other.item_id, fill=otherfill) - - def compareto(self, other): - myfill = self.canvas.itemcget(self.item_id, 'fill') - otherfill = self.canvas.itemcget(other.item_id, 'fill') - if self.value < other.value: - myflash = 'white' - otherflash = 'black' - outcome = -1 - elif self.value > other.value: - myflash = 'black' - otherflash = 'white' - outcome = 1 - else: - myflash = otherflash = 'grey' - outcome = 0 - try: - self.canvas.itemconfig(self.item_id, fill=myflash) - self.canvas.itemconfig(other.item_id, fill=otherflash) - self.array.wait(500) - finally: - self.canvas.itemconfig(self.item_id, fill=myfill) - self.canvas.itemconfig(other.item_id, fill=otherfill) - return outcome - - def position(self): - x1 = (self.index+1)*XGRID - WIDTH//2 - x2 = x1+WIDTH - y2 = (self.array.maxvalue+1)*YGRID - y1 = y2 - (self.value)*YGRID - return x1, y1, x2, y2 - - def nearestindex(self, x): - return int(round(float(x)/XGRID)) - 1 - - -# Subroutines that don't need an object - -def steps(here, there): - nsteps = abs(here - there) - if nsteps <= 3: - nsteps = nsteps * 3 - elif nsteps <= 5: - nsteps = nsteps * 2 - elif nsteps > 10: - nsteps = 10 - return nsteps - -def interpolate(oldpts, newpts, n): - if len(oldpts) != len(newpts): - raise ValueError("can't interpolate arrays of different length") - pts = [0]*len(oldpts) - res = [tuple(oldpts)] - for i in range(1, n): - for k in range(len(pts)): - pts[k] = oldpts[k] + (newpts[k] - oldpts[k])*i//n - res.append(tuple(pts)) - res.append(tuple(newpts)) - return res - - -# Various (un)sorting algorithms - -def uniform(array): - size = array.getsize() - array.setdata([(size+1)//2] * size) - array.reset("Uniform data, size %d" % size) - -def distinct(array): - size = array.getsize() - array.setdata(range(1, size+1)) - array.reset("Distinct data, size %d" % size) - -def randomize(array): - array.reset("Randomizing") - n = array.getsize() - for i in range(n): - j = random.randint(0, n-1) - array.swap(i, j) - array.message("Randomized") - -def insertionsort(array): - size = array.getsize() - array.reset("Insertion sort") - for i in range(1, size): - j = i-1 - while j >= 0: - if array.compare(j, j+1) <= 0: - break - array.swap(j, j+1) - j = j-1 - array.message("Sorted") - -def selectionsort(array): - size = array.getsize() - array.reset("Selection sort") - try: - for i in range(size): - array.show_partition(i, size) - for j in range(i+1, size): - if array.compare(i, j) > 0: - array.swap(i, j) - array.message("Sorted") - finally: - array.hide_partition() - -def bubblesort(array): - size = array.getsize() - array.reset("Bubble sort") - for i in range(size): - for j in range(1, size): - if array.compare(j-1, j) > 0: - array.swap(j-1, j) - array.message("Sorted") - -def quicksort(array): - size = array.getsize() - array.reset("Quicksort") - try: - stack = [(0, size)] - while stack: - first, last = stack[-1] - del stack[-1] - array.show_partition(first, last) - if last-first < 5: - array.message("Insertion sort") - for i in range(first+1, last): - j = i-1 - while j >= first: - if array.compare(j, j+1) <= 0: - break - array.swap(j, j+1) - j = j-1 - continue - array.message("Choosing pivot") - j, i, k = first, (first+last) // 2, last-1 - if array.compare(k, i) < 0: - array.swap(k, i) - if array.compare(k, j) < 0: - array.swap(k, j) - if array.compare(j, i) < 0: - array.swap(j, i) - pivot = j - array.show_pivot(pivot) - array.message("Pivot at left of partition") - array.wait(1000) - left = first - right = last - while 1: - array.message("Sweep right pointer") - right = right-1 - array.show_right(right) - while right > first and array.compare(right, pivot) >= 0: - right = right-1 - array.show_right(right) - array.message("Sweep left pointer") - left = left+1 - array.show_left(left) - while left < last and array.compare(left, pivot) <= 0: - left = left+1 - array.show_left(left) - if left > right: - array.message("End of partition") - break - array.message("Swap items") - array.swap(left, right) - array.message("Swap pivot back") - array.swap(pivot, right) - n1 = right-first - n2 = last-left - if n1 > 1: stack.append((first, right)) - if n2 > 1: stack.append((left, last)) - array.message("Sorted") - finally: - array.hide_partition() - -def demosort(array): - while 1: - for alg in [quicksort, insertionsort, selectionsort, bubblesort]: - randomize(array) - alg(array) - - -# Sort demo class -- usable as a Grail applet - -class SortDemo: - - def __init__(self, master, size=15): - self.master = master - self.size = size - self.busy = 0 - self.array = Array(self.master) - - self.botframe = Frame(master) - self.botframe.pack(side=BOTTOM) - self.botleftframe = Frame(self.botframe) - self.botleftframe.pack(side=LEFT, fill=Y) - self.botrightframe = Frame(self.botframe) - self.botrightframe.pack(side=RIGHT, fill=Y) - - self.b_qsort = Button(self.botleftframe, - text="Quicksort", command=self.c_qsort) - self.b_qsort.pack(fill=X) - self.b_isort = Button(self.botleftframe, - text="Insertion sort", command=self.c_isort) - self.b_isort.pack(fill=X) - self.b_ssort = Button(self.botleftframe, - text="Selection sort", command=self.c_ssort) - self.b_ssort.pack(fill=X) - self.b_bsort = Button(self.botleftframe, - text="Bubble sort", command=self.c_bsort) - self.b_bsort.pack(fill=X) - - # Terrible hack to overcome limitation of OptionMenu... - class MyIntVar(IntVar): - def __init__(self, master, demo): - self.demo = demo - IntVar.__init__(self, master) - def set(self, value): - IntVar.set(self, value) - if str(value) != '0': - self.demo.resize(value) - - self.v_size = MyIntVar(self.master, self) - self.v_size.set(size) - sizes = [1, 2, 3, 4] + list(range(5, 55, 5)) - if self.size not in sizes: - sizes.append(self.size) - sizes.sort() - self.m_size = OptionMenu(self.botleftframe, self.v_size, *sizes) - self.m_size.pack(fill=X) - - self.v_speed = StringVar(self.master) - self.v_speed.set("normal") - self.m_speed = OptionMenu(self.botleftframe, self.v_speed, - "single-step", "normal", "fast", "fastest") - self.m_speed.pack(fill=X) - - self.b_step = Button(self.botleftframe, - text="Step", command=self.c_step) - self.b_step.pack(fill=X) - - self.b_randomize = Button(self.botrightframe, - text="Randomize", command=self.c_randomize) - self.b_randomize.pack(fill=X) - self.b_uniform = Button(self.botrightframe, - text="Uniform", command=self.c_uniform) - self.b_uniform.pack(fill=X) - self.b_distinct = Button(self.botrightframe, - text="Distinct", command=self.c_distinct) - self.b_distinct.pack(fill=X) - self.b_demo = Button(self.botrightframe, - text="Demo", command=self.c_demo) - self.b_demo.pack(fill=X) - self.b_cancel = Button(self.botrightframe, - text="Cancel", command=self.c_cancel) - self.b_cancel.pack(fill=X) - self.b_cancel.config(state=DISABLED) - self.b_quit = Button(self.botrightframe, - text="Quit", command=self.c_quit) - self.b_quit.pack(fill=X) - - def resize(self, newsize): - if self.busy: - self.master.bell() - return - self.size = newsize - self.array.setdata(range(1, self.size+1)) - - def c_qsort(self): - self.run(quicksort) - - def c_isort(self): - self.run(insertionsort) - - def c_ssort(self): - self.run(selectionsort) - - def c_bsort(self): - self.run(bubblesort) - - def c_demo(self): - self.run(demosort) - - def c_randomize(self): - self.run(randomize) - - def c_uniform(self): - self.run(uniform) - - def c_distinct(self): - self.run(distinct) - - def run(self, func): - if self.busy: - self.master.bell() - return - self.busy = 1 - self.array.setspeed(self.v_speed.get()) - self.b_cancel.config(state=NORMAL) - try: - func(self.array) - except Array.Cancelled: - pass - self.b_cancel.config(state=DISABLED) - self.busy = 0 - - def c_cancel(self): - if not self.busy: - self.master.bell() - return - self.array.cancel() - - def c_step(self): - if not self.busy: - self.master.bell() - return - self.v_speed.set("single-step") - self.array.setspeed("single-step") - self.array.step() - - def c_quit(self): - if self.busy: - self.array.cancel() - self.master.after_idle(self.master.quit) - - -# Main program -- for stand-alone operation outside Grail - -def main(): - root = Tk() - demo = SortDemo(root) - root.protocol('WM_DELETE_WINDOW', demo.c_quit) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/ss1.py b/Demo/tkinter/guido/ss1.py deleted file mode 100644 index 8b07489..0000000 --- a/Demo/tkinter/guido/ss1.py +++ /dev/null @@ -1,842 +0,0 @@ -"""SS1 -- a spreadsheet.""" - -import os -import re -import sys -import html -from xml.parsers import expat - -LEFT, CENTER, RIGHT = "LEFT", "CENTER", "RIGHT" - -def ljust(x, n): - return x.ljust(n) -def center(x, n): - return x.center(n) -def rjust(x, n): - return x.rjust(n) -align2action = {LEFT: ljust, CENTER: center, RIGHT: rjust} - -align2xml = {LEFT: "left", CENTER: "center", RIGHT: "right"} -xml2align = {"left": LEFT, "center": CENTER, "right": RIGHT} - -align2anchor = {LEFT: "w", CENTER: "center", RIGHT: "e"} - -def sum(seq): - total = 0 - for x in seq: - if x is not None: - total += x - return total - -class Sheet: - - def __init__(self): - self.cells = {} # {(x, y): cell, ...} - self.ns = dict( - cell = self.cellvalue, - cells = self.multicellvalue, - sum = sum, - ) - - def cellvalue(self, x, y): - cell = self.getcell(x, y) - if hasattr(cell, 'recalc'): - return cell.recalc(self.ns) - else: - return cell - - def multicellvalue(self, x1, y1, x2, y2): - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - seq = [] - for y in range(y1, y2+1): - for x in range(x1, x2+1): - seq.append(self.cellvalue(x, y)) - return seq - - def getcell(self, x, y): - return self.cells.get((x, y)) - - def setcell(self, x, y, cell): - assert x > 0 and y > 0 - assert isinstance(cell, BaseCell) - self.cells[x, y] = cell - - def clearcell(self, x, y): - try: - del self.cells[x, y] - except KeyError: - pass - - def clearcells(self, x1, y1, x2, y2): - for xy in self.selectcells(x1, y1, x2, y2): - del self.cells[xy] - - def clearrows(self, y1, y2): - self.clearcells(0, y1, sys.maxint, y2) - - def clearcolumns(self, x1, x2): - self.clearcells(x1, 0, x2, sys.maxint) - - def selectcells(self, x1, y1, x2, y2): - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - return [(x, y) for x, y in self.cells - if x1 <= x <= x2 and y1 <= y <= y2] - - def movecells(self, x1, y1, x2, y2, dx, dy): - if dx == 0 and dy == 0: - return - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - assert x1+dx > 0 and y1+dy > 0 - new = {} - for x, y in self.cells: - cell = self.cells[x, y] - if hasattr(cell, 'renumber'): - cell = cell.renumber(x1, y1, x2, y2, dx, dy) - if x1 <= x <= x2 and y1 <= y <= y2: - x += dx - y += dy - new[x, y] = cell - self.cells = new - - def insertrows(self, y, n): - assert n > 0 - self.movecells(0, y, sys.maxint, sys.maxint, 0, n) - - def deleterows(self, y1, y2): - if y1 > y2: - y1, y2 = y2, y1 - self.clearrows(y1, y2) - self.movecells(0, y2+1, sys.maxint, sys.maxint, 0, y1-y2-1) - - def insertcolumns(self, x, n): - assert n > 0 - self.movecells(x, 0, sys.maxint, sys.maxint, n, 0) - - def deletecolumns(self, x1, x2): - if x1 > x2: - x1, x2 = x2, x1 - self.clearcells(x1, x2) - self.movecells(x2+1, 0, sys.maxint, sys.maxint, x1-x2-1, 0) - - def getsize(self): - maxx = maxy = 0 - for x, y in self.cells: - maxx = max(maxx, x) - maxy = max(maxy, y) - return maxx, maxy - - def reset(self): - for cell in self.cells.values(): - if hasattr(cell, 'reset'): - cell.reset() - - def recalc(self): - self.reset() - for cell in self.cells.values(): - if hasattr(cell, 'recalc'): - cell.recalc(self.ns) - - def display(self): - maxx, maxy = self.getsize() - width, height = maxx+1, maxy+1 - colwidth = [1] * width - full = {} - # Add column heading labels in row 0 - for x in range(1, width): - full[x, 0] = text, alignment = colnum2name(x), RIGHT - colwidth[x] = max(colwidth[x], len(text)) - # Add row labels in column 0 - for y in range(1, height): - full[0, y] = text, alignment = str(y), RIGHT - colwidth[0] = max(colwidth[0], len(text)) - # Add sheet cells in columns with x>0 and y>0 - for (x, y), cell in self.cells.items(): - if x <= 0 or y <= 0: - continue - if hasattr(cell, 'recalc'): - cell.recalc(self.ns) - if hasattr(cell, 'format'): - text, alignment = cell.format() - assert isinstance(text, str) - assert alignment in (LEFT, CENTER, RIGHT) - else: - text = str(cell) - if isinstance(cell, str): - alignment = LEFT - else: - alignment = RIGHT - full[x, y] = (text, alignment) - colwidth[x] = max(colwidth[x], len(text)) - # Calculate the horizontal separator line (dashes and dots) - sep = "" - for x in range(width): - if sep: - sep += "+" - sep += "-"*colwidth[x] - # Now print The full grid - for y in range(height): - line = "" - for x in range(width): - text, alignment = full.get((x, y)) or ("", LEFT) - text = align2action[alignment](text, colwidth[x]) - if line: - line += '|' - line += text - print(line) - if y == 0: - print(sep) - - def xml(self): - out = ['<spreadsheet>'] - for (x, y), cell in self.cells.items(): - if hasattr(cell, 'xml'): - cellxml = cell.xml() - else: - cellxml = '<value>%s</value>' % html.escape(cell) - out.append('<cell row="%s" col="%s">\n %s\n</cell>' % - (y, x, cellxml)) - out.append('</spreadsheet>') - return '\n'.join(out) - - def save(self, filename): - text = self.xml() - f = open(filename, "w") - f.write(text) - if text and not text.endswith('\n'): - f.write('\n') - f.close() - - def load(self, filename): - f = open(filename, 'rb') - SheetParser(self).parsefile(f) - f.close() - -class SheetParser: - - def __init__(self, sheet): - self.sheet = sheet - - def parsefile(self, f): - parser = expat.ParserCreate() - parser.StartElementHandler = self.startelement - parser.EndElementHandler = self.endelement - parser.CharacterDataHandler = self.data - parser.ParseFile(f) - - def startelement(self, tag, attrs): - method = getattr(self, 'start_'+tag, None) - if method: - for key, value in attrs.items(): - attrs[key] = str(value) # XXX Convert Unicode to 8-bit - method(attrs) - self.texts = [] - - def data(self, text): - text = str(text) # XXX Convert Unicode to 8-bit - self.texts.append(text) - - def endelement(self, tag): - method = getattr(self, 'end_'+tag, None) - if method: - method("".join(self.texts)) - - def start_cell(self, attrs): - self.y = int(attrs.get("row")) - self.x = int(attrs.get("col")) - - def start_value(self, attrs): - self.fmt = attrs.get('format') - self.alignment = xml2align.get(attrs.get('align')) - - start_formula = start_value - - def end_int(self, text): - try: - self.value = int(text) - except: - self.value = None - - def end_long(self, text): - try: - self.value = int(text) - except: - self.value = None - - def end_double(self, text): - try: - self.value = float(text) - except: - self.value = None - - def end_complex(self, text): - try: - self.value = complex(text) - except: - self.value = None - - def end_string(self, text): - try: - self.value = text - except: - self.value = None - - def end_value(self, text): - if isinstance(self.value, BaseCell): - self.cell = self.value - elif isinstance(self.value, str): - self.cell = StringCell(self.value, - self.fmt or "%s", - self.alignment or LEFT) - else: - self.cell = NumericCell(self.value, - self.fmt or "%s", - self.alignment or RIGHT) - - def end_formula(self, text): - self.cell = FormulaCell(text, - self.fmt or "%s", - self.alignment or RIGHT) - - def end_cell(self, text): - self.sheet.setcell(self.x, self.y, self.cell) - -class BaseCell: - __init__ = None # Must provide - """Abstract base class for sheet cells. - - Subclasses may but needn't provide the following APIs: - - cell.reset() -- prepare for recalculation - cell.recalc(ns) -> value -- recalculate formula - cell.format() -> (value, alignment) -- return formatted value - cell.xml() -> string -- return XML - """ - -class NumericCell(BaseCell): - - def __init__(self, value, fmt="%s", alignment=RIGHT): - assert isinstance(value, (int, int, float, complex)) - assert alignment in (LEFT, CENTER, RIGHT) - self.value = value - self.fmt = fmt - self.alignment = alignment - - def recalc(self, ns): - return self.value - - def format(self): - try: - text = self.fmt % self.value - except: - text = str(self.value) - return text, self.alignment - - def xml(self): - method = getattr(self, '_xml_' + type(self.value).__name__) - return '<value align="%s" format="%s">%s</value>' % ( - align2xml[self.alignment], - self.fmt, - method()) - - def _xml_int(self): - if -2**31 <= self.value < 2**31: - return '<int>%s</int>' % self.value - else: - return self._xml_long() - - def _xml_long(self): - return '<long>%s</long>' % self.value - - def _xml_float(self): - return '<double>%s</double>' % repr(self.value) - - def _xml_complex(self): - return '<complex>%s</double>' % repr(self.value) - -class StringCell(BaseCell): - - def __init__(self, text, fmt="%s", alignment=LEFT): - assert isinstance(text, (str, str)) - assert alignment in (LEFT, CENTER, RIGHT) - self.text = text - self.fmt = fmt - self.alignment = alignment - - def recalc(self, ns): - return self.text - - def format(self): - return self.text, self.alignment - - def xml(self): - s = '<value align="%s" format="%s"><string>%s</string></value>' - return s % ( - align2xml[self.alignment], - self.fmt, - html.escape(self.text)) - -class FormulaCell(BaseCell): - - def __init__(self, formula, fmt="%s", alignment=RIGHT): - assert alignment in (LEFT, CENTER, RIGHT) - self.formula = formula - self.translated = translate(self.formula) - self.fmt = fmt - self.alignment = alignment - self.reset() - - def reset(self): - self.value = None - - def recalc(self, ns): - if self.value is None: - try: - # A hack to evaluate expressions using true division - self.value = eval(self.translated, ns) - except: - exc = sys.exc_info()[0] - if hasattr(exc, "__name__"): - self.value = exc.__name__ - else: - self.value = str(exc) - return self.value - - def format(self): - try: - text = self.fmt % self.value - except: - text = str(self.value) - return text, self.alignment - - def xml(self): - return '<formula align="%s" format="%s">%s</formula>' % ( - align2xml[self.alignment], - self.fmt, - self.formula) - - def renumber(self, x1, y1, x2, y2, dx, dy): - out = [] - for part in re.split('(\w+)', self.formula): - m = re.match('^([A-Z]+)([1-9][0-9]*)$', part) - if m is not None: - sx, sy = m.groups() - x = colname2num(sx) - y = int(sy) - if x1 <= x <= x2 and y1 <= y <= y2: - part = cellname(x+dx, y+dy) - out.append(part) - return FormulaCell("".join(out), self.fmt, self.alignment) - -def translate(formula): - """Translate a formula containing fancy cell names to valid Python code. - - Examples: - B4 -> cell(2, 4) - B4:Z100 -> cells(2, 4, 26, 100) - """ - out = [] - for part in re.split(r"(\w+(?::\w+)?)", formula): - m = re.match(r"^([A-Z]+)([1-9][0-9]*)(?::([A-Z]+)([1-9][0-9]*))?$", part) - if m is None: - out.append(part) - else: - x1, y1, x2, y2 = m.groups() - x1 = colname2num(x1) - if x2 is None: - s = "cell(%s, %s)" % (x1, y1) - else: - x2 = colname2num(x2) - s = "cells(%s, %s, %s, %s)" % (x1, y1, x2, y2) - out.append(s) - return "".join(out) - -def cellname(x, y): - "Translate a cell coordinate to a fancy cell name (e.g. (1, 1)->'A1')." - assert x > 0 # Column 0 has an empty name, so can't use that - return colnum2name(x) + str(y) - -def colname2num(s): - "Translate a column name to number (e.g. 'A'->1, 'Z'->26, 'AA'->27)." - s = s.upper() - n = 0 - for c in s: - assert 'A' <= c <= 'Z' - n = n*26 + ord(c) - ord('A') + 1 - return n - -def colnum2name(n): - "Translate a column number to name (e.g. 1->'A', etc.)." - assert n > 0 - s = "" - while n: - n, m = divmod(n-1, 26) - s = chr(m+ord('A')) + s - return s - -import tkinter as Tk - -class SheetGUI: - - """Beginnings of a GUI for a spreadsheet. - - TO DO: - - clear multiple cells - - Insert, clear, remove rows or columns - - Show new contents while typing - - Scroll bars - - Grow grid when window is grown - - Proper menus - - Undo, redo - - Cut, copy and paste - - Formatting and alignment - """ - - def __init__(self, filename="sheet1.xml", rows=10, columns=5): - """Constructor. - - Load the sheet from the filename argument. - Set up the Tk widget tree. - """ - # Create and load the sheet - self.filename = filename - self.sheet = Sheet() - if os.path.isfile(filename): - self.sheet.load(filename) - # Calculate the needed grid size - maxx, maxy = self.sheet.getsize() - rows = max(rows, maxy) - columns = max(columns, maxx) - # Create the widgets - self.root = Tk.Tk() - self.root.wm_title("Spreadsheet: %s" % self.filename) - self.beacon = Tk.Label(self.root, text="A1", - font=('helvetica', 16, 'bold')) - self.entry = Tk.Entry(self.root) - self.savebutton = Tk.Button(self.root, text="Save", - command=self.save) - self.cellgrid = Tk.Frame(self.root) - # Configure the widget lay-out - self.cellgrid.pack(side="bottom", expand=1, fill="both") - self.beacon.pack(side="left") - self.savebutton.pack(side="right") - self.entry.pack(side="left", expand=1, fill="x") - # Bind some events - self.entry.bind("<Return>", self.return_event) - self.entry.bind("<Shift-Return>", self.shift_return_event) - self.entry.bind("<Tab>", self.tab_event) - self.entry.bind("<Shift-Tab>", self.shift_tab_event) - self.entry.bind("<Delete>", self.delete_event) - self.entry.bind("<Escape>", self.escape_event) - # Now create the cell grid - self.makegrid(rows, columns) - # Select the top-left cell - self.currentxy = None - self.cornerxy = None - self.setcurrent(1, 1) - # Copy the sheet cells to the GUI cells - self.sync() - - def delete_event(self, event): - if self.cornerxy != self.currentxy and self.cornerxy is not None: - self.sheet.clearcells(*(self.currentxy + self.cornerxy)) - else: - self.sheet.clearcell(*self.currentxy) - self.sync() - self.entry.delete(0, 'end') - return "break" - - def escape_event(self, event): - x, y = self.currentxy - self.load_entry(x, y) - - def load_entry(self, x, y): - cell = self.sheet.getcell(x, y) - if cell is None: - text = "" - elif isinstance(cell, FormulaCell): - text = '=' + cell.formula - else: - text, alignment = cell.format() - self.entry.delete(0, 'end') - self.entry.insert(0, text) - self.entry.selection_range(0, 'end') - - def makegrid(self, rows, columns): - """Helper to create the grid of GUI cells. - - The edge (x==0 or y==0) is filled with labels; the rest is real cells. - """ - self.rows = rows - self.columns = columns - self.gridcells = {} - # Create the top left corner cell (which selects all) - cell = Tk.Label(self.cellgrid, relief='raised') - cell.grid_configure(column=0, row=0, sticky='NSWE') - cell.bind("<ButtonPress-1>", self.selectall) - # Create the top row of labels, and confiure the grid columns - for x in range(1, columns+1): - self.cellgrid.grid_columnconfigure(x, minsize=64) - cell = Tk.Label(self.cellgrid, text=colnum2name(x), relief='raised') - cell.grid_configure(column=x, row=0, sticky='WE') - self.gridcells[x, 0] = cell - cell.__x = x - cell.__y = 0 - cell.bind("<ButtonPress-1>", self.selectcolumn) - cell.bind("<B1-Motion>", self.extendcolumn) - cell.bind("<ButtonRelease-1>", self.extendcolumn) - cell.bind("<Shift-Button-1>", self.extendcolumn) - # Create the leftmost column of labels - for y in range(1, rows+1): - cell = Tk.Label(self.cellgrid, text=str(y), relief='raised') - cell.grid_configure(column=0, row=y, sticky='WE') - self.gridcells[0, y] = cell - cell.__x = 0 - cell.__y = y - cell.bind("<ButtonPress-1>", self.selectrow) - cell.bind("<B1-Motion>", self.extendrow) - cell.bind("<ButtonRelease-1>", self.extendrow) - cell.bind("<Shift-Button-1>", self.extendrow) - # Create the real cells - for x in range(1, columns+1): - for y in range(1, rows+1): - cell = Tk.Label(self.cellgrid, relief='sunken', - bg='white', fg='black') - cell.grid_configure(column=x, row=y, sticky='NSWE') - self.gridcells[x, y] = cell - cell.__x = x - cell.__y = y - # Bind mouse events - cell.bind("<ButtonPress-1>", self.press) - cell.bind("<B1-Motion>", self.motion) - cell.bind("<ButtonRelease-1>", self.release) - cell.bind("<Shift-Button-1>", self.release) - - def selectall(self, event): - self.setcurrent(1, 1) - self.setcorner(sys.maxint, sys.maxint) - - def selectcolumn(self, event): - x, y = self.whichxy(event) - self.setcurrent(x, 1) - self.setcorner(x, sys.maxint) - - def extendcolumn(self, event): - x, y = self.whichxy(event) - if x > 0: - self.setcurrent(self.currentxy[0], 1) - self.setcorner(x, sys.maxint) - - def selectrow(self, event): - x, y = self.whichxy(event) - self.setcurrent(1, y) - self.setcorner(sys.maxint, y) - - def extendrow(self, event): - x, y = self.whichxy(event) - if y > 0: - self.setcurrent(1, self.currentxy[1]) - self.setcorner(sys.maxint, y) - - def press(self, event): - x, y = self.whichxy(event) - if x > 0 and y > 0: - self.setcurrent(x, y) - - def motion(self, event): - x, y = self.whichxy(event) - if x > 0 and y > 0: - self.setcorner(x, y) - - release = motion - - def whichxy(self, event): - w = self.cellgrid.winfo_containing(event.x_root, event.y_root) - if w is not None and isinstance(w, Tk.Label): - try: - return w.__x, w.__y - except AttributeError: - pass - return 0, 0 - - def save(self): - self.sheet.save(self.filename) - - def setcurrent(self, x, y): - "Make (x, y) the current cell." - if self.currentxy is not None: - self.change_cell() - self.clearfocus() - self.beacon['text'] = cellname(x, y) - self.load_entry(x, y) - self.entry.focus_set() - self.currentxy = x, y - self.cornerxy = None - gridcell = self.gridcells.get(self.currentxy) - if gridcell is not None: - gridcell['bg'] = 'yellow' - - def setcorner(self, x, y): - if self.currentxy is None or self.currentxy == (x, y): - self.setcurrent(x, y) - return - self.clearfocus() - self.cornerxy = x, y - x1, y1 = self.currentxy - x2, y2 = self.cornerxy or self.currentxy - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - for (x, y), cell in self.gridcells.items(): - if x1 <= x <= x2 and y1 <= y <= y2: - cell['bg'] = 'lightBlue' - gridcell = self.gridcells.get(self.currentxy) - if gridcell is not None: - gridcell['bg'] = 'yellow' - self.setbeacon(x1, y1, x2, y2) - - def setbeacon(self, x1, y1, x2, y2): - if x1 == y1 == 1 and x2 == y2 == sys.maxint: - name = ":" - elif (x1, x2) == (1, sys.maxint): - if y1 == y2: - name = "%d" % y1 - else: - name = "%d:%d" % (y1, y2) - elif (y1, y2) == (1, sys.maxint): - if x1 == x2: - name = "%s" % colnum2name(x1) - else: - name = "%s:%s" % (colnum2name(x1), colnum2name(x2)) - else: - name1 = cellname(*self.currentxy) - name2 = cellname(*self.cornerxy) - name = "%s:%s" % (name1, name2) - self.beacon['text'] = name - - - def clearfocus(self): - if self.currentxy is not None: - x1, y1 = self.currentxy - x2, y2 = self.cornerxy or self.currentxy - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - for (x, y), cell in self.gridcells.items(): - if x1 <= x <= x2 and y1 <= y <= y2: - cell['bg'] = 'white' - - def return_event(self, event): - "Callback for the Return key." - self.change_cell() - x, y = self.currentxy - self.setcurrent(x, y+1) - return "break" - - def shift_return_event(self, event): - "Callback for the Return key with Shift modifier." - self.change_cell() - x, y = self.currentxy - self.setcurrent(x, max(1, y-1)) - return "break" - - def tab_event(self, event): - "Callback for the Tab key." - self.change_cell() - x, y = self.currentxy - self.setcurrent(x+1, y) - return "break" - - def shift_tab_event(self, event): - "Callback for the Tab key with Shift modifier." - self.change_cell() - x, y = self.currentxy - self.setcurrent(max(1, x-1), y) - return "break" - - def change_cell(self): - "Set the current cell from the entry widget." - x, y = self.currentxy - text = self.entry.get() - cell = None - if text.startswith('='): - cell = FormulaCell(text[1:]) - else: - for cls in int, int, float, complex: - try: - value = cls(text) - except: - continue - else: - cell = NumericCell(value) - break - if cell is None and text: - cell = StringCell(text) - if cell is None: - self.sheet.clearcell(x, y) - else: - self.sheet.setcell(x, y, cell) - self.sync() - - def sync(self): - "Fill the GUI cells from the sheet cells." - self.sheet.recalc() - for (x, y), gridcell in self.gridcells.items(): - if x == 0 or y == 0: - continue - cell = self.sheet.getcell(x, y) - if cell is None: - gridcell['text'] = "" - else: - if hasattr(cell, 'format'): - text, alignment = cell.format() - else: - text, alignment = str(cell), LEFT - gridcell['text'] = text - gridcell['anchor'] = align2anchor[alignment] - - -def test_basic(): - "Basic non-gui self-test." - import os - a = Sheet() - for x in range(1, 11): - for y in range(1, 11): - if x == 1: - cell = NumericCell(y) - elif y == 1: - cell = NumericCell(x) - else: - c1 = cellname(x, 1) - c2 = cellname(1, y) - formula = "%s*%s" % (c1, c2) - cell = FormulaCell(formula) - a.setcell(x, y, cell) -## if os.path.isfile("sheet1.xml"): -## print "Loading from sheet1.xml" -## a.load("sheet1.xml") - a.display() - a.save("sheet1.xml") - -def test_gui(): - "GUI test." - if sys.argv[1:]: - filename = sys.argv[1] - else: - filename = "sheet1.xml" - g = SheetGUI(filename) - g.root.mainloop() - -if __name__ == '__main__': - #test_basic() - test_gui() diff --git a/Demo/tkinter/guido/svkill.py b/Demo/tkinter/guido/svkill.py deleted file mode 100755 index e63a32b..0000000 --- a/Demo/tkinter/guido/svkill.py +++ /dev/null @@ -1,124 +0,0 @@ -#! /usr/bin/env python - -# Tkinter interface to SYSV `ps' and `kill' commands. - -from tkinter import * - -if TkVersion < 4.0: - raise ImportError("This version of svkill requires Tk 4.0 or later") - -import subprocess -import os - -user = os.environ['LOGNAME'] - -class BarButton(Menubutton): - def __init__(self, master=None, **cnf): - Menubutton.__init__(self, master, **cnf) - self.pack(side=LEFT) - self.menu = Menu(self, name='menu') - self['menu'] = self.menu - -class Kill(Frame): - # List of (name, option, pid_column) - view_list = [ - ('Default', ''), - ('Every (-e)', '-e'), - ('Non process group leaders (-d)', '-d'), - ('Non leaders with tty (-a)', '-a'), - ('For this user (-u %s)' % user, '-u %s' % user), - ] - format_list = [ - ('Default', '', 0), - ('Long (-l)', '-l', 3), - ('Full (-f)', '-f', 1), - ('Full Long (-f -l)', '-l -f', 3), - ('Session and group ID (-j)', '-j', 0), - ('Scheduler properties (-c)', '-c', 0), - ] - def kill(self, selected): - c = self.format_list[self.format.get()][2] - pid = selected.split()[c] - os.system('kill -9 ' + pid) - self.do_update() - def do_update(self): - format = self.format_list[self.format.get()][1] - view = self.view_list[self.view.get()][1] - s = subprocess.getoutput('ps %s %s' % (view, format)) - list = s.split('\n') - self.header.set(list[0] + ' ') - del list[0] - self.frame.list.delete(0, AtEnd()) - for line in list: - self.frame.list.insert(0, line) - def do_motion(self, e): - e.widget.select_clear('0', 'end') - e.widget.select_set(e.widget.nearest(e.y)) - def do_leave(self, e): - e.widget.select_clear('0', 'end') - def do_1(self, e): - self.kill(e.widget.get(e.widget.nearest(e.y))) - def __init__(self, master=None, **cnf): - Frame.__init__(self, master, **cnf) - self.pack(expand=1, fill=BOTH) - self.bar = Frame(self, name='bar', relief=RAISED, - borderwidth=2) - self.bar.pack(fill=X) - self.bar.file = BarButton(self.bar, text='File') - self.bar.file.menu.add_command( - label='Quit', command=self.quit) - self.bar.view = BarButton(self.bar, text='View') - self.bar.format = BarButton(self.bar, text='Format') - self.view = IntVar(self) - self.view.set(0) - self.format = IntVar(self) - self.format.set(0) - for num in range(len(self.view_list)): - label, option = self.view_list[num] - self.bar.view.menu.add_radiobutton( - label=label, - command=self.do_update, - variable=self.view, - value=num) - for num in range(len(self.format_list)): - label, option, col = self.format_list[num] - self.bar.format.menu.add_radiobutton( - label=label, - command=self.do_update, - variable=self.format, - value=num) - self.bar.tk_menuBar(self.bar.file, - self.bar.view, - self.bar.format) - self.frame = Frame(self, relief=RAISED, borderwidth=2) - self.frame.pack(expand=1, fill=BOTH) - self.header = StringVar(self) - self.frame.label = Label( - self.frame, relief=FLAT, anchor=NW, borderwidth=0, - textvariable=self.header) - self.frame.label.pack(fill=Y, anchor=W) - self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL) - self.frame.list = Listbox( - self.frame, - relief=SUNKEN, - width=40, height=10, - selectbackground='#eed5b7', - selectborderwidth=0, - selectmode=BROWSE, - yscroll=self.frame.vscroll.set) - self.frame.vscroll['command'] = self.frame.list.yview - self.frame.vscroll.pack(side=RIGHT, fill=Y) - self.frame.list.pack(expand=1, fill=BOTH) - self.update = Button(self, text='Update', - command=self.do_update) - self.update.pack(fill=X) - self.frame.list.bind('<Motion>', self.do_motion) - self.frame.list.bind('<Leave>', self.do_leave) - self.frame.list.bind('<1>', self.do_1) - self.do_update() - -if __name__ == '__main__': - kill = Kill(None, borderwidth=5) - kill.winfo_toplevel().title('Tkinter Process Killer (SYSV)') - kill.winfo_toplevel().minsize(1, 1) - kill.mainloop() diff --git a/Demo/tkinter/guido/switch.py b/Demo/tkinter/guido/switch.py deleted file mode 100644 index 3f43925..0000000 --- a/Demo/tkinter/guido/switch.py +++ /dev/null @@ -1,55 +0,0 @@ -# Show how to do switchable panels. - -from tkinter import * - -class App: - - def __init__(self, top=None, master=None): - if top is None: - if master is None: - top = Tk() - else: - top = Toplevel(master) - self.top = top - self.buttonframe = Frame(top) - self.buttonframe.pack() - self.panelframe = Frame(top, borderwidth=2, relief=GROOVE) - self.panelframe.pack(expand=1, fill=BOTH) - self.panels = {} - self.curpanel = None - - def addpanel(self, name, klass): - button = Button(self.buttonframe, text=name, - command=lambda self=self, name=name: self.show(name)) - button.pack(side=LEFT) - frame = Frame(self.panelframe) - instance = klass(frame) - self.panels[name] = (button, frame, instance) - if self.curpanel is None: - self.show(name) - - def show(self, name): - (button, frame, instance) = self.panels[name] - if self.curpanel: - self.curpanel.pack_forget() - self.curpanel = frame - frame.pack(expand=1, fill="both") - -class LabelPanel: - def __init__(self, frame): - self.label = Label(frame, text="Hello world") - self.label.pack() - -class ButtonPanel: - def __init__(self, frame): - self.button = Button(frame, text="Press me") - self.button.pack() - -def main(): - app = App() - app.addpanel("label", LabelPanel) - app.addpanel("button", ButtonPanel) - app.top.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/tkman.py b/Demo/tkinter/guido/tkman.py deleted file mode 100755 index 1baed88..0000000 --- a/Demo/tkinter/guido/tkman.py +++ /dev/null @@ -1,267 +0,0 @@ -#! /usr/bin/env python - -# Tk man page browser -- currently only shows the Tcl/Tk man pages - -import os -import re -import sys -from tkinter import * - -from manpage import ManPage - -MANNDIRLIST = ['/usr/local/man/mann', '/usr/share/man/mann'] -MAN3DIRLIST = ['/usr/local/man/man3', '/usr/share/man/man3'] - -foundmanndir = 0 -for dir in MANNDIRLIST: - if os.path.exists(dir): - MANNDIR = dir - foundmanndir = 1 - -foundman3dir = 0 -for dir in MAN3DIRLIST: - if os.path.exists(dir): - MAN3DIR = dir - foundman3dir = 1 - -if not foundmanndir or not foundman3dir: - sys.stderr.write('\n') - if not foundmanndir: - msg = """\ -Failed to find mann directory. -Please add the correct entry to the MANNDIRLIST -at the top of %s script.""" % \ -sys.argv[0] - sys.stderr.write("%s\n\n" % msg) - if not foundman3dir: - msg = """\ -Failed to find man3 directory. -Please add the correct entry to the MAN3DIRLIST -at the top of %s script.""" % \ -sys.argv[0] - sys.stderr.write("%s\n\n" % msg) - sys.exit(1) - -del foundmanndir -del foundman3dir - -def listmanpages(mandir): - files = os.listdir(mandir) - names = [] - for file in files: - if file[-2:-1] == '.' and (file[-1] in 'ln123456789'): - names.append(file[:-2]) - names.sort() - return names - -class SelectionBox: - - def __init__(self, master=None): - self.choices = [] - - self.frame = Frame(master, name="frame") - self.frame.pack(expand=1, fill=BOTH) - self.master = self.frame.master - self.subframe = Frame(self.frame, name="subframe") - self.subframe.pack(expand=0, fill=BOTH) - self.leftsubframe = Frame(self.subframe, name='leftsubframe') - self.leftsubframe.pack(side=LEFT, expand=1, fill=BOTH) - self.rightsubframe = Frame(self.subframe, name='rightsubframe') - self.rightsubframe.pack(side=RIGHT, expand=1, fill=BOTH) - self.chaptervar = StringVar(master) - self.chapter = Menubutton(self.rightsubframe, name='chapter', - text='Directory', relief=RAISED, - borderwidth=2) - self.chapter.pack(side=TOP) - self.chaptermenu = Menu(self.chapter, name='chaptermenu') - self.chaptermenu.add_radiobutton(label='C functions', - value=MAN3DIR, - variable=self.chaptervar, - command=self.newchapter) - self.chaptermenu.add_radiobutton(label='Tcl/Tk functions', - value=MANNDIR, - variable=self.chaptervar, - command=self.newchapter) - self.chapter['menu'] = self.chaptermenu - self.listbox = Listbox(self.rightsubframe, name='listbox', - relief=SUNKEN, borderwidth=2, - width=20, height=5) - self.listbox.pack(expand=1, fill=BOTH) - self.l1 = Button(self.leftsubframe, name='l1', - text='Display manual page named:', - command=self.entry_cb) - self.l1.pack(side=TOP) - self.entry = Entry(self.leftsubframe, name='entry', - relief=SUNKEN, borderwidth=2, - width=20) - self.entry.pack(expand=0, fill=X) - self.l2frame = Frame(self.leftsubframe, name='l2frame') - self.l2frame.pack(expand=0, fill=NONE) - self.l2 = Button(self.l2frame, name='l2', - text='Search regexp:', - command=self.search_cb) - self.l2.pack(side=LEFT) - self.casevar = BooleanVar() - self.casesense = Checkbutton(self.l2frame, name='casesense', - text='Case sensitive', - variable=self.casevar, - relief=FLAT) - self.casesense.pack(side=LEFT) - self.search = Entry(self.leftsubframe, name='search', - relief=SUNKEN, borderwidth=2, - width=20) - self.search.pack(expand=0, fill=X) - self.title = Label(self.leftsubframe, name='title', - text='(none)') - self.title.pack(side=BOTTOM) - self.text = ManPage(self.frame, name='text', - relief=SUNKEN, borderwidth=2, - wrap=NONE, width=72, - selectbackground='pink') - self.text.pack(expand=1, fill=BOTH) - - self.entry.bind('<Return>', self.entry_cb) - self.search.bind('<Return>', self.search_cb) - self.listbox.bind('<Double-1>', self.listbox_cb) - - self.entry.bind('<Tab>', self.entry_tab) - self.search.bind('<Tab>', self.search_tab) - self.text.bind('<Tab>', self.text_tab) - - self.entry.focus_set() - - self.chaptervar.set(MANNDIR) - self.newchapter() - - def newchapter(self): - mandir = self.chaptervar.get() - self.choices = [] - self.addlist(listmanpages(mandir)) - - def addchoice(self, choice): - if choice not in self.choices: - self.choices.append(choice) - self.choices.sort() - self.update() - - def addlist(self, list): - self.choices[len(self.choices):] = list - self.choices.sort() - self.update() - - def entry_cb(self, *e): - self.update() - - def listbox_cb(self, e): - selection = self.listbox.curselection() - if selection and len(selection) == 1: - name = self.listbox.get(selection[0]) - self.show_page(name) - - def search_cb(self, *e): - self.search_string(self.search.get()) - - def entry_tab(self, e): - self.search.focus_set() - - def search_tab(self, e): - self.entry.focus_set() - - def text_tab(self, e): - self.entry.focus_set() - - def updatelist(self): - key = self.entry.get() - ok = list(filter(lambda name, key=key, n=len(key): name[:n]==key, - self.choices)) - if not ok: - self.frame.bell() - self.listbox.delete(0, AtEnd()) - exactmatch = 0 - for item in ok: - if item == key: exactmatch = 1 - self.listbox.insert(AtEnd(), item) - if exactmatch: - return key - n = self.listbox.size() - if n == 1: - return self.listbox.get(0) - # Else return None, meaning not a unique selection - - def update(self): - name = self.updatelist() - if name: - self.show_page(name) - self.entry.delete(0, AtEnd()) - self.updatelist() - - def show_page(self, name): - file = '%s/%s.?' % (self.chaptervar.get(), name) - fp = os.popen('nroff -man -c %s | ul -i' % file, 'r') - self.text.kill() - self.title['text'] = name - self.text.parsefile(fp) - - def search_string(self, search): - if not search: - self.frame.bell() - print('Empty search string') - return - if not self.casevar.get(): - map = re.IGNORECASE - else: - map = None - try: - if map: - prog = re.compile(search, map) - else: - prog = re.compile(search) - except re.error as msg: - self.frame.bell() - print('Regex error:', msg) - return - here = self.text.index(AtInsert()) - lineno = int(here[:here.find('.')]) - end = self.text.index(AtEnd()) - endlineno = int(end[:end.find('.')]) - wraplineno = lineno - found = 0 - while 1: - lineno = lineno + 1 - if lineno > endlineno: - if wraplineno <= 0: - break - endlineno = wraplineno - lineno = 0 - wraplineno = 0 - line = self.text.get('%d.0 linestart' % lineno, - '%d.0 lineend' % lineno) - i = prog.search(line) - if i: - found = 1 - n = max(1, len(i.group(0))) - try: - self.text.tag_remove('sel', - AtSelFirst(), - AtSelLast()) - except TclError: - pass - self.text.tag_add('sel', - '%d.%d' % (lineno, i.start()), - '%d.%d' % (lineno, i.start()+n)) - self.text.mark_set(AtInsert(), - '%d.%d' % (lineno, i.start())) - self.text.yview_pickplace(AtInsert()) - break - if not found: - self.frame.bell() - -def main(): - root = Tk() - sb = SelectionBox(root) - if sys.argv[1:]: - sb.show_page(sys.argv[1]) - root.minsize(1, 1) - root.mainloop() - -main() diff --git a/Demo/tkinter/guido/wish.py b/Demo/tkinter/guido/wish.py deleted file mode 100755 index 332501d..0000000 --- a/Demo/tkinter/guido/wish.py +++ /dev/null @@ -1,34 +0,0 @@ -# This is about all it requires to write a wish shell in Python! - -import _tkinter -import os -import sys - -tk = _tkinter.create(os.environ['DISPLAY'], 'wish', 'Tk', 1, 1) -tk.call('update') - -cmd = '' - -while True: - if cmd: - prompt = '' - else: - prompt = '% ' - try: - sys.stdout.write(prompt) - sys.stdout.flush() - line = sys.stdin.readline() - if not line: - break - except EOFError: - break - cmd += line - if tk.getboolean(tk.call('info', 'complete', cmd)): - tk.record(line) - try: - result = tk.call('eval', cmd) - except _tkinter.TclError as msg: - print('TclError:', msg) - else: - if result: print(result) - cmd = '' diff --git a/Demo/tkinter/matt/00-HELLO-WORLD.py b/Demo/tkinter/matt/00-HELLO-WORLD.py deleted file mode 100644 index 3b4092a..0000000 --- a/Demo/tkinter/matt/00-HELLO-WORLD.py +++ /dev/null @@ -1,27 +0,0 @@ -from tkinter import * - -# note that there is no explicit call to start Tk. -# Tkinter is smart enough to start the system if it's not already going. - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - - self.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - self.hi_there = Button(self, text='Hello', - command=self.printit) - self.hi_there.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/README b/Demo/tkinter/matt/README deleted file mode 100644 index eb9d302..0000000 --- a/Demo/tkinter/matt/README +++ /dev/null @@ -1,30 +0,0 @@ -This directory contains some ad-hoc examples of Tkinter widget -creation. The files named - - *-simple.py - -are the ones to start with if you're looking for a bare-bones usage of -a widget. The other files are meant to show common usage patters that -are a tad more involved. - -If you have a suggestion for an example program, please send mail to - - conway@virginia.edu - -and I'll include it. - - -matt - -TODO -------- -The X selection -Dialog Boxes -More canvas examples -Message widgets -Text Editors -Scrollbars -Listboxes - - - diff --git a/Demo/tkinter/matt/animation-simple.py b/Demo/tkinter/matt/animation-simple.py deleted file mode 100644 index 4120d66..0000000 --- a/Demo/tkinter/matt/animation-simple.py +++ /dev/null @@ -1,35 +0,0 @@ -from tkinter import * - -# This program shows how to use the "after" function to make animation. - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - self.draw = Canvas(self, width="5i", height="5i") - - # all of these work.. - self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue") - self.draw.pack(side=LEFT) - - def moveThing(self, *args): - # move 1/10 of an inch every 1/10 sec (1" per second, smoothly) - self.draw.move("thing", "0.01i", "0.01i") - self.after(10, self.moveThing) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - self.after(10, self.moveThing) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/animation-w-velocity-ctrl.py b/Demo/tkinter/matt/animation-w-velocity-ctrl.py deleted file mode 100644 index 88309ca..0000000 --- a/Demo/tkinter/matt/animation-w-velocity-ctrl.py +++ /dev/null @@ -1,44 +0,0 @@ -from tkinter import * - -# this is the same as simple-demo-1.py, but uses -# subclassing. -# note that there is no explicit call to start Tk. -# Tkinter is smart enough to start the system if it's not already going. - - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.draw = Canvas(self, width="5i", height="5i") - - self.speed = Scale(self, orient=HORIZONTAL, from_=-100, to=100) - - self.speed.pack(side=BOTTOM, fill=X) - - # all of these work.. - self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue") - self.draw.pack(side=LEFT) - - def moveThing(self, *args): - velocity = self.speed.get() - str = float(velocity) / 1000.0 - str = "%ri" % (str,) - self.draw.move("thing", str, str) - self.after(10, self.moveThing) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - self.after(10, self.moveThing) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/bind-w-mult-calls-p-type.py b/Demo/tkinter/matt/bind-w-mult-calls-p-type.py deleted file mode 100644 index 0da7c37..0000000 --- a/Demo/tkinter/matt/bind-w-mult-calls-p-type.py +++ /dev/null @@ -1,43 +0,0 @@ -from tkinter import * - -# This program shows how to use a simple type-in box - -class App(Frame): - def __init__(self, master=None): - Frame.__init__(self, master) - self.pack() - - self.entrythingy = Entry() - self.entrythingy.pack() - - # and here we get a callback when the user hits return. we could - # make the key that triggers the callback anything we wanted to. - # other typical options might be <Key-Tab> or <Key> (for anything) - self.entrythingy.bind('<Key-Return>', self.print_contents) - - # Note that here is where we bind a completely different callback to - # the same event. We pass "+" here to indicate that we wish to ADD - # this callback to the list associated with this event type. - # Not specifying "+" would simply override whatever callback was - # defined on this event. - self.entrythingy.bind('<Key-Return>', self.print_something_else, "+") - - def print_contents(self, event): - print("hi. contents of entry is now ---->", self.entrythingy.get()) - - - def print_something_else(self, event): - print("hi. Now doing something completely different") - - -root = App() -root.master.title("Foo") -root.mainloop() - - - -# secret tip for experts: if you pass *any* non-false value as -# the third parameter to bind(), Tkinter.py will accumulate -# callbacks instead of overwriting. I use "+" here because that's -# the Tk notation for getting this sort of behavior. The perfect GUI -# interface would use a less obscure notation. diff --git a/Demo/tkinter/matt/canvas-demo-simple.py b/Demo/tkinter/matt/canvas-demo-simple.py deleted file mode 100644 index 7f2c17b..0000000 --- a/Demo/tkinter/matt/canvas-demo-simple.py +++ /dev/null @@ -1,28 +0,0 @@ -from tkinter import * - -# this program creates a canvas and puts a single polygon on the canvas - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.draw = Canvas(self, width="5i", height="5i") - - # see the other demos for other ways of specifying coords for a polygon - self.draw.create_rectangle(0, 0, "3i", "3i", fill="black") - - self.draw.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-gridding.py b/Demo/tkinter/matt/canvas-gridding.py deleted file mode 100644 index 2f9d23a..0000000 --- a/Demo/tkinter/matt/canvas-gridding.py +++ /dev/null @@ -1,61 +0,0 @@ -from tkinter import * - -# this is the same as simple-demo-1.py, but uses -# subclassing. -# note that there is no explicit call to start Tk. -# Tkinter is smart enough to start the system if it's not already going. - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', - background='red', - foreground='white', - height=3, - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.canvasObject = Canvas(self, width="5i", height="5i") - self.canvasObject.pack(side=LEFT) - - def mouseDown(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - self.startx = self.canvasObject.canvasx(event.x, self.griddingSize) - self.starty = self.canvasObject.canvasy(event.y, self.griddingSize) - - def mouseMotion(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - x = self.canvasObject.canvasx(event.x, self.griddingSize) - y = self.canvasObject.canvasy(event.y, self.griddingSize) - - if (self.startx != event.x) and (self.starty != event.y) : - self.canvasObject.delete(self.rubberbandBox) - self.rubberbandBox = self.canvasObject.create_rectangle( - self.startx, self.starty, x, y) - # this flushes the output, making sure that - # the rectangle makes it to the screen - # before the next event is handled - self.update_idletasks() - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - - # this is a "tagOrId" for the rectangle we draw on the canvas - self.rubberbandBox = None - - # this is the size of the gridding squares - self.griddingSize = 50 - - Widget.bind(self.canvasObject, "<Button-1>", self.mouseDown) - Widget.bind(self.canvasObject, "<Button1-Motion>", self.mouseMotion) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-moving-or-creating.py b/Demo/tkinter/matt/canvas-moving-or-creating.py deleted file mode 100644 index edd64f7..0000000 --- a/Demo/tkinter/matt/canvas-moving-or-creating.py +++ /dev/null @@ -1,62 +0,0 @@ -from tkinter import * - -# this file demonstrates a more sophisticated movement -- -# move dots or create new ones if you click outside the dots - -class Test(Frame): - ################################################################### - ###### Event callbacks for THE CANVAS (not the stuff drawn on it) - ################################################################### - def mouseDown(self, event): - # see if we're inside a dot. If we are, it - # gets tagged as CURRENT for free by tk. - if not event.widget.find_withtag(CURRENT): - # there is no dot here, so we can make one, - # and bind some interesting behavior to it. - # ------ - # create a dot, and mark it as CURRENT - fred = self.draw.create_oval( - event.x - 10, event.y -10, event.x +10, event.y + 10, - fill="green", tags=CURRENT) - - self.draw.tag_bind(fred, "<Any-Enter>", self.mouseEnter) - self.draw.tag_bind(fred, "<Any-Leave>", self.mouseLeave) - - self.lastx = event.x - self.lasty = event.y - - def mouseMove(self, event): - self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - ################################################################### - ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas) - ################################################################### - def mouseEnter(self, event): - # the CURRENT tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="red") - - def mouseLeave(self, event): - # the CURRENT tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="blue") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - self.draw = Canvas(self, width="5i", height="5i") - self.draw.pack(side=LEFT) - - Widget.bind(self.draw, "<1>", self.mouseDown) - Widget.bind(self.draw, "<B1-Motion>", self.mouseMove) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-moving-w-mouse.py b/Demo/tkinter/matt/canvas-moving-w-mouse.py deleted file mode 100644 index 21d724f..0000000 --- a/Demo/tkinter/matt/canvas-moving-w-mouse.py +++ /dev/null @@ -1,55 +0,0 @@ -from tkinter import * - -# this file demonstrates the movement of a single canvas item under mouse control - -class Test(Frame): - ################################################################### - ###### Event callbacks for THE CANVAS (not the stuff drawn on it) - ################################################################### - def mouseDown(self, event): - # remember where the mouse went down - self.lastx = event.x - self.lasty = event.y - - def mouseMove(self, event): - # whatever the mouse is over gets tagged as CURRENT for free by tk. - self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - ################################################################### - ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas) - ################################################################### - def mouseEnter(self, event): - # the CURRENT tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="red") - - def mouseLeave(self, event): - # the CURRENT tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="blue") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - self.draw = Canvas(self, width="5i", height="5i") - self.draw.pack(side=LEFT) - - fred = self.draw.create_oval(0, 0, 20, 20, - fill="green", tags="selected") - - self.draw.tag_bind(fred, "<Any-Enter>", self.mouseEnter) - self.draw.tag_bind(fred, "<Any-Leave>", self.mouseLeave) - - Widget.bind(self.draw, "<1>", self.mouseDown) - Widget.bind(self.draw, "<B1-Motion>", self.mouseMove) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-mult-item-sel.py b/Demo/tkinter/matt/canvas-mult-item-sel.py deleted file mode 100644 index 4875b44..0000000 --- a/Demo/tkinter/matt/canvas-mult-item-sel.py +++ /dev/null @@ -1,78 +0,0 @@ -from tkinter import * - -# allows moving dots with multiple selection. - -SELECTED_COLOR = "red" -UNSELECTED_COLOR = "blue" - -class Test(Frame): - ################################################################### - ###### Event callbacks for THE CANVAS (not the stuff drawn on it) - ################################################################### - def mouseDown(self, event): - # see if we're inside a dot. If we are, it - # gets tagged as CURRENT for free by tk. - - if not event.widget.find_withtag(CURRENT): - # we clicked outside of all dots on the canvas. unselect all. - - # re-color everything back to an unselected color - self.draw.itemconfig("selected", fill=UNSELECTED_COLOR) - # unselect everything - self.draw.dtag("selected") - else: - # mark as "selected" the thing the cursor is under - self.draw.addtag("selected", "withtag", CURRENT) - # color it as selected - self.draw.itemconfig("selected", fill=SELECTED_COLOR) - - self.lastx = event.x - self.lasty = event.y - - - def mouseMove(self, event): - self.draw.move("selected", event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - def makeNewDot(self): - # create a dot, and mark it as current - fred = self.draw.create_oval(0, 0, 20, 20, - fill=SELECTED_COLOR, tags=CURRENT) - # and make it selected - self.draw.addtag("selected", "withtag", CURRENT) - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - - ################ - # make the canvas and bind some behavior to it - ################ - self.draw = Canvas(self, width="5i", height="5i") - Widget.bind(self.draw, "<1>", self.mouseDown) - Widget.bind(self.draw, "<B1-Motion>", self.mouseMove) - - # and other things..... - self.button = Button(self, text="make a new dot", foreground="blue", - command=self.makeNewDot) - - message = ("%s dots are selected and can be dragged.\n" - "%s are not selected.\n" - "Click in a dot to select it.\n" - "Click on empty space to deselect all dots." - ) % (SELECTED_COLOR, UNSELECTED_COLOR) - self.label = Message(self, width="5i", text=message) - - self.QUIT.pack(side=BOTTOM, fill=BOTH) - self.label.pack(side=BOTTOM, fill=X, expand=1) - self.button.pack(side=BOTTOM, fill=X) - self.draw.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-reading-tag-info.py b/Demo/tkinter/matt/canvas-reading-tag-info.py deleted file mode 100644 index 265f0a1..0000000 --- a/Demo/tkinter/matt/canvas-reading-tag-info.py +++ /dev/null @@ -1,49 +0,0 @@ -from tkinter import * - - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.drawing = Canvas(self, width="5i", height="5i") - - # make a shape - pgon = self.drawing.create_polygon( - 10, 10, 110, 10, 110, 110, 10 , 110, - fill="red", tags=("weee", "foo", "groo")) - - # this is how you query an object for its attributes - # config options FOR CANVAS ITEMS always come back in tuples of length 5. - # 0 attribute name - # 1 BLANK - # 2 BLANK - # 3 default value - # 4 current value - # the blank spots are for consistency with the config command that - # is used for widgets. (remember, this is for ITEMS drawn - # on a canvas widget, not widgets) - option_value = self.drawing.itemconfig(pgon, "stipple") - print("pgon's current stipple value is -->", option_value[4], "<--") - option_value = self.drawing.itemconfig(pgon, "fill") - print("pgon's current fill value is -->", option_value[4], "<--") - print(" when he is usually colored -->", option_value[3], "<--") - - ## here we print out all the tags associated with this object - option_value = self.drawing.itemconfig(pgon, "tags") - print("pgon's tags are", option_value[4]) - - self.drawing.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-w-widget-draw-el.py b/Demo/tkinter/matt/canvas-w-widget-draw-el.py deleted file mode 100644 index ca96583..0000000 --- a/Demo/tkinter/matt/canvas-w-widget-draw-el.py +++ /dev/null @@ -1,36 +0,0 @@ -from tkinter import * - -# this file demonstrates the creation of widgets as part of a canvas object - -class Test(Frame): - def printhi(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.draw = Canvas(self, width="5i", height="5i") - - self.button = Button(self, text="this is a button", - command=self.printhi) - - # note here the coords are given in pixels (form the - # upper right and corner of the window, as usual for X) - # but might just have well been given in inches or points or - # whatever...use the "anchor" option to control what point of the - # widget (in this case the button) gets mapped to the given x, y. - # you can specify corners, edges, center, etc... - self.draw.create_window(300, 300, window=self.button) - - self.draw.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-with-scrollbars.py b/Demo/tkinter/matt/canvas-with-scrollbars.py deleted file mode 100644 index 1c5681a..0000000 --- a/Demo/tkinter/matt/canvas-with-scrollbars.py +++ /dev/null @@ -1,60 +0,0 @@ -from tkinter import * - -# This example program creates a scroling canvas, and demonstrates -# how to tie scrollbars and canvses together. The mechanism -# is analogus for listboxes and other widgets with -# "xscroll" and "yscroll" configuration options. - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.question = Label(self, text="Can Find The BLUE Square??????") - self.question.pack() - - self.QUIT = Button(self, text='QUIT', background='red', - height=3, command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - spacer = Frame(self, height="0.25i") - spacer.pack(side=BOTTOM) - - # notice that the scroll region (20" x 20") is larger than - # displayed size of the widget (5" x 5") - self.draw = Canvas(self, width="5i", height="5i", - background="white", - scrollregion=(0, 0, "20i", "20i")) - - self.draw.scrollX = Scrollbar(self, orient=HORIZONTAL) - self.draw.scrollY = Scrollbar(self, orient=VERTICAL) - - # now tie the three together. This is standard boilerplate text - self.draw['xscrollcommand'] = self.draw.scrollX.set - self.draw['yscrollcommand'] = self.draw.scrollY.set - self.draw.scrollX['command'] = self.draw.xview - self.draw.scrollY['command'] = self.draw.yview - - # draw something. Note that the first square - # is visible, but you need to scroll to see the second one. - self.draw.create_rectangle(0, 0, "3.5i", "3.5i", fill="black") - self.draw.create_rectangle("10i", "10i", "13.5i", "13.5i", fill="blue") - - # pack 'em up - self.draw.scrollX.pack(side=BOTTOM, fill=X) - self.draw.scrollY.pack(side=RIGHT, fill=Y) - self.draw.pack(side=LEFT) - - - def scrollCanvasX(self, *args): - print("scrolling", args) - print(self.draw.scrollX.get()) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/dialog-box.py b/Demo/tkinter/matt/dialog-box.py deleted file mode 100644 index c0b8825..0000000 --- a/Demo/tkinter/matt/dialog-box.py +++ /dev/null @@ -1,64 +0,0 @@ -from tkinter import * -from tkinter.dialog import Dialog - -# this shows how to create a new window with a button in it -# that can create new windows - -class Test(Frame): - def printit(self): - print("hi") - - def makeWindow(self): - """Create a top-level dialog with some buttons. - - This uses the Dialog class, which is a wrapper around the Tcl/Tk - tk_dialog script. The function returns 0 if the user clicks 'yes' - or 1 if the user clicks 'no'. - """ - # the parameters to this call are as follows: - d = Dialog( - self, ## name of a toplevel window - title="fred the dialog box",## title on the window - text="click on a choice", ## message to appear in window - bitmap="info", ## bitmap (if any) to appear; - ## if none, use "" - # legal values here are: - # string what it looks like - # ---------------------------------------------- - # error a circle with a slash through it - # grey25 grey square - # grey50 darker grey square - # hourglass use for "wait.." - # info a large, lower case "i" - # questhead a human head with a "?" in it - # question a large "?" - # warning a large "!" - # @fname X bitmap where fname is the path to the file - # - default=0, # the index of the default button choice. - # hitting return selects this - strings=("yes", "no")) - # values of the 'strings' key are the labels for the - # buttons that appear left to right in the dialog box - return d.num - - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - self.hi_there = Button(self, text='Make a New Window', - command=self.makeWindow) - self.hi_there.pack(side=LEFT) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.windownum = 0 - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/entry-simple.py b/Demo/tkinter/matt/entry-simple.py deleted file mode 100644 index 1f55df5..0000000 --- a/Demo/tkinter/matt/entry-simple.py +++ /dev/null @@ -1,24 +0,0 @@ -from tkinter import * -import string - -# This program shows how to use a simple type-in box - -class App(Frame): - def __init__(self, master=None): - Frame.__init__(self, master) - self.pack() - - self.entrythingy = Entry() - self.entrythingy.pack() - - # and here we get a callback when the user hits return. we could - # make the key that triggers the callback anything we wanted to. - # other typical options might be <Key-Tab> or <Key> (for anything) - self.entrythingy.bind('<Key-Return>', self.print_contents) - - def print_contents(self, event): - print("hi. contents of entry is now ---->", self.entrythingy.get()) - -root = App() -root.master.title("Foo") -root.mainloop() diff --git a/Demo/tkinter/matt/entry-with-shared-variable.py b/Demo/tkinter/matt/entry-with-shared-variable.py deleted file mode 100644 index 7d93da7..0000000 --- a/Demo/tkinter/matt/entry-with-shared-variable.py +++ /dev/null @@ -1,45 +0,0 @@ -from tkinter import * - -# This program shows how to make a typein box shadow a program variable. - -class App(Frame): - def __init__(self, master=None): - Frame.__init__(self, master) - self.pack() - - self.entrythingy = Entry(self) - self.entrythingy.pack() - - self.button = Button(self, text="Uppercase The Entry", - command=self.upper) - self.button.pack() - - # here we have the text in the entry widget tied to a variable. - # changes in the variable are echoed in the widget and vice versa. - # Very handy. - # there are other Variable types. See Tkinter.py for all - # the other variable types that can be shadowed - self.contents = StringVar() - self.contents.set("this is a variable") - self.entrythingy.config(textvariable=self.contents) - - # and here we get a callback when the user hits return. we could - # make the key that triggers the callback anything we wanted to. - # other typical options might be <Key-Tab> or <Key> (for anything) - self.entrythingy.bind('<Key-Return>', self.print_contents) - - def upper(self): - # notice here, we don't actually refer to the entry box. - # we just operate on the string variable and we - # because it's being looked at by the entry widget, changing - # the variable changes the entry widget display automatically. - # the strange get/set operators are clunky, true... - str = self.contents.get().upper() - self.contents.set(str) - - def print_contents(self, event): - print("hi. contents of entry is now ---->", self.contents.get()) - -root = App() -root.master.title("Foo") -root.mainloop() diff --git a/Demo/tkinter/matt/killing-window-w-wm.py b/Demo/tkinter/matt/killing-window-w-wm.py deleted file mode 100644 index b4034d1..0000000 --- a/Demo/tkinter/matt/killing-window-w-wm.py +++ /dev/null @@ -1,42 +0,0 @@ -from tkinter import * - -# This file shows how to trap the killing of a window -# when the user uses window manager menus (typ. upper left hand corner -# menu in the decoration border). - - -### ******* this isn't really called -- read the comments -def my_delete_callback(): - print("whoops -- tried to delete me!") - -class Test(Frame): - def deathHandler(self, event): - print(self, "is now getting nuked. performing some save here....") - - def createWidgets(self): - # a hello button - self.hi_there = Button(self, text='Hello') - self.hi_there.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - - ### - ### PREVENT WM kills from happening - ### - - # the docs would have you do this: - -# self.master.protocol("WM_DELETE_WINDOW", my_delete_callback) - - # unfortunately, some window managers will not send this request to a window. - # the "protocol" function seems incapable of trapping these "aggressive" window kills. - # this line of code catches everything, tho. The window is deleted, but you have a chance - # of cleaning up first. - self.bind_all("<Destroy>", self.deathHandler) - - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/menu-all-types-of-entries.py b/Demo/tkinter/matt/menu-all-types-of-entries.py deleted file mode 100644 index 84f162e..0000000 --- a/Demo/tkinter/matt/menu-all-types-of-entries.py +++ /dev/null @@ -1,244 +0,0 @@ -from tkinter import * - -# some vocabulary to keep from getting confused. This terminology -# is something I cooked up for this file, but follows the man pages -# pretty closely -# -# -# -# This is a MENUBUTTON -# V -# +-------------+ -# | | -# -# +------------++------------++------------+ -# | || || | -# | File || Edit || Options | <-------- the MENUBAR -# | || || | -# +------------++------------++------------+ -# | New... | -# | Open... | -# | Print | -# | | <-------- This is a MENU. The lines of text in the menu are -# | | MENU ENTRIES -# | +---------------+ -# | Open Files > | file1 | -# | | file2 | -# | | another file | <------ this cascading part is also a MENU -# +----------------| | -# | | -# | | -# | | -# +---------------+ - - - -# some miscellaneous callbacks -def new_file(): - print("opening new file") - -def open_file(): - print("opening OLD file") - -def print_something(): - print("picked a menu item") - - - -anchovies = 0 - -def print_anchovies(): - global anchovies - anchovies = not anchovies - print("anchovies?", anchovies) - -def makeCommandMenu(): - # make menu button - Command_button = Menubutton(mBar, text='Simple Button Commands', - underline=0) - Command_button.pack(side=LEFT, padx="2m") - - # make the pulldown part of the File menu. The parameter passed is the master. - # we attach it to the button as a python attribute called "menu" by convention. - # hopefully this isn't too confusing... - Command_button.menu = Menu(Command_button) - - # just to be cute, let's disable the undo option: - Command_button.menu.add_command(label="Undo") - # undo is the 0th entry... - Command_button.menu.entryconfig(0, state=DISABLED) - - Command_button.menu.add_command(label='New...', underline=0, - command=new_file) - Command_button.menu.add_command(label='Open...', underline=0, - command=open_file) - Command_button.menu.add_command(label='Different Font', underline=0, - font='-*-helvetica-*-r-*-*-*-180-*-*-*-*-*-*', - command=print_something) - - # we can make bitmaps be menu entries too. File format is X11 bitmap. - # if you use XV, save it under X11 bitmap format. duh-uh.,.. - Command_button.menu.add_command( - bitmap="info") - #bitmap='@/home/mjc4y/dilbert/project.status.is.doomed.last.panel.bm') - - # this is just a line - Command_button.menu.add('separator') - - # change the color - Command_button.menu.add_command(label='Quit', underline=0, - background='red', - activebackground='green', - command=Command_button.quit) - - # set up a pointer from the file menubutton back to the file menu - Command_button['menu'] = Command_button.menu - - return Command_button - - - -def makeCascadeMenu(): - # make menu button - Cascade_button = Menubutton(mBar, text='Cascading Menus', underline=0) - Cascade_button.pack(side=LEFT, padx="2m") - - # the primary pulldown - Cascade_button.menu = Menu(Cascade_button) - - # this is the menu that cascades from the primary pulldown.... - Cascade_button.menu.choices = Menu(Cascade_button.menu) - - # ...and this is a menu that cascades from that. - Cascade_button.menu.choices.weirdones = Menu(Cascade_button.menu.choices) - - # then you define the menus from the deepest level on up. - Cascade_button.menu.choices.weirdones.add_command(label='avacado') - Cascade_button.menu.choices.weirdones.add_command(label='belgian endive') - Cascade_button.menu.choices.weirdones.add_command(label='beefaroni') - - # definition of the menu one level up... - Cascade_button.menu.choices.add_command(label='Chocolate') - Cascade_button.menu.choices.add_command(label='Vanilla') - Cascade_button.menu.choices.add_command(label='TuttiFruiti') - Cascade_button.menu.choices.add_command(label='WopBopaLoopBapABopBamBoom') - Cascade_button.menu.choices.add_command(label='Rocky Road') - Cascade_button.menu.choices.add_command(label='BubbleGum') - Cascade_button.menu.choices.add_cascade( - label='Weird Flavors', - menu=Cascade_button.menu.choices.weirdones) - - # and finally, the definition for the top level - Cascade_button.menu.add_cascade(label='more choices', - menu=Cascade_button.menu.choices) - - Cascade_button['menu'] = Cascade_button.menu - - return Cascade_button - -def makeCheckbuttonMenu(): - global fred - # make menu button - Checkbutton_button = Menubutton(mBar, text='Checkbutton Menus', - underline=0) - Checkbutton_button.pack(side=LEFT, padx='2m') - - # the primary pulldown - Checkbutton_button.menu = Menu(Checkbutton_button) - - # and all the check buttons. Note that the "variable" "onvalue" and "offvalue" options - # are not supported correctly at present. You have to do all your application - # work through the calback. - Checkbutton_button.menu.add_checkbutton(label='Pepperoni') - Checkbutton_button.menu.add_checkbutton(label='Sausage') - Checkbutton_button.menu.add_checkbutton(label='Extra Cheese') - - # so here's a callback - Checkbutton_button.menu.add_checkbutton(label='Anchovy', - command=print_anchovies) - - # and start with anchovies selected to be on. Do this by - # calling invoke on this menu option. To refer to the "anchovy" menu - # entry we need to know it's index. To do this, we use the index method - # which takes arguments of several forms: - # - # argument what it does - # ----------------------------------- - # a number -- this is useless. - # "last" -- last option in the menu - # "none" -- used with the activate command. see the man page on menus - # "active" -- the currently active menu option. A menu option is made active - # with the 'activate' method - # "@number" -- where 'number' is an integer and is treated like a y coordinate in pixels - # string pattern -- this is the option used below, and attempts to match "labels" using the - # rules of Tcl_StringMatch - Checkbutton_button.menu.invoke(Checkbutton_button.menu.index('Anchovy')) - - # set up a pointer from the file menubutton back to the file menu - Checkbutton_button['menu'] = Checkbutton_button.menu - - return Checkbutton_button - - -def makeRadiobuttonMenu(): - # make menu button - Radiobutton_button = Menubutton(mBar, text='Radiobutton Menus', - underline=0) - Radiobutton_button.pack(side=LEFT, padx='2m') - - # the primary pulldown - Radiobutton_button.menu = Menu(Radiobutton_button) - - # and all the Radio buttons. Note that the "variable" "onvalue" and "offvalue" options - # are not supported correctly at present. You have to do all your application - # work through the calback. - Radiobutton_button.menu.add_radiobutton(label='Republican') - Radiobutton_button.menu.add_radiobutton(label='Democrat') - Radiobutton_button.menu.add_radiobutton(label='Libertarian') - Radiobutton_button.menu.add_radiobutton(label='Commie') - Radiobutton_button.menu.add_radiobutton(label='Facist') - Radiobutton_button.menu.add_radiobutton(label='Labor Party') - Radiobutton_button.menu.add_radiobutton(label='Torie') - Radiobutton_button.menu.add_radiobutton(label='Independent') - Radiobutton_button.menu.add_radiobutton(label='Anarchist') - Radiobutton_button.menu.add_radiobutton(label='No Opinion') - - # set up a pointer from the file menubutton back to the file menu - Radiobutton_button['menu'] = Radiobutton_button.menu - - return Radiobutton_button - - -def makeDisabledMenu(): - Dummy_button = Menubutton(mBar, text='Dead Menu', underline=0) - Dummy_button.pack(side=LEFT, padx='2m') - - # this is the standard way of turning off a whole menu - Dummy_button["state"] = DISABLED - return Dummy_button - - -################################################# -#### Main starts here ... -root = Tk() - - -# make a menu bar -mBar = Frame(root, relief=RAISED, borderwidth=2) -mBar.pack(fill=X) - -Command_button = makeCommandMenu() -Cascade_button = makeCascadeMenu() -Checkbutton_button = makeCheckbuttonMenu() -Radiobutton_button = makeRadiobuttonMenu() -NoMenu = makeDisabledMenu() - -# finally, install the buttons in the menu bar. -# This allows for scanning from one menubutton to the next. -mBar.tk_menuBar(Command_button, Cascade_button, Checkbutton_button, Radiobutton_button, NoMenu) - - -root.title('menu demo') -root.iconname('menu demo') - -root.mainloop() diff --git a/Demo/tkinter/matt/menu-simple.py b/Demo/tkinter/matt/menu-simple.py deleted file mode 100644 index 5d3303f..0000000 --- a/Demo/tkinter/matt/menu-simple.py +++ /dev/null @@ -1,112 +0,0 @@ -from tkinter import * - -# some vocabulary to keep from getting confused. This terminology -# is something I cooked up for this file, but follows the man pages -# pretty closely -# -# -# -# This is a MENUBUTTON -# V -# +-------------+ -# | | -# -# +------------++------------++------------+ -# | || || | -# | File || Edit || Options | <-------- the MENUBAR -# | || || | -# +------------++------------++------------+ -# | New... | -# | Open... | -# | Print | -# | | <------ This is a MENU. The lines of text in the menu are -# | | MENU ENTRIES -# | +---------------+ -# | Open Files > | file1 | -# | | file2 | -# | | another file | <------ this cascading part is also a MENU -# +----------------| | -# | | -# | | -# | | -# +---------------+ - - - -def new_file(): - print("opening new file") - - -def open_file(): - print("opening OLD file") - - -def makeFileMenu(): - # make menu button : "File" - File_button = Menubutton(mBar, text='File', underline=0) - File_button.pack(side=LEFT, padx="1m") - File_button.menu = Menu(File_button) - - # add an item. The first param is a menu entry type, - # must be one of: "cascade", "checkbutton", "command", "radiobutton", "separator" - # see menu-demo-2.py for examples of use - File_button.menu.add_command(label='New...', underline=0, - command=new_file) - - - File_button.menu.add_command(label='Open...', underline=0, - command=open_file) - - File_button.menu.add_command(label='Quit', underline=0, - command='exit') - - # set up a pointer from the file menubutton back to the file menu - File_button['menu'] = File_button.menu - - return File_button - - - -def makeEditMenu(): - Edit_button = Menubutton(mBar, text='Edit', underline=0) - Edit_button.pack(side=LEFT, padx="1m") - Edit_button.menu = Menu(Edit_button) - - # just to be cute, let's disable the undo option: - Edit_button.menu.add('command', label="Undo") - # Since the tear-off bar is the 0th entry, - # undo is the 1st entry... - Edit_button.menu.entryconfig(1, state=DISABLED) - - # and these are just for show. No "command" callbacks attached. - Edit_button.menu.add_command(label="Cut") - Edit_button.menu.add_command(label="Copy") - Edit_button.menu.add_command(label="Paste") - - # set up a pointer from the file menubutton back to the file menu - Edit_button['menu'] = Edit_button.menu - - return Edit_button - - -################################################# - -#### Main starts here ... -root = Tk() - - -# make a menu bar -mBar = Frame(root, relief=RAISED, borderwidth=2) -mBar.pack(fill=X) - -File_button = makeFileMenu() -Edit_button = makeEditMenu() - -# finally, install the buttons in the menu bar. -# This allows for scanning from one menubutton to the next. -mBar.tk_menuBar(File_button, Edit_button) - -root.title('menu demo') -root.iconname('packer') - -root.mainloop() diff --git a/Demo/tkinter/matt/not-what-you-might-think-1.py b/Demo/tkinter/matt/not-what-you-might-think-1.py deleted file mode 100644 index 85c65c8..0000000 --- a/Demo/tkinter/matt/not-what-you-might-think-1.py +++ /dev/null @@ -1,28 +0,0 @@ -from tkinter import * - - -class Test(Frame): - def createWidgets(self): - - self.Gpanel = Frame(self, width='1i', height='1i', - background='green') - self.Gpanel.pack(side=LEFT) - - # a QUIT button - self.Gpanel.QUIT = Button(self.Gpanel, text='QUIT', - foreground='red', - command=self.quit) - self.Gpanel.QUIT.pack(side=LEFT) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.master.title('packer demo') -test.master.iconname('packer') - -test.mainloop() diff --git a/Demo/tkinter/matt/not-what-you-might-think-2.py b/Demo/tkinter/matt/not-what-you-might-think-2.py deleted file mode 100644 index 4512063..0000000 --- a/Demo/tkinter/matt/not-what-you-might-think-2.py +++ /dev/null @@ -1,30 +0,0 @@ -from tkinter import * - - -class Test(Frame): - def createWidgets(self): - - self.Gpanel = Frame(self, width='1i', height='1i', - background='green') - - # this line turns off the recalculation of geometry by masters. - self.Gpanel.propagate(0) - - self.Gpanel.pack(side=LEFT) - - # a QUIT button - self.Gpanel.QUIT = Button(self.Gpanel, text='QUIT', foreground='red', - command=self.quit) - self.Gpanel.QUIT.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.master.title('packer demo') -test.master.iconname('packer') - -test.mainloop() diff --git a/Demo/tkinter/matt/packer-and-placer-together.py b/Demo/tkinter/matt/packer-and-placer-together.py deleted file mode 100644 index 3cf6c45..0000000 --- a/Demo/tkinter/matt/packer-and-placer-together.py +++ /dev/null @@ -1,41 +0,0 @@ -from tkinter import * - -# This is a program that tests the placer geom manager in conjunction with -# the packer. The background (green) is packed, while the widget inside is placed - - -def do_motion(event): - app.button.place(x=event.x, y=event.y) - -def dothis(): - print('calling me!') - -def createWidgets(top): - # make a frame. Note that the widget is 200 x 200 - # and the window containing is 400x400. We do this - # simply to show that this is possible. The rest of the - # area is inaccesssible. - f = Frame(top, width=200, height=200, background='green') - - # note that we use a different manager here. - # This way, the top level frame widget resizes when the - # application window does. - f.pack(fill=BOTH, expand=1) - - # now make a button - f.button = Button(f, foreground='red', text='amazing', command=dothis) - - # and place it so that the nw corner is - # 1/2 way along the top X edge of its' parent - f.button.place(relx=0.5, rely=0.0, anchor=NW) - - # allow the user to move the button SUIT-style. - f.bind('<Control-Shift-Motion>', do_motion) - - return f - -root = Tk() -app = createWidgets(root) -root.geometry("400x400") -root.maxsize(1000, 1000) -root.mainloop() diff --git a/Demo/tkinter/matt/packer-simple.py b/Demo/tkinter/matt/packer-simple.py deleted file mode 100644 index 64f61d5..0000000 --- a/Demo/tkinter/matt/packer-simple.py +++ /dev/null @@ -1,32 +0,0 @@ -from tkinter import * - - -class Test(Frame): - def printit(self): - print(self.hi_there["command"]) - - def createWidgets(self): - # a hello button - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - self.hi_there = Button(self, text='Hello', - command=self.printit) - self.hi_there.pack(side=LEFT) - - # note how Packer defaults to side=TOP - - self.guy2 = Button(self, text='button 2') - self.guy2.pack() - - self.guy3 = Button(self, text='button 3') - self.guy3.pack() - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/placer-simple.py b/Demo/tkinter/matt/placer-simple.py deleted file mode 100644 index 6be0de9..0000000 --- a/Demo/tkinter/matt/placer-simple.py +++ /dev/null @@ -1,39 +0,0 @@ -from tkinter import * - -# This is a program that tests the placer geom manager - -def do_motion(event): - app.button.place(x=event.x, y=event.y) - -def dothis(): - print('calling me!') - -def createWidgets(top): - # make a frame. Note that the widget is 200 x 200 - # and the window containing is 400x400. We do this - # simply to show that this is possible. The rest of the - # area is inaccesssible. - f = Frame(top, width=200, height=200, background='green') - - # place it so the upper left hand corner of - # the frame is in the upper left corner of - # the parent - f.place(relx=0.0, rely=0.0) - - # now make a button - f.button = Button(f, foreground='red', text='amazing', command=dothis) - - # and place it so that the nw corner is - # 1/2 way along the top X edge of its' parent - f.button.place(relx=0.5, rely=0.0, anchor=NW) - - # allow the user to move the button SUIT-style. - f.bind('<Control-Shift-Motion>', do_motion) - - return f - -root = Tk() -app = createWidgets(root) -root.geometry("400x400") -root.maxsize(1000, 1000) -root.mainloop() diff --git a/Demo/tkinter/matt/pong-demo-1.py b/Demo/tkinter/matt/pong-demo-1.py deleted file mode 100644 index 82a5dc0..0000000 --- a/Demo/tkinter/matt/pong-demo-1.py +++ /dev/null @@ -1,52 +0,0 @@ -from tkinter import * - - -class Pong(Frame): - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - ## The playing field - self.draw = Canvas(self, width="5i", height="5i") - - ## The speed control for the ball - self.speed = Scale(self, orient=HORIZONTAL, label="ball speed", - from_=-100, to=100) - - self.speed.pack(side=BOTTOM, fill=X) - - # The ball - self.ball = self.draw.create_oval("0i", "0i", "0.10i", "0.10i", - fill="red") - self.x = 0.05 - self.y = 0.05 - self.velocity_x = 0.3 - self.velocity_y = 0.5 - - self.draw.pack(side=LEFT) - - def moveBall(self, *args): - if (self.x > 5.0) or (self.x < 0.0): - self.velocity_x = -1.0 * self.velocity_x - if (self.y > 5.0) or (self.y < 0.0): - self.velocity_y = -1.0 * self.velocity_y - - deltax = (self.velocity_x * self.speed.get() / 100.0) - deltay = (self.velocity_y * self.speed.get() / 100.0) - self.x = self.x + deltax - self.y = self.y + deltay - - self.draw.move(self.ball, "%ri" % deltax, "%ri" % deltay) - self.after(10, self.moveBall) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - self.after(10, self.moveBall) - - -game = Pong() - -game.mainloop() diff --git a/Demo/tkinter/matt/printing-coords-of-items.py b/Demo/tkinter/matt/printing-coords-of-items.py deleted file mode 100644 index 771a60d..0000000 --- a/Demo/tkinter/matt/printing-coords-of-items.py +++ /dev/null @@ -1,61 +0,0 @@ -from tkinter import * - -# this file demonstrates the creation of widgets as part of a canvas object - -class Test(Frame): - ################################################################### - ###### Event callbacks for THE CANVAS (not the stuff drawn on it) - ################################################################### - def mouseDown(self, event): - # see if we're inside a dot. If we are, it - # gets tagged as CURRENT for free by tk. - - if not event.widget.find_withtag(CURRENT): - # there is no dot here, so we can make one, - # and bind some interesting behavior to it. - # ------ - # create a dot, and mark it as current - fred = self.draw.create_oval( - event.x - 10, event.y -10, event.x +10, event.y + 10, - fill="green") - self.draw.tag_bind(fred, "<Enter>", self.mouseEnter) - self.draw.tag_bind(fred, "<Leave>", self.mouseLeave) - self.lastx = event.x - self.lasty = event.y - - def mouseMove(self, event): - self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - ################################################################### - ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas) - ################################################################### - def mouseEnter(self, event): - # the "current" tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="red") - print(list(self.draw.coords(CURRENT))) - - def mouseLeave(self, event): - # the "current" tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="blue") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - self.draw = Canvas(self, width="5i", height="5i") - self.draw.pack(side=LEFT) - - Widget.bind(self.draw, "<1>", self.mouseDown) - Widget.bind(self.draw, "<B1-Motion>", self.mouseMove) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/radiobutton-simple.py b/Demo/tkinter/matt/radiobutton-simple.py deleted file mode 100644 index a2719b8..0000000 --- a/Demo/tkinter/matt/radiobutton-simple.py +++ /dev/null @@ -1,62 +0,0 @@ -from tkinter import * - -# This is a demo program that shows how to -# create radio buttons and how to get other widgets to -# share the information in a radio button. -# -# There are other ways of doing this too, but -# the "variable" option of radiobuttons seems to be the easiest. -# -# note how each button has a value it sets the variable to as it gets hit. - - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - - self.flavor = StringVar() - self.flavor.set("chocolate") - - self.radioframe = Frame(self) - self.radioframe.pack() - - # 'text' is the label - # 'variable' is the name of the variable that all these radio buttons share - # 'value' is the value this variable takes on when the radio button is selected - # 'anchor' makes the text appear left justified (default is centered. ick) - self.radioframe.choc = Radiobutton( - self.radioframe, text="Chocolate Flavor", - variable=self.flavor, value="chocolate", - anchor=W) - self.radioframe.choc.pack(fill=X) - - self.radioframe.straw = Radiobutton( - self.radioframe, text="Strawberry Flavor", - variable=self.flavor, value="strawberry", - anchor=W) - self.radioframe.straw.pack(fill=X) - - self.radioframe.lemon = Radiobutton( - self.radioframe, text="Lemon Flavor", - variable=self.flavor, value="lemon", - anchor=W) - self.radioframe.lemon.pack(fill=X) - - # this is a text entry that lets you type in the name of a flavor too. - self.entry = Entry(self, textvariable=self.flavor) - self.entry.pack(fill=X) - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/rubber-band-box-demo-1.py b/Demo/tkinter/matt/rubber-band-box-demo-1.py deleted file mode 100644 index 48526d8..0000000 --- a/Demo/tkinter/matt/rubber-band-box-demo-1.py +++ /dev/null @@ -1,58 +0,0 @@ -from tkinter import * - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', - background='red', - foreground='white', - height=3, - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.canvasObject = Canvas(self, width="5i", height="5i") - self.canvasObject.pack(side=LEFT) - - def mouseDown(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - self.startx = self.canvasObject.canvasx(event.x) - self.starty = self.canvasObject.canvasy(event.y) - - def mouseMotion(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - x = self.canvasObject.canvasx(event.x) - y = self.canvasObject.canvasy(event.y) - - if (self.startx != event.x) and (self.starty != event.y) : - self.canvasObject.delete(self.rubberbandBox) - self.rubberbandBox = self.canvasObject.create_rectangle( - self.startx, self.starty, x, y) - # this flushes the output, making sure that - # the rectangle makes it to the screen - # before the next event is handled - self.update_idletasks() - - def mouseUp(self, event): - self.canvasObject.delete(self.rubberbandBox) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - - # this is a "tagOrId" for the rectangle we draw on the canvas - self.rubberbandBox = None - - # and the bindings that make it work.. - Widget.bind(self.canvasObject, "<Button-1>", self.mouseDown) - Widget.bind(self.canvasObject, "<Button1-Motion>", self.mouseMotion) - Widget.bind(self.canvasObject, "<Button1-ButtonRelease>", self.mouseUp) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/rubber-line-demo-1.py b/Demo/tkinter/matt/rubber-line-demo-1.py deleted file mode 100644 index cfc4882..0000000 --- a/Demo/tkinter/matt/rubber-line-demo-1.py +++ /dev/null @@ -1,51 +0,0 @@ -from tkinter import * - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', - background='red', - foreground='white', - height=3, - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.canvasObject = Canvas(self, width="5i", height="5i") - self.canvasObject.pack(side=LEFT) - - def mouseDown(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - self.startx = self.canvasObject.canvasx(event.x) - self.starty = self.canvasObject.canvasy(event.y) - - def mouseMotion(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - x = self.canvasObject.canvasx(event.x) - y = self.canvasObject.canvasy(event.y) - - if (self.startx != event.x) and (self.starty != event.y) : - self.canvasObject.delete(self.rubberbandLine) - self.rubberbandLine = self.canvasObject.create_line( - self.startx, self.starty, x, y) - # this flushes the output, making sure that - # the rectangle makes it to the screen - # before the next event is handled - self.update_idletasks() - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - # this is a "tagOrId" for the rectangle we draw on the canvas - self.rubberbandLine = None - Widget.bind(self.canvasObject, "<Button-1>", self.mouseDown) - Widget.bind(self.canvasObject, "<Button1-Motion>", self.mouseMotion) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/slider-demo-1.py b/Demo/tkinter/matt/slider-demo-1.py deleted file mode 100644 index 687f8a3..0000000 --- a/Demo/tkinter/matt/slider-demo-1.py +++ /dev/null @@ -1,36 +0,0 @@ -from tkinter import * - -# shows how to make a slider, set and get its value under program control - - -class Test(Frame): - def print_value(self, val): - print("slider now at", val) - - def reset(self): - self.slider.set(0) - - def createWidgets(self): - self.slider = Scale(self, from_=0, to=100, - orient=HORIZONTAL, - length="3i", - label="happy slider", - command=self.print_value) - - self.reset = Button(self, text='reset slider', - command=self.reset) - - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - - self.slider.pack(side=LEFT) - self.reset.pack(side=LEFT) - self.QUIT.pack(side=LEFT, fill=BOTH) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/subclass-existing-widgets.py b/Demo/tkinter/matt/subclass-existing-widgets.py deleted file mode 100644 index ce97f35..0000000 --- a/Demo/tkinter/matt/subclass-existing-widgets.py +++ /dev/null @@ -1,28 +0,0 @@ -from tkinter import * - -# This is a program that makes a simple two button application - - -class New_Button(Button): - def callback(self): - print(self.counter) - self.counter = self.counter + 1 - -def createWidgets(top): - f = Frame(top) - f.pack() - f.QUIT = Button(f, text='QUIT', foreground='red', command=top.quit) - - f.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - f.hi_there = New_Button(f, text='Hello') - # we do this on a different line because we need to reference f.hi_there - f.hi_there.config(command=f.hi_there.callback) - f.hi_there.pack(side=LEFT) - f.hi_there.counter = 43 - - -root = Tk() -createWidgets(root) -root.mainloop() diff --git a/Demo/tkinter/matt/two-radio-groups.py b/Demo/tkinter/matt/two-radio-groups.py deleted file mode 100644 index 38b61b1..0000000 --- a/Demo/tkinter/matt/two-radio-groups.py +++ /dev/null @@ -1,110 +0,0 @@ -from tkinter import * - -# The way to think about this is that each radio button menu -# controls a different variable -- clicking on one of the -# mutually exclusive choices in a radiobutton assigns some value -# to an application variable you provide. When you define a -# radiobutton menu choice, you have the option of specifying the -# name of a varaible and value to assign to that variable when -# that choice is selected. This clever mechanism relieves you, -# the programmer, from having to write a dumb callback that -# probably wouldn't have done anything more than an assignment -# anyway. The Tkinter options for this follow their Tk -# counterparts: -# {"variable" : my_flavor_variable, "value" : "strawberry"} -# where my_flavor_variable is an instance of one of the -# subclasses of Variable, provided in Tkinter.py (there is -# StringVar(), IntVar(), DoubleVar() and BooleanVar() to choose -# from) - - - -def makePoliticalParties(var): - # make menu button - Radiobutton_button = Menubutton(mBar, text='Political Party', - underline=0) - Radiobutton_button.pack(side=LEFT, padx='2m') - - # the primary pulldown - Radiobutton_button.menu = Menu(Radiobutton_button) - - Radiobutton_button.menu.add_radiobutton(label='Republican', - variable=var, value=1) - - Radiobutton_button.menu.add('radiobutton', {'label': 'Democrat', - 'variable' : var, - 'value' : 2}) - - Radiobutton_button.menu.add('radiobutton', {'label': 'Libertarian', - 'variable' : var, - 'value' : 3}) - - var.set(2) - - # set up a pointer from the file menubutton back to the file menu - Radiobutton_button['menu'] = Radiobutton_button.menu - - return Radiobutton_button - - -def makeFlavors(var): - # make menu button - Radiobutton_button = Menubutton(mBar, text='Flavors', - underline=0) - Radiobutton_button.pack(side=LEFT, padx='2m') - - # the primary pulldown - Radiobutton_button.menu = Menu(Radiobutton_button) - - Radiobutton_button.menu.add_radiobutton(label='Strawberry', - variable=var, value='Strawberry') - - Radiobutton_button.menu.add_radiobutton(label='Chocolate', - variable=var, value='Chocolate') - - Radiobutton_button.menu.add_radiobutton(label='Rocky Road', - variable=var, value='Rocky Road') - - # choose a default - var.set("Chocolate") - - # set up a pointer from the file menubutton back to the file menu - Radiobutton_button['menu'] = Radiobutton_button.menu - - return Radiobutton_button - - -def printStuff(): - print("party is", party.get()) - print("flavor is", flavor.get()) - print() - -################################################# -#### Main starts here ... -root = Tk() - - -# make a menu bar -mBar = Frame(root, relief=RAISED, borderwidth=2) -mBar.pack(fill=X) - -# make two application variables, -# one to control each radio button set -party = IntVar() -flavor = StringVar() - -Radiobutton_button = makePoliticalParties(party) -Radiobutton_button2 = makeFlavors(flavor) - -# finally, install the buttons in the menu bar. -# This allows for scanning from one menubutton to the next. -mBar.tk_menuBar(Radiobutton_button, Radiobutton_button2) - -b = Button(root, text="print party and flavor", foreground="red", - command=printStuff) -b.pack(side=TOP) - -root.title('menu demo') -root.iconname('menu demo') - -root.mainloop() diff --git a/Demo/tkinter/matt/window-creation-more.py b/Demo/tkinter/matt/window-creation-more.py deleted file mode 100644 index 32c8b70..0000000 --- a/Demo/tkinter/matt/window-creation-more.py +++ /dev/null @@ -1,35 +0,0 @@ -from tkinter import * - -# this shows how to create a new window with a button in it -# that can create new windows - -class Test(Frame): - def printit(self): - print("hi") - - def makeWindow(self): - fred = Toplevel() - fred.label = Button(fred, - text="This is window number %d." % self.windownum, - command=self.makeWindow) - fred.label.pack() - self.windownum = self.windownum + 1 - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - self.hi_there = Button(self, text='Make a New Window', - command=self.makeWindow) - self.hi_there.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.windownum = 0 - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/window-creation-simple.py b/Demo/tkinter/matt/window-creation-simple.py deleted file mode 100644 index f5e6230..0000000 --- a/Demo/tkinter/matt/window-creation-simple.py +++ /dev/null @@ -1,31 +0,0 @@ -from tkinter import * - -# this shows how to spawn off new windows at a button press - -class Test(Frame): - def printit(self): - print("hi") - - def makeWindow(self): - fred = Toplevel() - fred.label = Label(fred, text="Here's a new window") - fred.label.pack() - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - - self.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - self.hi_there = Button(self, text='Make a New Window', - command=self.makeWindow) - self.hi_there.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/window-creation-w-location.py b/Demo/tkinter/matt/window-creation-w-location.py deleted file mode 100644 index 9f82367..0000000 --- a/Demo/tkinter/matt/window-creation-w-location.py +++ /dev/null @@ -1,45 +0,0 @@ -from tkinter import * - -import sys -##sys.path.append("/users/mjc4y/projects/python/tkinter/utils") -##from TkinterUtils import * - -# this shows how to create a new window with a button in it that -# can create new windows - -class QuitButton(Button): - def __init__(self, master, *args, **kwargs): - if "text" not in kwargs: - kwargs["text"] = "QUIT" - if "command" not in kwargs: - kwargs["command"] = master.quit - Button.__init__(self, master, *args, **kwargs) - -class Test(Frame): - def makeWindow(self, *args): - fred = Toplevel() - - fred.label = Canvas (fred, width="2i", height="2i") - - fred.label.create_line("0", "0", "2i", "2i") - fred.label.create_line("0", "2i", "2i", "0") - fred.label.pack() - - ##centerWindow(fred, self.master) - - def createWidgets(self): - self.QUIT = QuitButton(self) - self.QUIT.pack(side=LEFT, fill=BOTH) - - self.makeWindow = Button(self, text='Make a New Window', - width=50, height=20, - command=self.makeWindow) - self.makeWindow.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/ttk/combo_themes.py b/Demo/tkinter/ttk/combo_themes.py deleted file mode 100644 index 45eee2d..0000000 --- a/Demo/tkinter/ttk/combo_themes.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Ttk Theme Selector. - -Although it is a theme selector, you won't notice many changes since -there is only a combobox and a frame around. -""" -from tkinter import ttk - -class App(ttk.Frame): - def __init__(self): - ttk.Frame.__init__(self) - - self.style = ttk.Style() - self._setup_widgets() - - def _change_theme(self, event): - if event.widget.current(): # value #0 is not a theme - newtheme = event.widget.get() - # change to the new theme and refresh all the widgets - self.style.theme_use(newtheme) - - def _setup_widgets(self): - themes = list(self.style.theme_names()) - themes.insert(0, "Pick a theme") - # Create a readonly Combobox which will display 4 values at max, - # which will cause it to create a scrollbar if there are more - # than 4 values in total. - themes_combo = ttk.Combobox(self, values=themes, state="readonly", - height=4) - themes_combo.set(themes[0]) # sets the combobox value to "Pick a theme" - # Combobox widget generates a <<ComboboxSelected>> virtual event - # when the user selects an element. This event is generated after - # the listbox is unposted (after you select an item, the combobox's - # listbox disappears, then it is said that listbox is now unposted). - themes_combo.bind("<<ComboboxSelected>>", self._change_theme) - themes_combo.pack(fill='x') - - self.pack(fill='both', expand=1) - - -def main(): - app = App() - app.master.title("Ttk Combobox") - app.mainloop() - -if __name__ == "__main__": - main() diff --git a/Demo/tkinter/ttk/dirbrowser.py b/Demo/tkinter/ttk/dirbrowser.py deleted file mode 100644 index bacddb5..0000000 --- a/Demo/tkinter/ttk/dirbrowser.py +++ /dev/null @@ -1,93 +0,0 @@ -"""A directory browser using Ttk Treeview. - -Based on the demo found in Tk 8.5 library/demos/browse -""" -import os -import glob -import tkinter -from tkinter import ttk - -def populate_tree(tree, node): - if tree.set(node, "type") != 'directory': - return - - path = tree.set(node, "fullpath") - tree.delete(*tree.get_children(node)) - - parent = tree.parent(node) - special_dirs = [] if parent else glob.glob('.') + glob.glob('..') - - for p in special_dirs + os.listdir(path): - ptype = None - p = os.path.join(path, p).replace('\\', '/') - if os.path.isdir(p): ptype = "directory" - elif os.path.isfile(p): ptype = "file" - - fname = os.path.split(p)[1] - id = tree.insert(node, "end", text=fname, values=[p, ptype]) - - if ptype == 'directory': - if fname not in ('.', '..'): - tree.insert(id, 0, text="dummy") - tree.item(id, text=fname) - elif ptype == 'file': - size = os.stat(p).st_size - tree.set(id, "size", "%d bytes" % size) - - -def populate_roots(tree): - dir = os.path.abspath('.').replace('\\', '/') - node = tree.insert('', 'end', text=dir, values=[dir, "directory"]) - populate_tree(tree, node) - -def update_tree(event): - tree = event.widget - populate_tree(tree, tree.focus()) - -def change_dir(event): - tree = event.widget - node = tree.focus() - if tree.parent(node): - path = os.path.abspath(tree.set(node, "fullpath")) - if os.path.isdir(path): - os.chdir(path) - tree.delete(tree.get_children('')) - populate_roots(tree) - -def autoscroll(sbar, first, last): - """Hide and show scrollbar as needed.""" - first, last = float(first), float(last) - if first <= 0 and last >= 1: - sbar.grid_remove() - else: - sbar.grid() - sbar.set(first, last) - -root = tkinter.Tk() - -vsb = ttk.Scrollbar(orient="vertical") -hsb = ttk.Scrollbar(orient="horizontal") - -tree = ttk.Treeview(columns=("fullpath", "type", "size"), - displaycolumns="size", yscrollcommand=lambda f, l: autoscroll(vsb, f, l), - xscrollcommand=lambda f, l:autoscroll(hsb, f, l)) - -vsb['command'] = tree.yview -hsb['command'] = tree.xview - -tree.heading("#0", text="Directory Structure", anchor='w') -tree.heading("size", text="File Size", anchor='w') -tree.column("size", stretch=0, width=100) - -populate_roots(tree) -tree.bind('<<TreeviewOpen>>', update_tree) -tree.bind('<Double-Button-1>', change_dir) - -# Arrange the tree and its scrollbars in the toplevel -tree.grid(column=0, row=0, sticky='nswe') -vsb.grid(column=1, row=0, sticky='ns') -hsb.grid(column=0, row=1, sticky='ew') -root.grid_columnconfigure(0, weight=1) -root.grid_rowconfigure(0, weight=1) - -root.mainloop() diff --git a/Demo/tkinter/ttk/img/close.gif b/Demo/tkinter/ttk/img/close.gif Binary files differdeleted file mode 100644 index 18cf6c7..0000000 --- a/Demo/tkinter/ttk/img/close.gif +++ /dev/null diff --git a/Demo/tkinter/ttk/img/close_active.gif b/Demo/tkinter/ttk/img/close_active.gif Binary files differdeleted file mode 100644 index db7f392..0000000 --- a/Demo/tkinter/ttk/img/close_active.gif +++ /dev/null diff --git a/Demo/tkinter/ttk/img/close_pressed.gif b/Demo/tkinter/ttk/img/close_pressed.gif Binary files differdeleted file mode 100644 index 5616954..0000000 --- a/Demo/tkinter/ttk/img/close_pressed.gif +++ /dev/null diff --git a/Demo/tkinter/ttk/listbox_scrollcmd.py b/Demo/tkinter/ttk/listbox_scrollcmd.py deleted file mode 100644 index 05faf63..0000000 --- a/Demo/tkinter/ttk/listbox_scrollcmd.py +++ /dev/null @@ -1,37 +0,0 @@ -"""Sample taken from: http://www.tkdocs.com/tutorial/morewidgets.html and -converted to Python, mainly to demonstrate xscrollcommand option. - -grid [tk::listbox .l -yscrollcommand ".s set" -height 5] -column 0 -row 0 -sticky nwes -grid [ttk::scrollbar .s -command ".l yview" -orient vertical] -column 1 -row 0 -sticky ns -grid [ttk::label .stat -text "Status message here" -anchor w] -column 0 -row 1 -sticky we -grid [ttk::sizegrip .sz] -column 1 -row 1 -sticky se -grid columnconfigure . 0 -weight 1; grid rowconfigure . 0 -weight 1 -for {set i 0} {$i<100} {incr i} { - .l insert end "Line $i of 100" - } -""" -import tkinter -from tkinter import ttk - -root = tkinter.Tk() - -l = tkinter.Listbox(height=5) -l.grid(column=0, row=0, sticky='nwes') - -s = ttk.Scrollbar(command=l.yview, orient='vertical') -l['yscrollcommand'] = s.set -s.grid(column=1, row=0, sticky="ns") - -stat = ttk.Label(text="Status message here", anchor='w') -stat.grid(column=0, row=1, sticky='we') - -sz = ttk.Sizegrip() -sz.grid(column=1, row=1, sticky='se') - -root.grid_columnconfigure(0, weight=1) -root.grid_rowconfigure(0, weight=1) - -for i in range(100): - l.insert('end', "Line %d of 100" % i) - -root.mainloop() diff --git a/Demo/tkinter/ttk/mac_searchentry.py b/Demo/tkinter/ttk/mac_searchentry.py deleted file mode 100644 index 97b1eaf..0000000 --- a/Demo/tkinter/ttk/mac_searchentry.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Mac style search widget - -Translated from Tcl code by Schelte Bron, http://wiki.tcl.tk/18188 -""" -import tkinter -from tkinter import ttk - -root = tkinter.Tk() - -data = """ -R0lGODlhKgAaAOfnAFdZVllbWFpcWVtdWlxeW11fXF9hXmBiX2ZnZWhpZ2lraGxua25wbXJ0 -cXR2c3V3dHZ4dXh6d3x+e31/fH6AfYSGg4eJhoiKh4qMiYuNio2PjHmUqnqVq3yXrZGTkJKU -kX+asJSWk32cuJWXlIGcs5aYlX6euZeZloOetZial4SftpqbmIWgt4GhvYahuIKivpudmYei -uYOjv5yem4ijuoSkwIWlwYmlu56gnYamwp+hnoenw4unvaCin4ioxJCnuZykrImpxZmlsoaq -zI2pv6KkoZGouoqqxpqms4erzaOloo6qwYurx5Kqu5untIiszqSmo5CrwoysyJeqtpOrvJyo -tZGsw42typSsvaaopZKtxJWtvp6qt4+uy6epppOuxZCvzKiqp5quuZSvxoyx06mrqJWwx42y -1JKxzpmwwaqsqZaxyI6z1ZqxwqutqpOzz4+01qyuq56yvpizypS00Jm0y5W10Zq1zJa20rCy -rpu3zqizwbGzr6C3yZy4z7K0saG4yp250LO1sqK5y5660Z+70qO7zKy4xaC806S8zba4taG9 -1KW9zq66x6+7yLi6t6S/1rC8yrm7uLO8xLG9y7q8ubS9xabB2anB07K+zLW+xrO/za7CzrTA -zrjAyLXBz77BvbbC0K/G2LjD0bnE0rLK28TGw8bIxcLL07vP28HN28rMycvOyr/T38DU4cnR -2s/RztHT0NLU0cTY5MrW5MvX5dHX2c3Z59bY1dPb5Nbb3dLe7Nvd2t3f3NXh797g3d3j5dnl -9OPl4eTm4+Ln6tzo9uXn5Obo5eDp8efp5uHq8uXq7ejq5+nr6OPs9Ovu6unu8O3v6+vw8+7w -7ezx9O/x7vDy7/Hz8O/19/P18vT38/L3+fb49Pf59vX6/fj69/b7/vn7+Pr8+ff9//v9+vz/ -+/7//P////////////////////////////////////////////////////////////////// -/////////////////////////////////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJZAD/ACwC -AAIAKAAWAAAI/gD/CRz4bwUGCg8eQFjIsGHDBw4iTLAQgqBFgisuePCiyJOpUyBDihRpypMi -Lx8qaLhIMIyGFZ5sAUsmjZrNmzhzWpO2DJgtTysqfGDpxoMbW8ekeQsXzty4p1CjRjUXrps3 -asJsuclQ4uKKSbamMR3n1JzZs2jRkh1HzuxVXX8y4CDYAwqua+DInVrRwMGJU2kDp31KThy1 -XGWGDlxhi1rTPAUICBBAoEAesoIzn6Vm68MKgVAUHftmzhOCBCtQwQKSoABgzZnJdSMmyIPA -FbCotdUQAIhNa9B6DPCAGbZac+SowVIMRVe4pwkA4GpqDlwuAAmMZx4nTtfnf1mO5JEDNy46 -MHJkxQEDgKC49rPjwC0bqGaZuOoZAKjBPE4NgAzUvYcWOc0QZF91imAnCDHJ5JFAAJN0I2Ba -4iRDUC/gOEVNDwIUcEABCAgAAATUTIgWOMBYRFp80ghiAQIIVAAEAwJIYI2JZnUji0XSYAYO -NcsQA8wy0hCTwAASXGOiONFcxAtpTokTHznfiLMNMAkcAMuE43jDC0vLeGOWe2R5o4sn1LgH -GzkWsvTPMgEOaA433Ag4TjjMuDkQMNi0tZ12sqWoJ0HATMPNffAZZ6U0wLAyqJ62RGoLLrhI -aqmlpzwaEAAh+QQJZAD/ACwAAAAAKgAaAAAI/gD/CRw40JEhQoEC+fGjcOHCMRAjRkxDsKLF -f5YcAcID582ZjyBDJhmZZIjJIUySEDHiBMhFghrtdNnRAgSHmzhz6sTZQcSLITx+CHn5bxSk -Nz5MCMGy55CjTVCjbuJEtSrVQ3uwqDBRQwrFi476SHHxow8qXcemVbPGtm21t3CnTaP27Jgu -VHtuiIjBsuImQkRiiEEFTNo2cOTMKV7MuLE5cN68QUOGSgwKG1EqJqJDY8+rZt8UjxtNunTj -cY3DgZOWS46KIFgGjiI0ZIsqaqNNjWjgYMUpx8Adc3v2aosNMAI1DbqyI9WycOb4IAggQEAB -A3lQBxet/TG4cMpI/tHwYeSfIzxM0uTKNs7UgAQrYL1akaDA7+3bueVqY4NJlUhIcQLNYx8E -AIQ01mwjTQ8DeNAdfouNA8440GBCQxJY3MEGD6p4Y844CQCAizcSgpMLAAlAuJ03qOyQRBR3 -nEHEK+BMGKIui4kDDAAIPKiiYuSYSMQQRCDCxhiziPMYBgDkEaEaAGQA3Y+MjUPOLFoMoUUh -cKxRC4ngeILiH8Qkk0cCAUzSDZWpzbLEE1EwggcYqWCj2DNADFDAAQUgIAAAEFDDJmPYqNJF -F1s4cscTmCDjDTjdSPOHBQggUAEQDAgggTWDPoYMJkFoUdRmddyyjWLeULMMMcAsIw0x4wkM -IME1g25zyxpHxFYUHmyIggw4H4ojITnfiLMNMAkcAAub4BQjihRdDGTJHmvc4Qo1wD6Imje6 -eILbj+BQ4wqu5Q3ECSJ0FOKKMtv4mBg33Pw4zjbKuBIIE1xYpIkhdQQiyi7OtAucj6dt48wu -otQhBRa6VvSJIRwhIkotvgRTzMUYZ6xxMcj4QkspeKDxxRhEmUfIHWjAgQcijEDissuXvCyz -zH7Q8YQURxDhUsn/bCInR3AELfTQZBRt9BBJkCGFFVhMwTNBlnBCSCGEIJQQIAklZMXWRBAR -RRRWENHwRQEBADs=""" - - -s1 = tkinter.PhotoImage("search1", data=data, format="gif -index 0") -s2 = tkinter.PhotoImage("search2", data=data, format="gif -index 1") - -style = ttk.Style() - -style.element_create("Search.field", "image", "search1", - ("focus", "search2"), border=[22, 7, 14], sticky="ew") - -style.layout("Search.entry", [ - ("Search.field", {"sticky": "nswe", "border": 1, "children": - [("Entry.padding", {"sticky": "nswe", "children": - [("Entry.textarea", {"sticky": "nswe"})] - })] - })] -) - -style.configure("Search.entry", background="#b2b2b2") - -root.configure(background="#b2b2b2") - -e1 = ttk.Entry(style="Search.entry", width=20) -e2 = ttk.Entry(style="Search.entry", width=20) - -e1.grid(padx=10, pady=10) -e2.grid(padx=10, pady=10) - -root.mainloop() diff --git a/Demo/tkinter/ttk/notebook_closebtn.py b/Demo/tkinter/ttk/notebook_closebtn.py deleted file mode 100644 index 6e65f09..0000000 --- a/Demo/tkinter/ttk/notebook_closebtn.py +++ /dev/null @@ -1,78 +0,0 @@ -"""A Ttk Notebook with close buttons. - -Based on an example by patthoyts, http://paste.tclers.tk/896 -""" -import os -import tkinter -from tkinter import ttk - -root = tkinter.Tk() - -imgdir = os.path.join(os.path.dirname(__file__), 'img') -i1 = tkinter.PhotoImage("img_close", file=os.path.join(imgdir, 'close.gif')) -i2 = tkinter.PhotoImage("img_closeactive", - file=os.path.join(imgdir, 'close_active.gif')) -i3 = tkinter.PhotoImage("img_closepressed", - file=os.path.join(imgdir, 'close_pressed.gif')) - -style = ttk.Style() - -style.element_create("close", "image", "img_close", - ("active", "pressed", "!disabled", "img_closepressed"), - ("active", "!disabled", "img_closeactive"), border=8, sticky='') - -style.layout("ButtonNotebook", [("ButtonNotebook.client", {"sticky": "nswe"})]) -style.layout("ButtonNotebook.Tab", [ - ("ButtonNotebook.tab", {"sticky": "nswe", "children": - [("ButtonNotebook.padding", {"side": "top", "sticky": "nswe", - "children": - [("ButtonNotebook.focus", {"side": "top", "sticky": "nswe", - "children": - [("ButtonNotebook.label", {"side": "left", "sticky": ''}), - ("ButtonNotebook.close", {"side": "left", "sticky": ''})] - })] - })] - })] -) - -def btn_press(event): - x, y, widget = event.x, event.y, event.widget - elem = widget.identify(x, y) - index = widget.index("@%d,%d" % (x, y)) - - if "close" in elem: - widget.state(['pressed']) - widget.pressed_index = index - -def btn_release(event): - x, y, widget = event.x, event.y, event.widget - - if not widget.instate(['pressed']): - return - - elem = widget.identify(x, y) - index = widget.index("@%d,%d" % (x, y)) - - if "close" in elem and widget.pressed_index == index: - widget.forget(index) - widget.event_generate("<<NotebookClosedTab>>") - - widget.state(["!pressed"]) - widget.pressed_index = None - - -root.bind_class("TNotebook", "<ButtonPress-1>", btn_press, True) -root.bind_class("TNotebook", "<ButtonRelease-1>", btn_release) - -# create a ttk notebook with our custom style, and add some tabs to it -nb = ttk.Notebook(width=200, height=200, style="ButtonNotebook") -nb.pressed_index = None -f1 = tkinter.Frame(nb, background="red") -f2 = tkinter.Frame(nb, background="green") -f3 = tkinter.Frame(nb, background="blue") -nb.add(f1, text='Red', padding=3) -nb.add(f2, text='Green', padding=3) -nb.add(f3, text='Blue', padding=3) -nb.pack(expand=1, fill='both') - -root.mainloop() diff --git a/Demo/tkinter/ttk/plastik_theme.py b/Demo/tkinter/ttk/plastik_theme.py deleted file mode 100644 index 9c68bb5..0000000 --- a/Demo/tkinter/ttk/plastik_theme.py +++ /dev/null @@ -1,268 +0,0 @@ -"""This demonstrates good part of the syntax accepted by theme_create. - -This is a translation of plastik.tcl to python. -You will need the images used by the plastik theme to test this. The -images (and other tile themes) can be retrived by doing: - -$ cvs -z3 -d:pserver:anonymous@tktable.cvs.sourceforge.net:/cvsroot/tktable \ - co tile-themes - -To test this module you should do, for example: - -import Tkinter -import plastik_theme - -root = Tkinter.Tk() -plastik_theme.install(plastik_image_dir) -... - -Where plastik_image_dir contains the path to the images directory used by -the plastik theme, something like: tile-themes/plastik/plastik -""" -import os -import glob -from tkinter import ttk, PhotoImage - -__all__ = ['install'] - -colors = { - "frame": "#efefef", - "disabledfg": "#aaaaaa", - "selectbg": "#657a9e", - "selectfg": "#ffffff" - } - -imgs = {} -def _load_imgs(imgdir): - imgdir = os.path.expanduser(imgdir) - if not os.path.isdir(imgdir): - raise Exception("%r is not a directory, can't load images" % imgdir) - for f in glob.glob("%s/*.gif" % imgdir): - img = os.path.split(f)[1] - name = img[:-4] - imgs[name] = PhotoImage(name, file=f, format="gif89") - -def install(imgdir): - _load_imgs(imgdir) - style = ttk.Style() - style.theme_create("plastik", "default", settings={ - ".": { - "configure": - {"background": colors['frame'], - "troughcolor": colors['frame'], - "selectbackground": colors['selectbg'], - "selectforeground": colors['selectfg'], - "fieldbackground": colors['frame'], - "font": "TkDefaultFont", - "borderwidth": 1}, - "map": {"foreground": [("disabled", colors['disabledfg'])]} - }, - - "Vertical.TScrollbar": {"layout": [ - ("Vertical.Scrollbar.uparrow", {"side": "top", "sticky": ''}), - ("Vertical.Scrollbar.downarrow", {"side": "bottom", "sticky": ''}), - ("Vertical.Scrollbar.uparrow", {"side": "bottom", "sticky": ''}), - ("Vertical.Scrollbar.trough", {"sticky": "ns", "children": - [("Vertical.Scrollbar.thumb", {"expand": 1, "unit": 1, - "children": [("Vertical.Scrollbar.grip", {"sticky": ''})] - })] - })] - }, - - "Horizontal.TScrollbar": {"layout": [ - ("Horizontal.Scrollbar.leftarrow", {"side": "left", "sticky": ''}), - ("Horizontal.Scrollbar.rightarrow", - {"side": "right", "sticky": ''}), - ("Horizontal.Scrollbar.leftarrow", - {"side": "right", "sticky": ''}), - ("Horizontal.Scrollbar.trough", {"sticky": "ew", "children": - [("Horizontal.Scrollbar.thumb", {"expand": 1, "unit": 1, - "children": [("Horizontal.Scrollbar.grip", {"sticky": ''})] - })] - })] - }, - - "TButton": { - "configure": {"width": 10, "anchor": "center"}, - "layout": [ - ("Button.button", {"children": - [("Button.focus", {"children": - [("Button.padding", {"children": - [("Button.label", {"side": "left", "expand": 1})] - })] - })] - }) - ] - }, - - "Toolbutton": { - "configure": {"anchor": "center"}, - "layout": [ - ("Toolbutton.border", {"children": - [("Toolbutton.button", {"children": - [("Toolbutton.padding", {"children": - [("Toolbutton.label", {"side":"left", "expand":1})] - })] - })] - }) - ] - }, - - "TMenubutton": {"layout": [ - ("Menubutton.button", {"children": - [("Menubutton.indicator", {"side": "right"}), - ("Menubutton.focus", {"children": - [("Menubutton.padding", {"children": - [("Menubutton.label", {"side": "left", "expand": 1})] - })] - })] - })] - }, - - "TNotebook": {"configure": {"tabmargins": [0, 2, 0, 0]}}, - "TNotebook.tab": { - "configure": {"padding": [6, 2, 6, 2], "expand": [0, 0, 2]}, - "map": {"expand": [("selected", [1, 2, 4, 2])]} - }, - "Treeview": {"configure": {"padding": 0}}, - - # elements - "Button.button": {"element create": - ("image", 'button-n', - ("pressed", 'button-p'), ("active", 'button-h'), - {"border": [4, 10], "padding": 4, "sticky":"ewns"} - ) - }, - - "Toolbutton.button": {"element create": - ("image", 'tbutton-n', - ("selected", 'tbutton-p'), ("pressed", 'tbutton-p'), - ("active", 'tbutton-h'), - {"border": [4, 9], "padding": 3, "sticky": "news"} - ) - }, - - "Checkbutton.indicator": {"element create": - ("image", 'check-nu', - ('active', 'selected', 'check-hc'), - ('pressed', 'selected', 'check-pc'), - ('active', 'check-hu'), - ("selected", 'check-nc'), - {"sticky": ''} - ) - }, - - "Radiobutton.indicator": {"element create": - ("image", 'radio-nu', - ('active', 'selected', 'radio-hc'), - ('pressed', 'selected', 'radio-pc'), - ('active', 'radio-hu'), ('selected', 'radio-nc'), - {"sticky": ''} - ) - }, - - "Horizontal.Scrollbar.thumb": {"element create": - ("image", 'hsb-n', {"border": 3, "sticky": "ew"}) - }, - - "Horizontal.Scrollbar.grip": {"element create": ("image", 'hsb-g')}, - "Horizontal.Scrollbar.trough": {"element create": ("image", 'hsb-t')}, - "Vertical.Scrollbar.thumb": {"element create": - ("image", 'vsb-n', {"border": 3, "sticky": "ns"}) - }, - "Vertical.Scrollbar.grip": {"element create": ("image", 'vsb-g')}, - "Vertical.Scrollbar.trough": {"element create": ("image", 'vsb-t')}, - "Scrollbar.uparrow": {"element create": - ("image", 'arrowup-n', ("pressed", 'arrowup-p'), {"sticky": ''}) - }, - "Scrollbar.downarrow": {"element create": - ("image", 'arrowdown-n', - ("pressed", 'arrowdown-p'), {'sticky': ''}) - }, - "Scrollbar.leftarrow": {"element create": - ("image", 'arrowleft-n', - ("pressed", 'arrowleft-p'), {'sticky': ''}) - }, - "Scrollbar.rightarrow": {"element create": - ("image", 'arrowright-n', ("pressed", 'arrowright-p'), - {'sticky': ''}) - }, - - "Horizontal.Scale.slider": {"element create": - ("image", 'hslider-n', {'sticky': ''}) - }, - "Horizontal.Scale.trough": {"element create": - ("image", 'hslider-t', {'border': 1, 'padding': 0}) - }, - "Vertical.Scale.slider": {"element create": - ("image", 'vslider-n', {'sticky': ''}) - }, - "Vertical.Scale.trough": {"element create": - ("image", 'vslider-t', {'border': 1, 'padding': 0}) - }, - - "Entry.field": {"element create": - ("image", 'entry-n', - ("focus", 'entry-f'), - {'border': 2, 'padding': [3, 4], 'sticky': 'news'} - ) - }, - - "Labelframe.border": {"element create": - ("image", 'border', {'border': 4, 'padding': 4, 'sticky': 'news'}) - }, - - "Menubutton.button": {"element create": - ("image", 'combo-r', - ('active', 'combo-ra'), - {'sticky': 'news', 'border': [4, 6, 24, 15], - 'padding': [4, 4, 5]} - ) - }, - "Menubutton.indicator": {"element create": - ("image", 'arrow-d', {"sticky": "e", "border": [15, 0, 0, 0]}) - }, - - "Combobox.field": {"element create": - ("image", 'combo-n', - ('readonly', 'active', 'combo-ra'), - ('focus', 'active', 'combo-fa'), - ('active', 'combo-a'), ('!readonly', 'focus', 'combo-f'), - ('readonly', 'combo-r'), - {'border': [4, 6, 24, 15], 'padding': [4, 4, 5], - 'sticky': 'news'} - ) - }, - "Combobox.downarrow": {"element create": - ("image", 'arrow-d', {'sticky': 'e', 'border': [15, 0, 0, 0]}) - }, - - "Notebook.client": {"element create": - ("image", 'notebook-c', {'border': 4}) - }, - "Notebook.tab": {"element create": - ("image", 'notebook-tn', - ("selected", 'notebook-ts'), ("active", 'notebook-ta'), - {'padding': [0, 2, 0, 0], 'border': [4, 10, 4, 10]} - ) - }, - - "Progressbar.trough": {"element create": - ("image", 'hprogress-t', {'border': 2}) - }, - "Horizontal.Progressbar.pbar": {"element create": - ("image", 'hprogress-b', {'border': [2, 9]}) - }, - "Vertical.Progressbar.pbar": {"element create": - ("image", 'vprogress-b', {'border': [9, 2]}) - }, - - "Treeheading.cell": {"element create": - ("image", 'tree-n', - ("pressed", 'tree-p'), - {'border': [4, 10], 'padding': 4, 'sticky': 'news'} - ) - } - - }) - style.theme_use("plastik") diff --git a/Demo/tkinter/ttk/roundframe.py b/Demo/tkinter/ttk/roundframe.py deleted file mode 100644 index ce3685a..0000000 --- a/Demo/tkinter/ttk/roundframe.py +++ /dev/null @@ -1,111 +0,0 @@ -"""Ttk Frame with rounded corners. - -Based on an example by Bryan Oakley, found at: http://wiki.tcl.tk/20152""" -import tkinter -from tkinter import ttk - -root = tkinter.Tk() - -img1 = tkinter.PhotoImage("frameFocusBorder", data=""" -R0lGODlhQABAAPcAAHx+fMTCxKSipOTi5JSSlNTS1LSytPTy9IyKjMzKzKyq -rOzq7JyanNza3Ly6vPz6/ISChMTGxKSmpOTm5JSWlNTW1LS2tPT29IyOjMzO -zKyurOzu7JyenNze3Ly+vPz+/OkAKOUA5IEAEnwAAACuQACUAAFBAAB+AFYd -QAC0AABBAAB+AIjMAuEEABINAAAAAHMgAQAAAAAAAAAAAKjSxOIEJBIIpQAA -sRgBMO4AAJAAAHwCAHAAAAUAAJEAAHwAAP+eEP8CZ/8Aif8AAG0BDAUAAJEA -AHwAAIXYAOfxAIESAHwAAABAMQAbMBZGMAAAIEggJQMAIAAAAAAAfqgaXESI -5BdBEgB+AGgALGEAABYAAAAAAACsNwAEAAAMLwAAAH61MQBIAABCM8B+AAAU -AAAAAAAApQAAsf8Brv8AlP8AQf8Afv8AzP8A1P8AQf8AfgAArAAABAAADAAA -AACQDADjAAASAAAAAACAAADVABZBAAB+ALjMwOIEhxINUAAAANIgAOYAAIEA -AHwAAGjSAGEEABYIAAAAAEoBB+MAAIEAAHwCACABAJsAAFAAAAAAAGjJAGGL -AAFBFgB+AGmIAAAQAABHAAB+APQoAOE/ABIAAAAAAADQAADjAAASAAAAAPiF -APcrABKDAAB8ABgAGO4AAJAAqXwAAHAAAAUAAJEAAHwAAP8AAP8AAP8AAP8A -AG0pIwW3AJGSAHx8AEocI/QAAICpAHwAAAA0SABk6xaDEgB8AAD//wD//wD/ -/wD//2gAAGEAABYAAAAAAAC0/AHj5AASEgAAAAA01gBkWACDTAB8AFf43PT3 -5IASEnwAAOAYd+PuMBKQTwB8AGgAEGG35RaSEgB8AOj/NOL/ZBL/gwD/fMkc -q4sA5UGpEn4AAIg02xBk/0eD/358fx/4iADk5QASEgAAAALnHABkAACDqQB8 -AMyINARkZA2DgwB8fBABHL0AAEUAqQAAAIAxKOMAPxIwAAAAAIScAOPxABIS -AAAAAIIAnQwA/0IAR3cAACwAAAAAQABAAAAI/wA/CBxIsKDBgwgTKlzIsKFD -gxceNnxAsaLFixgzUrzAsWPFCw8kDgy5EeQDkBxPolypsmXKlx1hXnS48UEH -CwooMCDAgIJOCjx99gz6k+jQnkWR9lRgYYDJkAk/DlAgIMICZlizat3KtatX -rAsiCNDgtCJClQkoFMgqsu3ArBkoZDgA8uDJAwk4bGDmtm9BZgcYzK078m4D -Cgf4+l0skNkGCg3oUhR4d4GCDIoZM2ZWQMECyZQvLMggIbPmzQIyfCZ5YcME -AwFMn/bLLIKBCRtMHljQQcDV2ZqZTRDQYfWFAwMqUJANvC8zBhUWbDi5YUAB -Bsybt2VGoUKH3AcmdP+Im127xOcJih+oXsEDdvOLuQfIMGBD9QwBlsOnzcBD -hfrsuVfefgzJR599A+CnH4Hb9fcfgu29x6BIBgKYYH4DTojQc/5ZGGGGGhpU -IYIKghgiQRw+GKCEJxZIwXwWlthiQyl6KOCMLsJIIoY4LlQjhDf2mNCI9/Eo -5IYO2sjikX+9eGCRCzL5V5JALillY07GaOSVb1G5ookzEnlhlFx+8OOXZb6V -5Y5kcnlmckGmKaaMaZrpJZxWXjnnlmW++WGdZq5ZXQEetKmnlxPgl6eUYhJq -KKOI0imnoNbF2ScFHQJJwW99TsBAAAVYWEAAHEQAZoi1cQDqAAeEV0EACpT/ -JqcACgRQAW6uNWCbYKcyyEwGDBgQwa2tTlBBAhYIQMFejC5AgQAWJNDABK3y -loEDEjCgV6/aOcYBAwp4kIF6rVkXgAEc8IQZVifCBRQHGqya23HGIpsTBgSU -OsFX/PbrVVjpYsCABA4kQCxHu11ogAQUIOAwATpBLDFQFE9sccUYS0wAxD5h -4DACFEggbAHk3jVBA/gtTIHHEADg8sswxyzzzDQDAAEECGAQsgHiTisZResN -gLIHBijwLQEYePzx0kw37fTSSjuMr7ZMzfcgYZUZi58DGsTKwbdgayt22GSP -bXbYY3MggQIaONDzAJ8R9kFlQheQQAAOWGCAARrwdt23Bn8H7vfggBMueOEG -WOBBAAkU0EB9oBGUdXIFZJBABAEEsPjmmnfO+eeeh/55BBEk0Ph/E8Q9meQq -bbDABAN00EADFRRQ++2254777rr3jrvjFTTQwQCpz7u6QRut5/oEzA/g/PPQ -Ry/99NIz//oGrZpUUEAAOw==""") - -img2 = tkinter.PhotoImage("frameBorder", data=""" -R0lGODlhQABAAPcAAHx+fMTCxKSipOTi5JSSlNTS1LSytPTy9IyKjMzKzKyq -rOzq7JyanNza3Ly6vPz6/ISChMTGxKSmpOTm5JSWlNTW1LS2tPT29IyOjMzO -zKyurOzu7JyenNze3Ly+vPz+/OkAKOUA5IEAEnwAAACuQACUAAFBAAB+AFYd -QAC0AABBAAB+AIjMAuEEABINAAAAAHMgAQAAAAAAAAAAAKjSxOIEJBIIpQAA -sRgBMO4AAJAAAHwCAHAAAAUAAJEAAHwAAP+eEP8CZ/8Aif8AAG0BDAUAAJEA -AHwAAIXYAOfxAIESAHwAAABAMQAbMBZGMAAAIEggJQMAIAAAAAAAfqgaXESI -5BdBEgB+AGgALGEAABYAAAAAAACsNwAEAAAMLwAAAH61MQBIAABCM8B+AAAU -AAAAAAAApQAAsf8Brv8AlP8AQf8Afv8AzP8A1P8AQf8AfgAArAAABAAADAAA -AACQDADjAAASAAAAAACAAADVABZBAAB+ALjMwOIEhxINUAAAANIgAOYAAIEA -AHwAAGjSAGEEABYIAAAAAEoBB+MAAIEAAHwCACABAJsAAFAAAAAAAGjJAGGL -AAFBFgB+AGmIAAAQAABHAAB+APQoAOE/ABIAAAAAAADQAADjAAASAAAAAPiF -APcrABKDAAB8ABgAGO4AAJAAqXwAAHAAAAUAAJEAAHwAAP8AAP8AAP8AAP8A -AG0pIwW3AJGSAHx8AEocI/QAAICpAHwAAAA0SABk6xaDEgB8AAD//wD//wD/ -/wD//2gAAGEAABYAAAAAAAC0/AHj5AASEgAAAAA01gBkWACDTAB8AFf43PT3 -5IASEnwAAOAYd+PuMBKQTwB8AGgAEGG35RaSEgB8AOj/NOL/ZBL/gwD/fMkc -q4sA5UGpEn4AAIg02xBk/0eD/358fx/4iADk5QASEgAAAALnHABkAACDqQB8 -AMyINARkZA2DgwB8fBABHL0AAEUAqQAAAIAxKOMAPxIwAAAAAIScAOPxABIS -AAAAAIIAnQwA/0IAR3cAACwAAAAAQABAAAAI/wA/CBxIsKDBgwgTKlzIsKFD -gxceNnxAsaLFixgzUrzAsWPFCw8kDgy5EeQDkBxPolypsmXKlx1hXnS48UEH -CwooMCDAgIJOCjx99gz6k+jQnkWR9lRgYYDJkAk/DlAgIMICkVgHLoggQIPT -ighVJqBQIKvZghkoZDgA8uDJAwk4bDhLd+ABBmvbjnzbgMKBuoA/bKDQgC1F -gW8XKMgQOHABBQsMI76wIIOExo0FZIhM8sKGCQYCYA4cwcCEDSYPLOgg4Oro -uhMEdOB84cCAChReB2ZQYcGGkxsGFGCgGzCFCh1QH5jQIW3xugwSzD4QvIIH -4s/PUgiQYcCG4BkC5P/ObpaBhwreq18nb3Z79+8Dwo9nL9I8evjWsdOX6D59 -fPH71Xeef/kFyB93/sln4EP2Ebjegg31B5+CEDLUIH4PVqiQhOABqKFCF6qn -34cHcfjffCQaFOJtGaZYkIkUuljQigXK+CKCE3po40A0trgjjDru+EGPI/6I -Y4co7kikkAMBmaSNSzL5gZNSDjkghkXaaGIBHjwpY4gThJeljFt2WSWYMQpZ -5pguUnClehS4tuMEDARQgH8FBMBBBExGwIGdAxywXAUBKHCZkAIoEEAFp33W -QGl47ZgBAwZEwKigE1SQgAUCUDCXiwtQIIAFCTQwgaCrZeCABAzIleIGHDD/ -oIAHGUznmXABGMABT4xpmBYBHGgAKGq1ZbppThgAG8EEAW61KwYMSOBAApdy -pNp/BkhAAQLcEqCTt+ACJW645I5rLrgEeOsTBtwiQIEElRZg61sTNBBethSw -CwEA/Pbr778ABywwABBAgAAG7xpAq6mGUUTdAPZ6YIACsRKAAbvtZqzxxhxn -jDG3ybbKFHf36ZVYpuE5oIGhHMTqcqswvyxzzDS/HDMHEiiggQMLDxCZXh8k -BnEBCQTggAUGGKCB0ktr0PTTTEfttNRQT22ABR4EkEABDXgnGUEn31ZABglE -EEAAWaeN9tpqt832221HEEECW6M3wc+Hga3SBgtMODBABw00UEEBgxdO+OGG -J4744oZzXUEDHQxwN7F5G7QRdXxPoPkAnHfu+eeghw665n1vIKhJBQUEADs=""") - -style = ttk.Style() - -style.element_create("RoundedFrame", "image", "frameBorder", - ("focus", "frameFocusBorder"), border=16, sticky="nsew") - -style.layout("RoundedFrame", [("RoundedFrame", {"sticky": "nsew"})]) -style.configure("TEntry", borderwidth=0) - -frame = ttk.Frame(style="RoundedFrame", padding=10) -frame.pack(fill='x') - -frame2 = ttk.Frame(style="RoundedFrame", padding=10) -frame2.pack(fill='both', expand=1) - -entry = ttk.Entry(frame, text='Test') -entry.pack(fill='x') -entry.bind("<FocusIn>", lambda evt: frame.state(["focus"])) -entry.bind("<FocusOut>", lambda evt: frame.state(["!focus"])) - -text = tkinter.Text(frame2, borderwidth=0, bg="white", highlightthickness=0) -text.pack(fill='both', expand=1) -text.bind("<FocusIn>", lambda evt: frame2.state(["focus"])) -text.bind("<FocusOut>", lambda evt: frame2.state(["!focus"])) - -root.mainloop() diff --git a/Demo/tkinter/ttk/theme_selector.py b/Demo/tkinter/ttk/theme_selector.py deleted file mode 100644 index 09c5a72..0000000 --- a/Demo/tkinter/ttk/theme_selector.py +++ /dev/null @@ -1,61 +0,0 @@ -"""Ttk Theme Selector v2. - -This is an improvement from the other theme selector (themes_combo.py) -since now you can notice theme changes in Ttk Combobox, Ttk Frame, -Ttk Label and Ttk Button. -""" -import tkinter -from tkinter import ttk - -class App(ttk.Frame): - def __init__(self): - ttk.Frame.__init__(self, borderwidth=3) - - self.style = ttk.Style() - - # XXX Ideally I wouldn't want to create a Tkinter.IntVar to make - # it works with Checkbutton variable option. - self.theme_autochange = tkinter.IntVar(self, 0) - self._setup_widgets() - - def _change_theme(self): - self.style.theme_use(self.themes_combo.get()) - - def _theme_sel_changed(self, widget): - if self.theme_autochange.get(): - self._change_theme() - - def _setup_widgets(self): - themes_lbl = ttk.Label(self, text="Themes") - - themes = self.style.theme_names() - self.themes_combo = ttk.Combobox(self, values=themes, state="readonly") - self.themes_combo.set(themes[0]) - self.themes_combo.bind("<<ComboboxSelected>>", self._theme_sel_changed) - - change_btn = ttk.Button(self, text='Change Theme', - command=self._change_theme) - - theme_change_checkbtn = ttk.Checkbutton(self, - text="Change themes when combobox item is activated", - variable=self.theme_autochange) - - themes_lbl.grid(ipadx=6, sticky="w") - self.themes_combo.grid(row=0, column=1, padx=6, sticky="ew") - change_btn.grid(row=0, column=2, padx=6, sticky="e") - theme_change_checkbtn.grid(row=1, columnspan=3, sticky="w", pady=6) - - top = self.winfo_toplevel() - top.rowconfigure(0, weight=1) - top.columnconfigure(0, weight=1) - self.columnconfigure(1, weight=1) - self.grid(row=0, column=0, sticky="nsew", columnspan=3, rowspan=2) - - -def main(): - app = App() - app.master.title("Theme Selector") - app.mainloop() - -if __name__ == "__main__": - main() diff --git a/Demo/tkinter/ttk/treeview_multicolumn.py b/Demo/tkinter/ttk/treeview_multicolumn.py deleted file mode 100644 index be72237..0000000 --- a/Demo/tkinter/ttk/treeview_multicolumn.py +++ /dev/null @@ -1,107 +0,0 @@ -"""Demo based on the demo mclist included with tk source distribution.""" -import tkinter -import tkinter.font -from tkinter import ttk - -tree_columns = ("country", "capital", "currency") -tree_data = [ - ("Argentina", "Buenos Aires", "ARS"), - ("Australia", "Canberra", "AUD"), - ("Brazil", "Brazilia", "BRL"), - ("Canada", "Ottawa", "CAD"), - ("China", "Beijing", "CNY"), - ("France", "Paris", "EUR"), - ("Germany", "Berlin", "EUR"), - ("India", "New Delhi", "INR"), - ("Italy", "Rome", "EUR"), - ("Japan", "Tokyo", "JPY"), - ("Mexico", "Mexico City", "MXN"), - ("Russia", "Moscow", "RUB"), - ("South Africa", "Pretoria", "ZAR"), - ("United Kingdom", "London", "GBP"), - ("United States", "Washington, D.C.", "USD") - ] - -def sortby(tree, col, descending): - """Sort tree contents when a column is clicked on.""" - # grab values to sort - data = [(tree.set(child, col), child) for child in tree.get_children('')] - - # reorder data - data.sort(reverse=descending) - for indx, item in enumerate(data): - tree.move(item[1], '', indx) - - # switch the heading so that it will sort in the opposite direction - tree.heading(col, - command=lambda col=col: sortby(tree, col, int(not descending))) - -class App(object): - def __init__(self): - self.tree = None - self._setup_widgets() - self._build_tree() - - def _setup_widgets(self): - msg = ttk.Label(wraplength="4i", justify="left", anchor="n", - padding=(10, 2, 10, 6), - text=("Ttk is the new Tk themed widget set. One of the widgets it " - "includes is a tree widget, which can be configured to " - "display multiple columns of informational data without " - "displaying the tree itself. This is a simple way to build " - "a listbox that has multiple columns. Clicking on the " - "heading for a column will sort the data by that column. " - "You can also change the width of the columns by dragging " - "the boundary between them.")) - msg.pack(fill='x') - - container = ttk.Frame() - container.pack(fill='both', expand=True) - - # XXX Sounds like a good support class would be one for constructing - # a treeview with scrollbars. - self.tree = ttk.Treeview(columns=tree_columns, show="headings") - vsb = ttk.Scrollbar(orient="vertical", command=self.tree.yview) - hsb = ttk.Scrollbar(orient="horizontal", command=self.tree.xview) - self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set) - self.tree.grid(column=0, row=0, sticky='nsew', in_=container) - vsb.grid(column=1, row=0, sticky='ns', in_=container) - hsb.grid(column=0, row=1, sticky='ew', in_=container) - - container.grid_columnconfigure(0, weight=1) - container.grid_rowconfigure(0, weight=1) - - def _build_tree(self): - for col in tree_columns: - self.tree.heading(col, text=col.title(), - command=lambda c=col: sortby(self.tree, c, 0)) - # XXX tkFont.Font().measure expected args are incorrect according - # to the Tk docs - self.tree.column(col, width=tkinter.font.Font().measure(col.title())) - - for item in tree_data: - self.tree.insert('', 'end', values=item) - - # adjust columns lenghts if necessary - for indx, val in enumerate(item): - ilen = tkinter.font.Font().measure(val) - if self.tree.column(tree_columns[indx], width=None) < ilen: - self.tree.column(tree_columns[indx], width=ilen) - -def main(): - root = tkinter.Tk() - root.wm_title("Multi-Column List") - root.wm_iconname("mclist") - - import plastik_theme - try: - plastik_theme.install('~/tile-themes/plastik/plastik') - except Exception: - import warnings - warnings.warn("plastik theme being used without images") - - app = App() - root.mainloop() - -if __name__ == "__main__": - main() diff --git a/Demo/tkinter/ttk/ttkcalendar.py b/Demo/tkinter/ttk/ttkcalendar.py deleted file mode 100644 index 8e35f1f..0000000 --- a/Demo/tkinter/ttk/ttkcalendar.py +++ /dev/null @@ -1,231 +0,0 @@ -""" -Simple calendar using ttk Treeview together with calendar and datetime -classes. -""" -import calendar -import tkinter -import tkinter.font -from tkinter import ttk - -def get_calendar(locale, fwday): - # instantiate proper calendar class - if locale is None: - return calendar.TextCalendar(fwday) - else: - return calendar.LocaleTextCalendar(fwday, locale) - -class Calendar(ttk.Frame): - # XXX ToDo: cget and configure - - datetime = calendar.datetime.datetime - timedelta = calendar.datetime.timedelta - - def __init__(self, master=None, **kw): - """ - WIDGET-SPECIFIC OPTIONS - - locale, firstweekday, year, month, selectbackground, - selectforeground - """ - # remove custom options from kw before initializating ttk.Frame - fwday = kw.pop('firstweekday', calendar.MONDAY) - year = kw.pop('year', self.datetime.now().year) - month = kw.pop('month', self.datetime.now().month) - locale = kw.pop('locale', None) - sel_bg = kw.pop('selectbackground', '#ecffc4') - sel_fg = kw.pop('selectforeground', '#05640e') - - self._date = self.datetime(year, month, 1) - self._selection = None # no date selected - - ttk.Frame.__init__(self, master, **kw) - - self._cal = get_calendar(locale, fwday) - - self.__setup_styles() # creates custom styles - self.__place_widgets() # pack/grid used widgets - self.__config_calendar() # adjust calendar columns and setup tags - # configure a canvas, and proper bindings, for selecting dates - self.__setup_selection(sel_bg, sel_fg) - - # store items ids, used for insertion later - self._items = [self._calendar.insert('', 'end', values='') - for _ in range(6)] - # insert dates in the currently empty calendar - self._build_calendar() - - # set the minimal size for the widget - self._calendar.bind('<Map>', self.__minsize) - - def __setitem__(self, item, value): - if item in ('year', 'month'): - raise AttributeError("attribute '%s' is not writeable" % item) - elif item == 'selectbackground': - self._canvas['background'] = value - elif item == 'selectforeground': - self._canvas.itemconfigure(self._canvas.text, item=value) - else: - ttk.Frame.__setitem__(self, item, value) - - def __getitem__(self, item): - if item in ('year', 'month'): - return getattr(self._date, item) - elif item == 'selectbackground': - return self._canvas['background'] - elif item == 'selectforeground': - return self._canvas.itemcget(self._canvas.text, 'fill') - else: - r = ttk.tclobjs_to_py({item: ttk.Frame.__getitem__(self, item)}) - return r[item] - - def __setup_styles(self): - # custom ttk styles - style = ttk.Style(self.master) - arrow_layout = lambda dir: ( - [('Button.focus', {'children': [('Button.%sarrow' % dir, None)]})] - ) - style.layout('L.TButton', arrow_layout('left')) - style.layout('R.TButton', arrow_layout('right')) - - def __place_widgets(self): - # header frame and its widgets - hframe = ttk.Frame(self) - lbtn = ttk.Button(hframe, style='L.TButton', command=self._prev_month) - rbtn = ttk.Button(hframe, style='R.TButton', command=self._next_month) - self._header = ttk.Label(hframe, width=15, anchor='center') - # the calendar - self._calendar = ttk.Treeview(show='', selectmode='none', height=7) - - # pack the widgets - hframe.pack(in_=self, side='top', pady=4, anchor='center') - lbtn.grid(in_=hframe) - self._header.grid(in_=hframe, column=1, row=0, padx=12) - rbtn.grid(in_=hframe, column=2, row=0) - self._calendar.pack(in_=self, expand=1, fill='both', side='bottom') - - def __config_calendar(self): - cols = self._cal.formatweekheader(3).split() - self._calendar['columns'] = cols - self._calendar.tag_configure('header', background='grey90') - self._calendar.insert('', 'end', values=cols, tag='header') - # adjust its columns width - font = tkinter.font.Font() - maxwidth = max(font.measure(col) for col in cols) - for col in cols: - self._calendar.column(col, width=maxwidth, minwidth=maxwidth, - anchor='e') - - def __setup_selection(self, sel_bg, sel_fg): - self._font = tkinter.font.Font() - self._canvas = canvas = tkinter.Canvas(self._calendar, - background=sel_bg, borderwidth=0, highlightthickness=0) - canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='w') - - canvas.bind('<ButtonPress-1>', lambda evt: canvas.place_forget()) - self._calendar.bind('<Configure>', lambda evt: canvas.place_forget()) - self._calendar.bind('<ButtonPress-1>', self._pressed) - - def __minsize(self, evt): - width, height = self._calendar.master.geometry().split('x') - height = height[:height.index('+')] - self._calendar.master.minsize(width, height) - - def _build_calendar(self): - year, month = self._date.year, self._date.month - - # update header text (Month, YEAR) - header = self._cal.formatmonthname(year, month, 0) - self._header['text'] = header.title() - - # update calendar shown dates - cal = self._cal.monthdayscalendar(year, month) - for indx, item in enumerate(self._items): - week = cal[indx] if indx < len(cal) else [] - fmt_week = [('%02d' % day) if day else '' for day in week] - self._calendar.item(item, values=fmt_week) - - def _show_selection(self, text, bbox): - """Configure canvas for a new selection.""" - x, y, width, height = bbox - - textw = self._font.measure(text) - - canvas = self._canvas - canvas.configure(width=width, height=height) - canvas.coords(canvas.text, width - textw, height / 2 - 1) - canvas.itemconfigure(canvas.text, text=text) - canvas.place(in_=self._calendar, x=x, y=y) - - # Callbacks - - def _pressed(self, evt): - """Clicked somewhere in the calendar.""" - x, y, widget = evt.x, evt.y, evt.widget - item = widget.identify_row(y) - column = widget.identify_column(x) - - if not column or not item in self._items: - # clicked in the weekdays row or just outside the columns - return - - item_values = widget.item(item)['values'] - if not len(item_values): # row is empty for this month - return - - text = item_values[int(column[1]) - 1] - if not text: # date is empty - return - - bbox = widget.bbox(item, column) - if not bbox: # calendar not visible yet - return - - # update and then show selection - text = '%02d' % text - self._selection = (text, item, column) - self._show_selection(text, bbox) - - def _prev_month(self): - """Updated calendar to show the previous month.""" - self._canvas.place_forget() - - self._date = self._date - self.timedelta(days=1) - self._date = self.datetime(self._date.year, self._date.month, 1) - self._build_calendar() # reconstuct calendar - - def _next_month(self): - """Update calendar to show the next month.""" - self._canvas.place_forget() - - year, month = self._date.year, self._date.month - self._date = self._date + self.timedelta( - days=calendar.monthrange(year, month)[1] + 1) - self._date = self.datetime(self._date.year, self._date.month, 1) - self._build_calendar() # reconstruct calendar - - # Properties - - @property - def selection(self): - """Return a datetime representing the current selected date.""" - if not self._selection: - return None - - year, month = self._date.year, self._date.month - return self.datetime(year, month, int(self._selection[0])) - -def test(): - import sys - root = tkinter.Tk() - root.title('Ttk Calendar') - ttkcal = Calendar(firstweekday=calendar.SUNDAY) - ttkcal.pack(expand=1, fill='both') - - if 'win' not in sys.platform: - style = ttk.Style() - style.theme_use('clam') - - root.mainloop() - -if __name__ == '__main__': - test() diff --git a/Demo/tkinter/ttk/widget_state.py b/Demo/tkinter/ttk/widget_state.py deleted file mode 100644 index b68f13b..0000000 --- a/Demo/tkinter/ttk/widget_state.py +++ /dev/null @@ -1,83 +0,0 @@ -"""Sample demo showing widget states and some font styling.""" -from tkinter import ttk - -states = ['active', 'disabled', 'focus', 'pressed', 'selected', - 'background', 'readonly', 'alternate', 'invalid'] - -for state in states[:]: - states.append("!" + state) - -def reset_state(widget): - nostate = states[len(states) // 2:] - widget.state(nostate) - -class App(ttk.Frame): - def __init__(self, title=None): - ttk.Frame.__init__(self, borderwidth=6) - self.master.title(title) - - self.style = ttk.Style() - - # get default font size and family - btn_font = self.style.lookup("TButton", "font") - fsize = str(self.tk.eval("font configure %s -size" % btn_font)) - self.font_family = self.tk.eval("font configure %s -family" % btn_font) - if ' ' in self.font_family: - self.font_family = '{%s}' % self.font_family - self.fsize_prefix = fsize[0] if fsize[0] == '-' else '' - self.base_fsize = int(fsize[1 if fsize[0] == '-' else 0:]) - - # a list to hold all the widgets that will have their states changed - self.update_widgets = [] - - self._setup_widgets() - - def _set_font(self, extra=0): - self.style.configure("TButton", font="%s %s%d" % (self.font_family, - self.fsize_prefix, self.base_fsize + extra)) - - def _new_state(self, widget, newtext): - widget = self.nametowidget(widget) - - if not newtext: - goodstates = ["disabled"] - font_extra = 0 - else: - # set widget state according to what has been entered in the entry - newstates = set(newtext.split()) # eliminate duplicates - - # keep only the valid states - goodstates = [state for state in newstates if state in states] - # define a new font size based on amount of states - font_extra = 2 * len(goodstates) - - # set new widget state - for widget in self.update_widgets: - reset_state(widget) # remove any previous state from the widget - widget.state(goodstates) - - # update Ttk Button font size - self._set_font(font_extra) - return 1 - - def _setup_widgets(self): - btn = ttk.Button(self, text='Enter states and watch') - - entry = ttk.Entry(self, cursor='xterm', validate="key") - entry['validatecommand'] = (self.register(self._new_state), '%W', '%P') - entry.focus() - - self.update_widgets.append(btn) - entry.validate() - - entry.pack(fill='x', padx=6) - btn.pack(side='left', pady=6, padx=6, anchor='n') - self.pack(fill='both', expand=1) - - -def main(): - app = App("Widget State Tester") - app.mainloop() - -if __name__ == "__main__": - main() diff --git a/Demo/turtle/about_turtle.txt b/Demo/turtle/about_turtle.txt deleted file mode 100644 index e4ba217..0000000 --- a/Demo/turtle/about_turtle.txt +++ /dev/null @@ -1,76 +0,0 @@ - -======================================================== - A new turtle module for Python -======================================================== - -Turtle graphics is a popular way for introducing programming to -kids. It was part of the original Logo programming language developed -by Wally Feurzig and Seymour Papert in 1966. - -Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it -the command turtle.forward(15), and it moves (on-screen!) 15 pixels in -the direction it is facing, drawing a line as it moves. Give it the -command turtle.left(25), and it rotates in-place 25 degrees clockwise. - -By combining together these and similar commands, intricate shapes and -pictures can easily be drawn. - ------ turtle.py - -This module is an extended reimplementation of turtle.py from the -Python standard distribution up to Python 2.5. (See: http:\\www.python.org) - -It tries to keep the merits of turtle.py and to be (nearly) 100% -compatible with it. This means in the first place to enable the -learning programmer to use all the commands, classes and methods -interactively when using the module from within IDLE run with -the -n switch. - -Roughly it has the following features added: - -- Better animation of the turtle movements, especially of turning the - turtle. So the turtles can more easily be used as a visual feedback - instrument by the (beginning) programmer. - -- Different turtle shapes, gif-images as turtle shapes, user defined - and user controllable turtle shapes, among them compound - (multicolored) shapes. Turtle shapes can be stgretched and tilted, which - makes turtles zu very versatile geometrical objects. - -- Fine control over turtle movement and screen updates via delay(), - and enhanced tracer() and speed() methods. - -- Aliases for the most commonly used commands, like fd for forward etc., - following the early Logo traditions. This reduces the boring work of - typing long sequences of commands, which often occur in a natural way - when kids try to program fancy pictures on their first encounter with - turtle graphcis. - -- Turtles now have an undo()-method with configurable undo-buffer. - -- Some simple commands/methods for creating event driven programs - (mouse-, key-, timer-events). Especially useful for programming games. - -- A scrollable Canvas class. The default scrollable Canvas can be - extended interactively as needed while playing around with the turtle(s). - -- A TurtleScreen class with methods controlling background color or - background image, window and canvas size and other properties of the - TurtleScreen. - -- There is a method, setworldcoordinates(), to install a user defined - coordinate-system for the TurtleScreen. - -- The implementation uses a 2-vector class named Vec2D, derived from tuple. - This class is public, so it can be imported by the application programmer, - which makes certain types of computations very natural and compact. - -- Appearance of the TurtleScreen and the Turtles at startup/import can be - configured by means of a turtle.cfg configuration file. - The default configuration mimics the appearance of the old turtle module. - -- If configured appropriately the module reads in docstrings from a docstring - dictionary in some different language, supplied separately and replaces - the english ones by those read in. There is a utility function - write_docstringdict() to write a dictionary with the original (english) - docstrings to disc, so it can serve as a template for translations. diff --git a/Demo/turtle/about_turtledemo.txt b/Demo/turtle/about_turtledemo.txt deleted file mode 100644 index 54c25a5..0000000 --- a/Demo/turtle/about_turtledemo.txt +++ /dev/null @@ -1,13 +0,0 @@ - - -------------------------------------- - About turtleDemo.py - -------------------------------------- - - Tiny demo Viewer to view turtle graphics example scripts. - - Quickly and dirtyly assembled by Gregor Lingl. - June, 2006 - - For more information see: turtleDemo - Help - - Have fun! diff --git a/Demo/turtle/demohelp.txt b/Demo/turtle/demohelp.txt deleted file mode 100644 index 5683875..0000000 --- a/Demo/turtle/demohelp.txt +++ /dev/null @@ -1,75 +0,0 @@ - - - ---------------------------------------------- - - turtleDemo - Help - - ---------------------------------------------- - - This document has two sections: - - (1) How to use the demo viewer - (2) How to add your own demos to the demo repository - - - (1) How to use the demo viewer. - - Select a demoscript from the example menu. - The (syntax coloured) source code appears in the left - source code window. IT CANNOT BE EDITED, but ONLY VIEWED! - - - Press START button to start the demo. - - Stop execution by pressing the STOP button. - - Clear screen by pressing the CLEAR button. - - Restart by pressing the START button again. - - SPECIAL demos are those which run EVENTDRIVEN. - (For example clock.py - or oldTurtleDemo.py which - in the end expects a mouse click.): - - Press START button to start the demo. - - - Until the EVENTLOOP is entered everything works - as in an ordinary demo script. - - - When the EVENTLOOP is entered, you control the - application by using the mouse and/or keys (or it's - controlled by some timer events) - To stop it you can and must press the STOP button. - - While the EVENTLOOP is running, the examples menu is disabled. - - - Only after having pressed the STOP button, you may - restart it or choose another example script. - - * * * * * * * * - In some rare situations there may occur interferences/conflicts - between events concerning the demo script and those concerning the - demo-viewer. (They run in the same process.) Strange behaviour may be - the consequence and in the worst case you must close and restart the - viewer. - * * * * * * * * - - - (2) How to add your own demos to the demo repository - - - scriptname: must begin with tdemo_ , - so it must have the form tdemo_<your-script-name>.py - - - place: same directory as turtleDemo.py or some - subdirectory, the name of which must also begin with - tdemo_..... - - - requirements on source code: - code must contain a main() function which will - be executed by the viewer (see provided example scripts) - main() may return a string which will be displayed - in the Label below the source code window (when execution - has finished.) - - !! For programs, which are EVENT DRIVEN, main must return - !! the string "EVENTLOOP". This informs the viewer, that the - !! script is still running and must be stopped by the user! - - - diff --git a/Demo/turtle/tdemo_I_dontlike_tiltdemo.py b/Demo/turtle/tdemo_I_dontlike_tiltdemo.py deleted file mode 100644 index 1d8652c..0000000 --- a/Demo/turtle/tdemo_I_dontlike_tiltdemo.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - tdemo-I_dont_like_tiltdemo.py - -Demostrates - (a) use of a tilted ellipse as - turtle shape - (b) stamping that shape - -We can remove it, if you don't like it. - Without using reset() ;-) - --------------------------------------- -""" -from turtle import * -import time - -def main(): - reset() - shape("circle") - resizemode("user") - - pu(); bk(24*18/6.283); rt(90); pd() - tilt(45) - - pu() - - turtlesize(16,10,5) - color("red", "violet") - for i in range(18): - fd(24) - lt(20) - stamp() - color("red", "") - for i in range(18): - fd(24) - lt(20) - stamp() - - tilt(-15) - turtlesize(3, 1, 4) - color("blue", "yellow") - for i in range(17): - fd(24) - lt(20) - if i%2 == 0: - stamp() - time.sleep(1) - while undobufferentries(): - undo() - ht() - write("OK, OVER!", align="center", font=("Courier", 18, "bold")) - return "Done!" - -if __name__=="__main__": - msg = main() - print(msg) -# mainloop() diff --git a/Demo/turtle/tdemo_bytedesign.py b/Demo/turtle/tdemo_bytedesign.py deleted file mode 100644 index 85f2887..0000000 --- a/Demo/turtle/tdemo_bytedesign.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - tdemo_bytedesign.py - -An example adapted from the example-suite -of PythonCard's turtle graphics. - -It's based on an article in BYTE magazine -Problem Solving with Logo: Using Turtle -Graphics to Redraw a Design -November 1982, p. 118 - 134 - -------------------------------------------- - -Due to the statement - -t.delay(0) - -in line 152, which sets the animation delay -to 0, this animation runs in "line per line" -mode as fast as possible. -""" - -import math -from turtle import Turtle, mainloop -from time import clock - -# wrapper for any additional drawing routines -# that need to know about each other -class Designer(Turtle): - - def design(self, homePos, scale): - self.up() - for i in range(5): - self.forward(64.65 * scale) - self.down() - self.wheel(self.position(), scale) - self.up() - self.backward(64.65 * scale) - self.right(72) - self.up() - self.goto(homePos) - self.right(36) - self.forward(24.5 * scale) - self.right(198) - self.down() - self.centerpiece(46 * scale, 143.4, scale) - self.getscreen().tracer(True) - - def wheel(self, initpos, scale): - self.right(54) - for i in range(4): - self.pentpiece(initpos, scale) - self.down() - self.left(36) - for i in range(5): - self.tripiece(initpos, scale) - self.left(36) - for i in range(5): - self.down() - self.right(72) - self.forward(28 * scale) - self.up() - self.backward(28 * scale) - self.left(54) - self.getscreen().update() - - def tripiece(self, initpos, scale): - oldh = self.heading() - self.down() - self.backward(2.5 * scale) - self.tripolyr(31.5 * scale, scale) - self.up() - self.goto(initpos) - self.setheading(oldh) - self.down() - self.backward(2.5 * scale) - self.tripolyl(31.5 * scale, scale) - self.up() - self.goto(initpos) - self.setheading(oldh) - self.left(72) - self.getscreen().update() - - def pentpiece(self, initpos, scale): - oldh = self.heading() - self.up() - self.forward(29 * scale) - self.down() - for i in range(5): - self.forward(18 * scale) - self.right(72) - self.pentr(18 * scale, 75, scale) - self.up() - self.goto(initpos) - self.setheading(oldh) - self.forward(29 * scale) - self.down() - for i in range(5): - self.forward(18 * scale) - self.right(72) - self.pentl(18 * scale, 75, scale) - self.up() - self.goto(initpos) - self.setheading(oldh) - self.left(72) - self.getscreen().update() - - def pentl(self, side, ang, scale): - if side < (2 * scale): return - self.forward(side) - self.left(ang) - self.pentl(side - (.38 * scale), ang, scale) - - def pentr(self, side, ang, scale): - if side < (2 * scale): return - self.forward(side) - self.right(ang) - self.pentr(side - (.38 * scale), ang, scale) - - def tripolyr(self, side, scale): - if side < (4 * scale): return - self.forward(side) - self.right(111) - self.forward(side / 1.78) - self.right(111) - self.forward(side / 1.3) - self.right(146) - self.tripolyr(side * .75, scale) - - def tripolyl(self, side, scale): - if side < (4 * scale): return - self.forward(side) - self.left(111) - self.forward(side / 1.78) - self.left(111) - self.forward(side / 1.3) - self.left(146) - self.tripolyl(side * .75, scale) - - def centerpiece(self, s, a, scale): - self.forward(s); self.left(a) - if s < (7.5 * scale): - return - self.centerpiece(s - (1.2 * scale), a, scale) - -def main(): - t = Designer() - t.speed(0) - t.hideturtle() - t.getscreen().delay(0) - t.getscreen().tracer(0) - at = clock() - t.design(t.position(), 2) - et = clock() - return "runtime: %.2f sec." % (et-at) - -if __name__ == '__main__': - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_chaos.py b/Demo/turtle/tdemo_chaos.py deleted file mode 100644 index d4656f8..0000000 --- a/Demo/turtle/tdemo_chaos.py +++ /dev/null @@ -1,59 +0,0 @@ -# File: tdemo_chaos.py -# Author: Gregor Lingl -# Date: 2009-06-24 - -# A demonstration of chaos - -from turtle import * - -N = 80 - -def f(x): - return 3.9*x*(1-x) - -def g(x): - return 3.9*(x-x**2) - -def h(x): - return 3.9*x-3.9*x*x - -def jumpto(x, y): - penup(); goto(x,y) - -def line(x1, y1, x2, y2): - jumpto(x1, y1) - pendown() - goto(x2, y2) - -def coosys(): - line(-1, 0, N+1, 0) - line(0, -0.1, 0, 1.1) - -def plot(fun, start, colour): - pencolor(colour) - x = start - jumpto(0, x) - pendown() - dot(5) - for i in range(N): - x=fun(x) - goto(i+1,x) - dot(5) - -def main(): - reset() - setworldcoordinates(-1.0,-0.1, N+1, 1.1) - speed(0) - hideturtle() - coosys() - plot(f, 0.35, "blue") - plot(g, 0.35, "green") - plot(h, 0.35, "red") - # Now zoom in: - for s in range(100): - setworldcoordinates(0.5*s,-0.1, N+1, 1.1) - return "Done!" - -if __name__ == "__main__": - main() - mainloop() diff --git a/Demo/turtle/tdemo_clock.py b/Demo/turtle/tdemo_clock.py deleted file mode 100644 index e186c38..0000000 --- a/Demo/turtle/tdemo_clock.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/python -# -*- coding: cp1252 -*- -""" turtle-example-suite: - - tdemo_clock.py - -Enhanced clock-program, showing date -and time - ------------------------------------ - Press STOP to exit the program! - ------------------------------------ -""" -from turtle import * -from datetime import datetime - -mode("logo") - -def jump(distanz, winkel=0): - penup() - right(winkel) - forward(distanz) - left(winkel) - pendown() - -def hand(laenge, spitze): - fd(laenge*1.15) - rt(90) - fd(spitze/2.0) - lt(120) - fd(spitze) - lt(120) - fd(spitze) - lt(120) - fd(spitze/2.0) - -def make_hand_shape(name, laenge, spitze): - reset() - jump(-laenge*0.15) - begin_poly() - hand(laenge, spitze) - end_poly() - hand_form = get_poly() - register_shape(name, hand_form) - - -def clockface(radius): - reset() - pensize(7) - for i in range(60): - jump(radius) - if i % 5 == 0: - fd(25) - jump(-radius-25) - else: - dot(3) - jump(-radius) - rt(6) - -def setup(): - global second_hand, minute_hand, hour_hand, writer - mode("logo") - make_hand_shape("second_hand", 125, 25) - make_hand_shape("minute_hand", 130, 25) - make_hand_shape("hour_hand", 90, 25) - clockface(160) - second_hand = Turtle() - second_hand.shape("second_hand") - second_hand.color("gray20", "gray80") - minute_hand = Turtle() - minute_hand.shape("minute_hand") - minute_hand.color("blue1", "red1") - hour_hand = Turtle() - hour_hand.shape("hour_hand") - hour_hand.color("blue3", "red3") - for hand in second_hand, minute_hand, hour_hand: - hand.resizemode("user") - hand.shapesize(1, 1, 3) - hand.speed(0) - ht() - writer = Turtle() - #writer.mode("logo") - writer.ht() - writer.pu() - writer.bk(85) - - -def wochentag(t): - wochentag = ["Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday", "Sunday"] - return wochentag[t.weekday()] - -def datum(z): - monat = ["Jan.", "Feb.", "Mar.", "Apr.", "May", "June", - "July", "Aug.", "Sep.", "Oct.", "Nov.", "Dec."] - j = z.year - m = monat[z.month - 1] - t = z.day - return "%s %d %d" % (m, t, j) - -def tick(): - t = datetime.today() - sekunde = t.second + t.microsecond*0.000001 - minute = t.minute + sekunde/60.0 - stunde = t.hour + minute/60.0 - tracer(False) - writer.clear() - writer.home() - writer.forward(65) - writer.write(wochentag(t), - align="center", font=("Courier", 14, "bold")) - writer.back(150) - writer.write(datum(t), - align="center", font=("Courier", 14, "bold")) - writer.forward(85) - tracer(True) - second_hand.setheading(6*sekunde) - minute_hand.setheading(6*minute) - hour_hand.setheading(30*stunde) - tracer(True) - ontimer(tick, 100) - -def main(): - tracer(False) - setup() - tracer(True) - tick() - return "EVENTLOOP" - -if __name__ == "__main__": - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_colormixer.py b/Demo/turtle/tdemo_colormixer.py deleted file mode 100644 index f5d308d..0000000 --- a/Demo/turtle/tdemo_colormixer.py +++ /dev/null @@ -1,60 +0,0 @@ -# colormixer - -from turtle import Screen, Turtle, mainloop -import sys -sys.setrecursionlimit(20000) # overcomes, for now, an instability of Python 3.0 - -class ColorTurtle(Turtle): - - def __init__(self, x, y): - Turtle.__init__(self) - self.shape("turtle") - self.resizemode("user") - self.shapesize(3,3,5) - self.pensize(10) - self._color = [0,0,0] - self.x = x - self._color[x] = y - self.color(self._color) - self.speed(0) - self.left(90) - self.pu() - self.goto(x,0) - self.pd() - self.sety(1) - self.pu() - self.sety(y) - self.pencolor("gray25") - self.ondrag(self.shift) - - def shift(self, x, y): - self.sety(max(0,min(y,1))) - self._color[self.x] = self.ycor() - self.fillcolor(self._color) - setbgcolor() - -def setbgcolor(): - screen.bgcolor(red.ycor(), green.ycor(), blue.ycor()) - -def main(): - global screen, red, green, blue - screen = Screen() - screen.delay(0) - screen.setworldcoordinates(-1, -0.3, 3, 1.3) - - red = ColorTurtle(0, .5) - green = ColorTurtle(1, .5) - blue = ColorTurtle(2, .5) - setbgcolor() - - writer = Turtle() - writer.ht() - writer.pu() - writer.goto(1,1.15) - writer.write("DRAG!",align="center",font=("Arial",30,("bold","italic"))) - return "EVENTLOOP" - -if __name__ == "__main__": - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_forest.py b/Demo/turtle/tdemo_forest.py deleted file mode 100644 index 01fa186..0000000 --- a/Demo/turtle/tdemo_forest.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/python -""" turtlegraphics-example-suite: - - tdemo_forest.py - -Displays a 'forest' of 3 'breadth-first-trees' -similar to the one from example tree. -For further remarks see xtx_tree.py - -This example is a 'breadth-first'-rewrite of -a Logo program written by Erich Neuwirth. See: -http://homepage.univie.ac.at/erich.neuwirth/ -""" -from turtle import Turtle, colormode, tracer, mainloop -from random import randrange -from time import clock - -def symRandom(n): - return randrange(-n,n+1) - -def randomize( branchlist, angledist, sizedist ): - return [ (angle+symRandom(angledist), - sizefactor*1.01**symRandom(sizedist)) - for angle, sizefactor in branchlist ] - -def randomfd( t, distance, parts, angledist ): - for i in range(parts): - t.left(symRandom(angledist)) - t.forward( (1.0 * distance)/parts ) - -def tree(tlist, size, level, widthfactor, branchlists, angledist=10, sizedist=5): - # benutzt Liste von turtles und Liste von Zweiglisten, - # fuer jede turtle eine! - if level > 0: - lst = [] - brs = [] - for t, branchlist in list(zip(tlist,branchlists)): - t.pensize( size * widthfactor ) - t.pencolor( 255 - (180 - 11 * level + symRandom(15)), - 180 - 11 * level + symRandom(15), - 0 ) - t.pendown() - randomfd(t, size, level, angledist ) - yield 1 - for angle, sizefactor in branchlist: - t.left(angle) - lst.append(t.clone()) - brs.append(randomize(branchlist, angledist, sizedist)) - t.right(angle) - for x in tree(lst, size*sizefactor, level-1, widthfactor, brs, - angledist, sizedist): - yield None - - -def start(t,x,y): - colormode(255) - t.reset() - t.speed(0) - t.hideturtle() - t.left(90) - t.penup() - t.setpos(x,y) - t.pendown() - -def doit1(level, pen): - pen.hideturtle() - start(pen, 20, -208) - t = tree( [pen], 80, level, 0.1, [[ (45,0.69), (0,0.65), (-45,0.71) ]] ) - return t - -def doit2(level, pen): - pen.hideturtle() - start(pen, -135, -130) - t = tree( [pen], 120, level, 0.1, [[ (45,0.69), (-45,0.71) ]] ) - return t - -def doit3(level, pen): - pen.hideturtle() - start(pen, 190, -90) - t = tree( [pen], 100, level, 0.1, [[ (45,0.7), (0,0.72), (-45,0.65) ]] ) - return t - -# Hier 3 Baumgeneratoren: -def main(): - p = Turtle() - p.ht() - tracer(75,0) - u = doit1(6, Turtle(undobuffersize=1)) - s = doit2(7, Turtle(undobuffersize=1)) - t = doit3(5, Turtle(undobuffersize=1)) - a = clock() - while True: - done = 0 - for b in u,s,t: - try: - b.__next__() - except: - done += 1 - if done == 3: - break - - tracer(1,10) - b = clock() - return "runtime: %.2f sec." % (b-a) - -if __name__ == '__main__': - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_fractalcurves.py b/Demo/turtle/tdemo_fractalcurves.py deleted file mode 100644 index 247f16c..0000000 --- a/Demo/turtle/tdemo_fractalcurves.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - tdemo_fractalCurves.py - -This program draws two fractal-curve-designs: -(1) A hilbert curve (in a box) -(2) A combination of Koch-curves. - -The CurvesTurtle class and the fractal-curve- -methods are taken from the PythonCard example -scripts for turtle-graphics. -""" -from turtle import * -from time import sleep, clock - -class CurvesTurtle(Pen): - # example derived from - # Turtle Geometry: The Computer as a Medium for Exploring Mathematics - # by Harold Abelson and Andrea diSessa - # p. 96-98 - def hilbert(self, size, level, parity): - if level == 0: - return - # rotate and draw first subcurve with opposite parity to big curve - self.left(parity * 90) - self.hilbert(size, level - 1, -parity) - # interface to and draw second subcurve with same parity as big curve - self.forward(size) - self.right(parity * 90) - self.hilbert(size, level - 1, parity) - # third subcurve - self.forward(size) - self.hilbert(size, level - 1, parity) - # fourth subcurve - self.right(parity * 90) - self.forward(size) - self.hilbert(size, level - 1, -parity) - # a final turn is needed to make the turtle - # end up facing outward from the large square - self.left(parity * 90) - - # Visual Modeling with Logo: A Structural Approach to Seeing - # by James Clayson - # Koch curve, after Helge von Koch who introduced this geometric figure in 1904 - # p. 146 - def fractalgon(self, n, rad, lev, dir): - import math - - # if dir = 1 turn outward - # if dir = -1 turn inward - edge = 2 * rad * math.sin(math.pi / n) - self.pu() - self.fd(rad) - self.pd() - self.rt(180 - (90 * (n - 2) / n)) - for i in range(n): - self.fractal(edge, lev, dir) - self.rt(360 / n) - self.lt(180 - (90 * (n - 2) / n)) - self.pu() - self.bk(rad) - self.pd() - - # p. 146 - def fractal(self, dist, depth, dir): - if depth < 1: - self.fd(dist) - return - self.fractal(dist / 3, depth - 1, dir) - self.lt(60 * dir) - self.fractal(dist / 3, depth - 1, dir) - self.rt(120 * dir) - self.fractal(dist / 3, depth - 1, dir) - self.lt(60 * dir) - self.fractal(dist / 3, depth - 1, dir) - -def main(): - ft = CurvesTurtle() - - ft.reset() - ft.speed(0) - ft.ht() - ft.getscreen().tracer(1,0) - ft.pu() - - size = 6 - ft.setpos(-33*size, -32*size) - ft.pd() - - ta=clock() - ft.fillcolor("red") - ft.begin_fill() - ft.fd(size) - - ft.hilbert(size, 6, 1) - - # frame - ft.fd(size) - for i in range(3): - ft.lt(90) - ft.fd(size*(64+i%2)) - ft.pu() - for i in range(2): - ft.fd(size) - ft.rt(90) - ft.pd() - for i in range(4): - ft.fd(size*(66+i%2)) - ft.rt(90) - ft.end_fill() - tb=clock() - res = "Hilbert: %.2fsec. " % (tb-ta) - - sleep(3) - - ft.reset() - ft.speed(0) - ft.ht() - ft.getscreen().tracer(1,0) - - ta=clock() - ft.color("black", "blue") - ft.begin_fill() - ft.fractalgon(3, 250, 4, 1) - ft.end_fill() - ft.begin_fill() - ft.color("red") - ft.fractalgon(3, 200, 4, -1) - ft.end_fill() - tb=clock() - res += "Koch: %.2fsec." % (tb-ta) - return res - -if __name__ == '__main__': - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_lindenmayer_indian.py b/Demo/turtle/tdemo_lindenmayer_indian.py deleted file mode 100644 index bda5067..0000000 --- a/Demo/turtle/tdemo_lindenmayer_indian.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - xtx_lindenmayer_indian.py - -Each morning women in Tamil Nadu, in southern -India, place designs, created by using rice -flour and known as kolam on the thresholds of -their homes. - -These can be described by Lindenmayer systems, -which can easily be implemented with turtle -graphics and Python. - -Two examples are shown here: -(1) the snake kolam -(2) anklets of Krishna - -Taken from Marcia Ascher: Mathematics -Elsewhere, An Exploration of Ideas Across -Cultures - -""" -################################ -# Mini Lindenmayer tool -############################### - -from turtle import * - -def replace( seq, replacementRules, n ): - for i in range(n): - newseq = "" - for element in seq: - newseq = newseq + replacementRules.get(element,element) - seq = newseq - return seq - -def draw( commands, rules ): - for b in commands: - try: - rules[b]() - except TypeError: - try: - draw(rules[b], rules) - except: - pass - - -def main(): - ################################ - # Example 1: Snake kolam - ################################ - - - def r(): - right(45) - - def l(): - left(45) - - def f(): - forward(7.5) - - snake_rules = {"-":r, "+":l, "f":f, "b":"f+f+f--f--f+f+f"} - snake_replacementRules = {"b": "b+f+b--f--b+f+b"} - snake_start = "b--f--b--f" - - drawing = replace(snake_start, snake_replacementRules, 3) - - reset() - speed(3) - tracer(1,0) - ht() - up() - backward(195) - down() - draw(drawing, snake_rules) - - from time import sleep - sleep(3) - - ################################ - # Example 2: Anklets of Krishna - ################################ - - def A(): - color("red") - circle(10,90) - - def B(): - from math import sqrt - color("black") - l = 5/sqrt(2) - forward(l) - circle(l, 270) - forward(l) - - def F(): - color("green") - forward(10) - - krishna_rules = {"a":A, "b":B, "f":F} - krishna_replacementRules = {"a" : "afbfa", "b" : "afbfbfbfa" } - krishna_start = "fbfbfbfb" - - reset() - speed(0) - tracer(3,0) - ht() - left(45) - drawing = replace(krishna_start, krishna_replacementRules, 3) - draw(drawing, krishna_rules) - tracer(1) - return "Done!" - -if __name__=='__main__': - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_minimal_hanoi.py b/Demo/turtle/tdemo_minimal_hanoi.py deleted file mode 100644 index a8bdca7..0000000 --- a/Demo/turtle/tdemo_minimal_hanoi.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - tdemo_minimal_hanoi.py - -A minimal 'Towers of Hanoi' animation: -A tower of 6 discs is transferred from the -left to the right peg. - -An imho quite elegant and concise -implementation using a tower class, which -is derived from the built-in type list. - -Discs are turtles with shape "square", but -stretched to rectangles by shapesize() - --------------------------------------- - To exit press STOP button - --------------------------------------- -""" -from turtle import * - -class Disc(Turtle): - def __init__(self, n): - Turtle.__init__(self, shape="square", visible=False) - self.pu() - self.shapesize(1.5, n*1.5, 2) # square-->rectangle - self.fillcolor(n/6., 0, 1-n/6.) - self.st() - -class Tower(list): - "Hanoi tower, a subclass of built-in type list" - def __init__(self, x): - "create an empty tower. x is x-position of peg" - self.x = x - def push(self, d): - d.setx(self.x) - d.sety(-150+34*len(self)) - self.append(d) - def pop(self): - d = list.pop(self) - d.sety(150) - return d - -def hanoi(n, from_, with_, to_): - if n > 0: - hanoi(n-1, from_, to_, with_) - to_.push(from_.pop()) - hanoi(n-1, with_, from_, to_) - -def play(): - onkey(None,"space") - clear() - hanoi(6, t1, t2, t3) - write("press STOP button to exit", - align="center", font=("Courier", 16, "bold")) - -def main(): - global t1, t2, t3 - ht(); penup(); goto(0, -225) # writer turtle - t1 = Tower(-250) - t2 = Tower(0) - t3 = Tower(250) - # make tower of 6 discs - for i in range(6,0,-1): - t1.push(Disc(i)) - # prepare spartanic user interface ;-) - write("press spacebar to start game", - align="center", font=("Courier", 16, "bold")) - onkey(play, "space") - listen() - return "EVENTLOOP" - -if __name__=="__main__": - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_nim.py b/Demo/turtle/tdemo_nim.py deleted file mode 100644 index 8e66d7e..0000000 --- a/Demo/turtle/tdemo_nim.py +++ /dev/null @@ -1,227 +0,0 @@ -""" turtle-example-suite: - - tdemo_nim.py - -Play nim against the computer. The player -who takes the last stick is the winner. - -Implements the model-view-controller -design pattern. -""" - - -import turtle -import random -import time - -SCREENWIDTH = 640 -SCREENHEIGHT = 480 - -MINSTICKS = 7 -MAXSTICKS = 31 - -HUNIT = SCREENHEIGHT // 12 -WUNIT = SCREENWIDTH // ((MAXSTICKS // 5) * 11 + (MAXSTICKS % 5) * 2) - -SCOLOR = (63, 63, 31) -HCOLOR = (255, 204, 204) -COLOR = (204, 204, 255) - -def randomrow(): - return random.randint(MINSTICKS, MAXSTICKS) - -def computerzug(state): - xored = state[0] ^ state[1] ^ state[2] - if xored == 0: - return randommove(state) - for z in range(3): - s = state[z] ^ xored - if s <= state[z]: - move = (z, s) - return move - -def randommove(state): - m = max(state) - while True: - z = random.randint(0,2) - if state[z] > (m > 1): - break - rand = random.randint(m > 1, state[z]-1) - return z, rand - - -class NimModel(object): - def __init__(self, game): - self.game = game - - def setup(self): - if self.game.state not in [Nim.CREATED, Nim.OVER]: - return - self.sticks = [randomrow(), randomrow(), randomrow()] - self.player = 0 - self.winner = None - self.game.view.setup() - self.game.state = Nim.RUNNING - - def move(self, row, col): - maxspalte = self.sticks[row] - self.sticks[row] = col - self.game.view.notify_move(row, col, maxspalte, self.player) - if self.game_over(): - self.game.state = Nim.OVER - self.winner = self.player - self.game.view.notify_over() - elif self.player == 0: - self.player = 1 - row, col = computerzug(self.sticks) - self.move(row, col) - self.player = 0 - - def game_over(self): - return self.sticks == [0, 0, 0] - - def notify_move(self, row, col): - if self.sticks[row] <= col: - return - self.move(row, col) - - -class Stick(turtle.Turtle): - def __init__(self, row, col, game): - turtle.Turtle.__init__(self, visible=False) - self.row = row - self.col = col - self.game = game - x, y = self.coords(row, col) - self.shape("square") - self.shapesize(HUNIT/10.0, WUNIT/20.0) - self.speed(0) - self.pu() - self.goto(x,y) - self.color("white") - self.showturtle() - - def coords(self, row, col): - packet, remainder = divmod(col, 5) - x = (3 + 11 * packet + 2 * remainder) * WUNIT - y = (2 + 3 * row) * HUNIT - return x - SCREENWIDTH // 2 + WUNIT // 2, SCREENHEIGHT // 2 - y - HUNIT // 2 - - def makemove(self, x, y): - if self.game.state != Nim.RUNNING: - return - self.game.controller.notify_move(self.row, self.col) - - -class NimView(object): - def __init__(self, game): - self.game = game - self.screen = game.screen - self.model = game.model - self.screen.colormode(255) - self.screen.tracer(False) - self.screen.bgcolor((240, 240, 255)) - self.writer = turtle.Turtle(visible=False) - self.writer.pu() - self.writer.speed(0) - self.sticks = {} - for row in range(3): - for col in range(MAXSTICKS): - self.sticks[(row, col)] = Stick(row, col, game) - self.display("... a moment please ...") - self.screen.tracer(True) - - def display(self, msg1, msg2=None): - self.screen.tracer(False) - self.writer.clear() - if msg2 is not None: - self.writer.goto(0, - SCREENHEIGHT // 2 + 48) - self.writer.pencolor("red") - self.writer.write(msg2, align="center", font=("Courier",18,"bold")) - self.writer.goto(0, - SCREENHEIGHT // 2 + 20) - self.writer.pencolor("black") - self.writer.write(msg1, align="center", font=("Courier",14,"bold")) - self.screen.tracer(True) - - - def setup(self): - self.screen.tracer(False) - for row in range(3): - for col in range(self.model.sticks[row]): - self.sticks[(row, col)].color(SCOLOR) - for row in range(3): - for col in range(self.model.sticks[row], MAXSTICKS): - self.sticks[(row, col)].color("white") - self.display("Your turn! Click leftmost stick to remove.") - self.screen.tracer(True) - - def notify_move(self, row, col, maxspalte, player): - if player == 0: - farbe = HCOLOR - for s in range(col, maxspalte): - self.sticks[(row, s)].color(farbe) - else: - self.display(" ... thinking ... ") - time.sleep(0.5) - self.display(" ... thinking ... aaah ...") - farbe = COLOR - for s in range(maxspalte-1, col-1, -1): - time.sleep(0.2) - self.sticks[(row, s)].color(farbe) - self.display("Your turn! Click leftmost stick to remove.") - - def notify_over(self): - if self.game.model.winner == 0: - msg2 = "Congrats. You're the winner!!!" - else: - msg2 = "Sorry, the computer is the winner." - self.display("To play again press space bar. To leave press ESC.", msg2) - - def clear(self): - if self.game.state == Nim.OVER: - self.screen.clear() - -class NimController(object): - - def __init__(self, game): - self.game = game - self.sticks = game.view.sticks - self.BUSY = False - for stick in self.sticks.values(): - stick.onclick(stick.makemove) - self.game.screen.onkey(self.game.model.setup, "space") - self.game.screen.onkey(self.game.view.clear, "Escape") - self.game.view.display("Press space bar to start game") - self.game.screen.listen() - - def notify_move(self, row, col): - if self.BUSY: - return - self.BUSY = True - self.game.model.notify_move(row, col) - self.BUSY = False - -class Nim(object): - CREATED = 0 - RUNNING = 1 - OVER = 2 - def __init__(self, screen): - self.state = Nim.CREATED - self.screen = screen - self.model = NimModel(self) - self.view = NimView(self) - self.controller = NimController(self) - - -mainscreen = turtle.Screen() -mainscreen.mode("standard") -mainscreen.setup(SCREENWIDTH, SCREENHEIGHT) - -def main(): - nim = Nim(mainscreen) - return "EVENTLOOP!" - -if __name__ == "__main__": - main() - turtle.mainloop() - diff --git a/Demo/turtle/tdemo_paint.py b/Demo/turtle/tdemo_paint.py deleted file mode 100644 index 337a57c..0000000 --- a/Demo/turtle/tdemo_paint.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - tdemo_paint.py - -A simple eventdriven paint program - -- use left mouse button to move turtle -- middle mouse button to change color -- right mouse button do turn filling on/off - ------------------------------------------- - Play around by clicking into the canvas - using all three mouse buttons. - ------------------------------------------- - To exit press STOP button - ------------------------------------------- -""" -from turtle import * - -def switchupdown(x=0, y=0): - if pen()["pendown"]: - end_fill() - up() - else: - down() - begin_fill() - -def changecolor(x=0, y=0): - global colors - colors = colors[1:]+colors[:1] - color(colors[0]) - -def main(): - global colors - shape("circle") - resizemode("user") - shapesize(.5) - width(3) - colors=["red", "green", "blue", "yellow"] - color(colors[0]) - switchupdown() - onscreenclick(goto,1) - onscreenclick(changecolor,2) - onscreenclick(switchupdown,3) - return "EVENTLOOP" - -if __name__ == "__main__": - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_peace.py b/Demo/turtle/tdemo_peace.py deleted file mode 100644 index ea57069..0000000 --- a/Demo/turtle/tdemo_peace.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - tdemo_peace.py - -A very simple drawing suitable as a beginner's -programming example. - -Uses only commands, which are also available in -old turtle.py. - -Intentionally no variables are used except for the -colorloop: -""" - -from turtle import * - -def main(): - peacecolors = ("red3", "orange", "yellow", - "seagreen4", "orchid4", - "royalblue1", "dodgerblue4") - - reset() - s = Screen() - up() - goto(-320,-195) - width(70) - - for pcolor in peacecolors: - color(pcolor) - down() - forward(640) - up() - backward(640) - left(90) - forward(66) - right(90) - - width(25) - color("white") - goto(0,-170) - down() - - circle(170) - left(90) - forward(340) - up() - left(180) - forward(170) - right(45) - down() - forward(170) - up() - backward(170) - left(90) - down() - forward(170) - up() - - goto(0,300) # vanish if hideturtle() is not available ;-) - return "Done!!" - -if __name__ == "__main__": - main() - mainloop() diff --git a/Demo/turtle/tdemo_penrose.py b/Demo/turtle/tdemo_penrose.py deleted file mode 100644 index f816f66..0000000 --- a/Demo/turtle/tdemo_penrose.py +++ /dev/null @@ -1,181 +0,0 @@ -#!/usr/bin/python -""" xturtle-example-suite: - - xtx_kites_and_darts.py - -Constructs two aperiodic penrose-tilings, -consisting of kites and darts, by the method -of inflation in six steps. - -Starting points are the patterns "sun" -consisting of five kites and "star" -consisting of five darts. - -For more information see: - http://en.wikipedia.org/wiki/Penrose_tiling - ------------------------------------------- -""" -from turtle import * -from math import cos, pi -from time import clock, sleep - -f = (5**0.5-1)/2.0 # (sqrt(5)-1)/2 -- golden ratio -d = 2 * cos(3*pi/10) - -def kite(l): - fl = f * l - lt(36) - fd(l) - rt(108) - fd(fl) - rt(36) - fd(fl) - rt(108) - fd(l) - rt(144) - -def dart(l): - fl = f * l - lt(36) - fd(l) - rt(144) - fd(fl) - lt(36) - fd(fl) - rt(144) - fd(l) - rt(144) - -def inflatekite(l, n): - if n == 0: - px, py = pos() - h, x, y = int(heading()), round(px,3), round(py,3) - tiledict[(h,x,y)] = True - return - fl = f * l - lt(36) - inflatedart(fl, n-1) - fd(l) - rt(144) - inflatekite(fl, n-1) - lt(18) - fd(l*d) - rt(162) - inflatekite(fl, n-1) - lt(36) - fd(l) - rt(180) - inflatedart(fl, n-1) - lt(36) - -def inflatedart(l, n): - if n == 0: - px, py = pos() - h, x, y = int(heading()), round(px,3), round(py,3) - tiledict[(h,x,y)] = False - return - fl = f * l - inflatekite(fl, n-1) - lt(36) - fd(l) - rt(180) - inflatedart(fl, n-1) - lt(54) - fd(l*d) - rt(126) - inflatedart(fl, n-1) - fd(l) - rt(144) - -def draw(l, n, th=2): - clear() - l = l * f**n - shapesize(l/100.0, l/100.0, th) - for k in tiledict: - h, x, y = k - setpos(x, y) - setheading(h) - if tiledict[k]: - shape("kite") - color("black", (0, 0.75, 0)) - else: - shape("dart") - color("black", (0.75, 0, 0)) - stamp() - -def sun(l, n): - for i in range(5): - inflatekite(l, n) - lt(72) - -def star(l,n): - for i in range(5): - inflatedart(l, n) - lt(72) - -def makeshapes(): - tracer(0) - begin_poly() - kite(100) - end_poly() - register_shape("kite", get_poly()) - begin_poly() - dart(100) - end_poly() - register_shape("dart", get_poly()) - tracer(1) - -def start(): - reset() - ht() - pu() - makeshapes() - resizemode("user") - -def test(l=200, n=4, fun=sun, startpos=(0,0), th=2): - global tiledict - goto(startpos) - setheading(0) - tiledict = {} - a = clock() - tracer(0) - fun(l, n) - b = clock() - draw(l, n, th) - tracer(1) - c = clock() - print("Calculation: %7.4f s" % (b - a)) - print("Drawing: %7.4f s" % (c - b)) - print("Together: %7.4f s" % (c - a)) - nk = len([x for x in tiledict if tiledict[x]]) - nd = len([x for x in tiledict if not tiledict[x]]) - print("%d kites and %d darts = %d pieces." % (nk, nd, nk+nd)) - -def demo(fun=sun): - start() - for i in range(8): - a = clock() - test(300, i, fun) - b = clock() - t = b - a - if t < 2: - sleep(2 - t) - -def main(): - #title("Penrose-tiling with kites and darts.") - mode("logo") - bgcolor(0.3, 0.3, 0) - demo(sun) - sleep(2) - demo(star) - pencolor("black") - goto(0,-200) - pencolor(0.7,0.7,1) - write("Please wait...", - align="center", font=('Arial Black', 36, 'bold')) - test(600, 8, startpos=(70, 117)) - return "Done" - -if __name__ == "__main__": - msg = main() - mainloop() diff --git a/Demo/turtle/tdemo_planet_and_moon.py b/Demo/turtle/tdemo_planet_and_moon.py deleted file mode 100644 index 983449c..0000000 --- a/Demo/turtle/tdemo_planet_and_moon.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - tdemo_planets_and_moon.py - -Gravitational system simulation using the -approximation method from Feynman-lectures, -p.9-8, using turtlegraphics. - -Example: heavy central body, light planet, -very light moon! -Planet has a circular orbit, moon a stable -orbit around the planet. - -You can hold the movement temporarily by pressing -the left mouse button with mouse over the -scrollbar of the canvas. - -""" -from turtle import Shape, Turtle, mainloop, Vec2D as Vec -from time import sleep - -G = 8 - -class GravSys(object): - def __init__(self): - self.planets = [] - self.t = 0 - self.dt = 0.01 - def init(self): - for p in self.planets: - p.init() - def start(self): - for i in range(10000): - self.t += self.dt - for p in self.planets: - p.step() - -class Star(Turtle): - def __init__(self, m, x, v, gravSys, shape): - Turtle.__init__(self, shape=shape) - self.penup() - self.m = m - self.setpos(x) - self.v = v - gravSys.planets.append(self) - self.gravSys = gravSys - self.resizemode("user") - self.pendown() - def init(self): - dt = self.gravSys.dt - self.a = self.acc() - self.v = self.v + 0.5*dt*self.a - def acc(self): - a = Vec(0,0) - for planet in self.gravSys.planets: - if planet != self: - v = planet.pos()-self.pos() - a += (G*planet.m/abs(v)**3)*v - return a - def step(self): - dt = self.gravSys.dt - self.setpos(self.pos() + dt*self.v) - if self.gravSys.planets.index(self) != 0: - self.setheading(self.towards(self.gravSys.planets[0])) - self.a = self.acc() - self.v = self.v + dt*self.a - -## create compound yellow/blue turtleshape for planets - -def main(): - s = Turtle() - s.reset() - s.getscreen().tracer(0,0) - s.ht() - s.pu() - s.fd(6) - s.lt(90) - s.begin_poly() - s.circle(6, 180) - s.end_poly() - m1 = s.get_poly() - s.begin_poly() - s.circle(6,180) - s.end_poly() - m2 = s.get_poly() - - planetshape = Shape("compound") - planetshape.addcomponent(m1,"orange") - planetshape.addcomponent(m2,"blue") - s.getscreen().register_shape("planet", planetshape) - s.getscreen().tracer(1,0) - - ## setup gravitational system - gs = GravSys() - sun = Star(1000000, Vec(0,0), Vec(0,-2.5), gs, "circle") - sun.color("yellow") - sun.shapesize(1.8) - sun.pu() - earth = Star(12500, Vec(210,0), Vec(0,195), gs, "planet") - earth.pencolor("green") - earth.shapesize(0.8) - moon = Star(1, Vec(220,0), Vec(0,295), gs, "planet") - moon.pencolor("blue") - moon.shapesize(0.5) - gs.init() - gs.start() - return "Done!" - -if __name__ == '__main__': - msg = main() - print(msg) - #mainloop() diff --git a/Demo/turtle/tdemo_round_dance.py b/Demo/turtle/tdemo_round_dance.py deleted file mode 100644 index bffc1e6..0000000 --- a/Demo/turtle/tdemo_round_dance.py +++ /dev/null @@ -1,90 +0,0 @@ -""" turtle-example-suite: - - tdemo_round_dance.py - -(Needs version 1.1 of the turtle module that -comes with Python 3.1) - -Dancing turtles have a compound shape -consisting of a series of triangles of -decreasing size. - -Turtles march along a circle while rotating -pairwise in opposite direction, with one -exception. Does that breaking of symmetry -enhance the attractiveness of the example? - -Press any key to stop the animation. - -Technically: demonstrates use of compound -shapes, transformation of shapes as well as -cloning turtles. The animation is -controlled through update(). -""" - -from turtle import * - -def stop(): - global running - running = False - -def main(): - global running - clearscreen() - bgcolor("gray10") - tracer(False) - shape("triangle") - f = 0.793402 - phi = 9.064678 - s = 5 - c = 1 - # create compound shape - sh = Shape("compound") - for i in range(10): - shapesize(s) - p =get_shapepoly() - s *= f - c *= f - tilt(-phi) - sh.addcomponent(p, (c, 0.25, 1-c), "black") - register_shape("multitri", sh) - # create dancers - shapesize(1) - shape("multitri") - pu() - setpos(0, -200) - dancers = [] - for i in range(180): - fd(7) - tilt(-4) - lt(2) - update() - if i % 12 == 0: - dancers.append(clone()) - home() - # dance - running = True - onkeypress(stop) - listen() - cs = 1 - while running: - ta = -4 - for dancer in dancers: - dancer.fd(7) - dancer.lt(2) - dancer.tilt(ta) - ta = -4 if ta > 0 else 2 - if cs < 180: - right(4) - shapesize(cs) - cs *= 1.005 - update() - return "DONE!" - -if __name__=='__main__': - print(main()) - mainloop() - - - - diff --git a/Demo/turtle/tdemo_tree.py b/Demo/turtle/tdemo_tree.py deleted file mode 100644 index fda653c..0000000 --- a/Demo/turtle/tdemo_tree.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - tdemo_tree.py - -Displays a 'breadth-first-tree' - in contrast -to the classical Logo tree drawing programs, -which use a depth-first-algorithm. - -Uses: -(1) a tree-generator, where the drawing is -quasi the side-effect, whereas the generator -always yields None. -(2) Turtle-cloning: At each branching point the -current pen is cloned. So in the end there -are 1024 turtles. -""" -from turtle import Turtle, mainloop -from time import clock - -def tree(plist, l, a, f): - """ plist is list of pens - l is length of branch - a is half of the angle between 2 branches - f is factor by which branch is shortened - from level to level.""" - if l > 3: - lst = [] - for p in plist: - p.forward(l) - q = p.clone() - p.left(a) - q.right(a) - lst.append(p) - lst.append(q) - for x in tree(lst, l*f, a, f): - yield None - -def maketree(): - p = Turtle() - p.setundobuffer(None) - p.hideturtle() - p.speed(0) - p.getscreen().tracer(30,0) - p.left(90) - p.penup() - p.forward(-210) - p.pendown() - t = tree([p], 200, 65, 0.6375) - for x in t: - pass - print(len(p.getscreen().turtles())) - -def main(): - a=clock() - maketree() - b=clock() - return "done: %.2f sec." % (b-a) - -if __name__ == "__main__": - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_wikipedia.py b/Demo/turtle/tdemo_wikipedia.py deleted file mode 100644 index 73e03d2..0000000 --- a/Demo/turtle/tdemo_wikipedia.py +++ /dev/null @@ -1,65 +0,0 @@ -""" turtle-example-suite: - - tdemo_wikipedia3.py - -This example is -inspired by the Wikipedia article on turtle -graphics. (See example wikipedia1 for URLs) - -First we create (ne-1) (i.e. 35 in this -example) copies of our first turtle p. -Then we let them perform their steps in -parallel. - -Followed by a complete undo(). -""" -from turtle import Screen, Turtle, mainloop -from time import clock, sleep - -def mn_eck(p, ne,sz): - turtlelist = [p] - #create ne-1 additional turtles - for i in range(1,ne): - q = p.clone() - q.rt(360.0/ne) - turtlelist.append(q) - p = q - for i in range(ne): - c = abs(ne/2.0-i)/(ne*.7) - # let those ne turtles make a step - # in parallel: - for t in turtlelist: - t.rt(360./ne) - t.pencolor(1-c,0,c) - t.fd(sz) - -def main(): - s = Screen() - s.bgcolor("black") - p=Turtle() - p.speed(0) - p.hideturtle() - p.pencolor("red") - p.pensize(3) - - s.tracer(36,0) - - at = clock() - mn_eck(p, 36, 19) - et = clock() - z1 = et-at - - sleep(1) - - at = clock() - while any([t.undobufferentries() for t in s.turtles()]): - for t in s.turtles(): - t.undo() - et = clock() - return "Laufzeit: %.3f sec" % (z1+et-at) - - -if __name__ == '__main__': - msg = main() - print(msg) - mainloop() diff --git a/Demo/turtle/tdemo_yinyang.py b/Demo/turtle/tdemo_yinyang.py deleted file mode 100644 index 6508b44..0000000 --- a/Demo/turtle/tdemo_yinyang.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/python -""" turtle-example-suite: - - tdemo_yinyang.py - -Another drawing suitable as a beginner's -programming example. - -The small circles are drawn by the circle -command. - -""" - -from turtle import * - -def yin(radius, color1, color2): - width(3) - color("black", color1) - begin_fill() - circle(radius/2., 180) - circle(radius, 180) - left(180) - circle(-radius/2., 180) - end_fill() - left(90) - up() - forward(radius*0.35) - right(90) - down() - color(color1, color2) - begin_fill() - circle(radius*0.15) - end_fill() - left(90) - up() - backward(radius*0.35) - down() - left(90) - -def main(): - reset() - yin(200, "black", "white") - yin(200, "white", "black") - ht() - return "Done!" - -if __name__ == '__main__': - main() - mainloop() diff --git a/Demo/turtle/turtle.cfg b/Demo/turtle/turtle.cfg deleted file mode 100644 index bd89a74..0000000 --- a/Demo/turtle/turtle.cfg +++ /dev/null @@ -1,10 +0,0 @@ -width = 800 -height = 600 -canvwidth = 1200 -canvheight = 900 -shape = arrow -mode = standard -resizemode = auto -fillcolor = "" -title = Python turtle graphics demo. - diff --git a/Demo/turtle/turtleDemo.py b/Demo/turtle/turtleDemo.py deleted file mode 100644 index 36bf15c..0000000 --- a/Demo/turtle/turtleDemo.py +++ /dev/null @@ -1,291 +0,0 @@ -#!/usr/bin/python -import sys -import os - -from tkinter import * -from idlelib.Percolator import Percolator -from idlelib.ColorDelegator import ColorDelegator -from idlelib.textView import view_file # TextViewer -from imp import reload - -import turtle -import time - -STARTUP = 1 -READY = 2 -RUNNING = 3 -DONE = 4 -EVENTDRIVEN = 5 - -menufont = ("Arial", 12, NORMAL) -btnfont = ("Arial", 12, 'bold') -txtfont = ('Lucida Console', 8, 'normal') - -def getExampleEntries(): - cwd = os.getcwd() - #print(cwd, os.listdir(cwd)) - if "turtleDemo.py" not in os.listdir(cwd): - print("Directory of turtleDemo must be current working directory!") - print("But in your case this is", cwd) - sys.exit() - entries1 = [entry for entry in os.listdir(cwd) if - entry.startswith("tdemo_") and - not entry.endswith(".pyc")] - entries2 = [] - for entry in entries1: - if entry.endswith(".py"): - entries2.append(entry) - else: - path = os.path.join(cwd,entry) - sys.path.append(path) - subdir = [entry] - scripts = [script for script in os.listdir(path) if - script.startswith("tdemo_") and - script.endswith(".py")] - entries2.append(subdir+scripts) - return entries2 - -def showDemoHelp(): - view_file(demo.root, "Help on turtleDemo", "demohelp.txt") - -def showAboutDemo(): - view_file(demo.root, "About turtleDemo", "about_turtledemo.txt") - -def showAboutTurtle(): - view_file(demo.root, "About the new turtle module.", "about_turtle.txt") - -class DemoWindow(object): - - def __init__(self, filename=None): #, root=None): - self.root = root = turtle._root = Tk() - root.wm_protocol("WM_DELETE_WINDOW", self._destroy) - - ################# - self.mBar = Frame(root, relief=RAISED, borderwidth=2) - self.mBar.pack(fill=X) - - self.ExamplesBtn = self.makeLoadDemoMenu() - self.OptionsBtn = self.makeHelpMenu() - self.mBar.tk_menuBar(self.ExamplesBtn, self.OptionsBtn) #, QuitBtn) - - root.title('Python turtle-graphics examples') - ################# - self.left_frame = left_frame = Frame(root) - self.text_frame = text_frame = Frame(left_frame) - self.vbar = vbar =Scrollbar(text_frame, name='vbar') - self.text = text = Text(text_frame, - name='text', padx=5, wrap='none', - width=45) - vbar['command'] = text.yview - vbar.pack(side=LEFT, fill=Y) - ##################### - self.hbar = hbar =Scrollbar(text_frame, name='hbar', orient=HORIZONTAL) - hbar['command'] = text.xview - hbar.pack(side=BOTTOM, fill=X) - ##################### - text['yscrollcommand'] = vbar.set - text.config(font=txtfont) - text.config(xscrollcommand=hbar.set) - text.pack(side=LEFT, fill=Y, expand=1) - ##################### - self.output_lbl = Label(left_frame, height= 1,text=" --- ", bg = "#ddf", - font = ("Arial", 16, 'normal')) - self.output_lbl.pack(side=BOTTOM, expand=0, fill=X) - ##################### - text_frame.pack(side=LEFT, fill=BOTH, expand=0) - left_frame.pack(side=LEFT, fill=BOTH, expand=0) - self.graph_frame = g_frame = Frame(root) - - turtle._Screen._root = g_frame - turtle._Screen._canvas = turtle.ScrolledCanvas(g_frame, 800, 600, 1000, 800) - #xturtle.Screen._canvas.pack(expand=1, fill="both") - self.screen = _s_ = turtle.Screen() -##### - turtle.TurtleScreen.__init__(_s_, _s_._canvas) -##### - self.scanvas = _s_._canvas - #xturtle.RawTurtle.canvases = [self.scanvas] - turtle.RawTurtle.screens = [_s_] - - self.scanvas.pack(side=TOP, fill=BOTH, expand=1) - - self.btn_frame = btn_frame = Frame(g_frame, height=100) - self.start_btn = Button(btn_frame, text=" START ", font=btnfont, fg = "white", - disabledforeground = "#fed", command=self.startDemo) - self.start_btn.pack(side=LEFT, fill=X, expand=1) - self.stop_btn = Button(btn_frame, text=" STOP ", font=btnfont, fg = "white", - disabledforeground = "#fed", command = self.stopIt) - self.stop_btn.pack(side=LEFT, fill=X, expand=1) - self.clear_btn = Button(btn_frame, text=" CLEAR ", font=btnfont, fg = "white", - disabledforeground = "#fed", command = self.clearCanvas) - self.clear_btn.pack(side=LEFT, fill=X, expand=1) - - self.btn_frame.pack(side=TOP, fill=BOTH, expand=0) - self.graph_frame.pack(side=TOP, fill=BOTH, expand=1) - - Percolator(text).insertfilter(ColorDelegator()) - self.dirty = False - self.exitflag = False - if filename: - self.loadfile(filename) - self.configGUI(NORMAL, DISABLED, DISABLED, DISABLED, - "Choose example from menu", "black") - self.state = STARTUP - - def _destroy(self): - self.root.destroy() - sys.exit() - - def configGUI(self, menu, start, stop, clear, txt="", color="blue"): - self.ExamplesBtn.config(state=menu) - - self.start_btn.config(state=start) - if start==NORMAL: - self.start_btn.config(bg="#d00") - else: - self.start_btn.config(bg="#fca") - - self.stop_btn.config(state=stop) - if stop==NORMAL: - self.stop_btn.config(bg="#d00") - else: - self.stop_btn.config(bg="#fca") - self.clear_btn.config(state=clear) - - self.clear_btn.config(state=clear) - if clear==NORMAL: - self.clear_btn.config(bg="#d00") - else: - self.clear_btn.config(bg="#fca") - - self.output_lbl.config(text=txt, fg=color) - - - def makeLoadDemoMenu(self): - CmdBtn = Menubutton(self.mBar, text='Examples', underline=0, font=menufont) - CmdBtn.pack(side=LEFT, padx="2m") - CmdBtn.menu = Menu(CmdBtn) - - for entry in getExampleEntries(): - def loadexample(x): - def emit(): - self.loadfile(x) - return emit - if isinstance(entry,str): - CmdBtn.menu.add_command(label=entry[6:-3], underline=0, font=menufont, - command=loadexample(entry)) - else: - _dir, entries = entry[0], entry[1:] - CmdBtn.menu.choices = Menu(CmdBtn.menu) - for e in entries: - CmdBtn.menu.choices.add_command(label=e[6:-3], underline=0, font=menufont, - command = loadexample(os.path.join(_dir,e))) - - CmdBtn.menu.add_cascade(label=_dir[6:], - menu = CmdBtn.menu.choices, font=menufont ) - - CmdBtn['menu'] = CmdBtn.menu - return CmdBtn - - - def makeHelpMenu(self): - CmdBtn = Menubutton(self.mBar, text='Help', underline=0, font = menufont) - CmdBtn.pack(side=LEFT, padx='2m') - CmdBtn.menu = Menu(CmdBtn) - - CmdBtn.menu.add_command(label='About turtle.py', font=menufont, command=showAboutTurtle) - CmdBtn.menu.add_command(label='turtleDemo - Help', font=menufont, command=showDemoHelp) - CmdBtn.menu.add_command(label='About turtleDemo', font=menufont, command=showAboutDemo) - - CmdBtn['menu'] = CmdBtn.menu - return CmdBtn - - def refreshCanvas(self): - if not self.dirty: return - self.screen.clear() - #self.screen.mode("standard") - self.dirty=False - - def loadfile(self,filename): - self.refreshCanvas() - if os.path.exists(filename) and not os.path.isdir(filename): - # load and display file text - f = open(filename,'r') - chars = f.read() - f.close() - self.text.delete("1.0", "end") - self.text.insert("1.0",chars) - direc, fname = os.path.split(filename) - self.root.title(fname[6:-3]+" - a Python turtle graphics example") - self.module = __import__(fname[:-3]) - reload(self.module) - self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED, - "Press start button", "red") - self.state = READY - - def startDemo(self): - self.refreshCanvas() - self.dirty = True - turtle.TurtleScreen._RUNNING = True - self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED, - "demo running...", "black") - self.screen.clear() - self.screen.mode("standard") - self.state = RUNNING - - try: - result = self.module.main() - if result == "EVENTLOOP": - self.state = EVENTDRIVEN - else: - self.state = DONE - except turtle.Terminator: - self.state = DONE - result = "stopped!" - if self.state == DONE: - self.configGUI(NORMAL, NORMAL, DISABLED, NORMAL, - result) - elif self.state == EVENTDRIVEN: - self.exitflag = True - self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED, - "use mouse/keys or STOP", "red") - - def clearCanvas(self): - self.refreshCanvas() - self.screen._delete("all") - self.scanvas.config(cursor="") - self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED) - - def stopIt(self): - if self.exitflag: - self.clearCanvas() - self.exitflag = False - self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED, - "STOPPED!", "red") - turtle.TurtleScreen._RUNNING = False - #print "stopIT: exitflag = True" - else: - turtle.TurtleScreen._RUNNING = False - #print "stopIt: exitflag = False" - -if __name__ == '__main__': - demo = DemoWindow() - RUN = True - while RUN: - try: - #print("ENTERING mainloop") - demo.root.mainloop() - except AttributeError: - #print("AttributeError!- WAIT A MOMENT!") - time.sleep(0.3) - print("GOING ON ..") - demo.ckearCanvas() - except TypeError: - demo.screen._delete("all") - #print("CRASH!!!- WAIT A MOMENT!") - time.sleep(0.3) - #print("GOING ON ..") - demo.clearCanvas() - except: - print("BYE!") - RUN = False diff --git a/Demo/turtle/turtledemo_two_canvases.py b/Demo/turtle/turtledemo_two_canvases.py deleted file mode 100644 index 57ecb1d..0000000 --- a/Demo/turtle/turtledemo_two_canvases.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/python -## DEMONSTRATES USE OF 2 CANVASES, SO CANNOT BE RUN IN DEMOVIEWER! -"""turtle example: Using TurtleScreen and RawTurtle -for drawing on two distinct canvases. -""" -from turtle import TurtleScreen, RawTurtle, TK - -root = TK.Tk() -cv1 = TK.Canvas(root, width=300, height=200, bg="#ddffff") -cv2 = TK.Canvas(root, width=300, height=200, bg="#ffeeee") -cv1.pack() -cv2.pack() - -s1 = TurtleScreen(cv1) -s1.bgcolor(0.85, 0.85, 1) -s2 = TurtleScreen(cv2) -s2.bgcolor(1, 0.85, 0.85) - -p = RawTurtle(s1) -q = RawTurtle(s2) - -p.color("red", (1, 0.85, 0.85)) -p.width(3) -q.color("blue", (0.85, 0.85, 1)) -q.width(3) - -for t in p,q: - t.shape("turtle") - t.lt(36) - -q.lt(180) - -for t in p, q: - t.begin_fill() -for i in range(5): - for t in p, q: - t.fd(50) - t.lt(72) -for t in p,q: - t.end_fill() - t.lt(54) - t.pu() - t.bk(50) - -## Want to get some info? - -print(s1, s2) -print(p, q) -print(s1.turtles()) -print(s2.turtles()) - -TK.mainloop() diff --git a/Demo/xml/elem_count.py b/Demo/xml/elem_count.py deleted file mode 100644 index 99d6ca9..0000000 --- a/Demo/xml/elem_count.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -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 - -class FancyCounter(handler.ContentHandler): - - def __init__(self): - self._elems = 0 - self._attrs = 0 - self._elem_types = defaultdict(int) - self._attr_types = defaultdict(int) - - def startElement(self, name, attrs): - self._elems += 1 - self._attrs += len(attrs) - self._elem_types[name] += 1 - - for name in attrs.keys(): - self._attr_types[name] += 1 - - def endDocument(self): - print("There were", self._elems, "elements.") - print("There were", self._attrs, "attributes.") - - print("---ELEMENT TYPES") - for pair in self._elem_types.items(): - print("%20s %d" % pair) - - print("---ATTRIBUTE TYPES") - for pair in self._attr_types.items(): - print("%20s %d" % pair) - -if __name__ == '__main__': - parser = make_parser() - parser.setContentHandler(FancyCounter()) - parser.parse(sys.argv[1]) diff --git a/Demo/xml/roundtrip.py b/Demo/xml/roundtrip.py deleted file mode 100644 index 801c009..0000000 --- a/Demo/xml/roundtrip.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -A simple demo that reads in an XML document and spits out an equivalent, -but not necessarily identical, document. -""" - -import sys - -from xml.sax import saxutils, handler, make_parser - -# --- The ContentHandler - -class ContentGenerator(handler.ContentHandler): - - def __init__(self, out=sys.stdout): - handler.ContentHandler.__init__(self) - self._out = out - - # ContentHandler methods - - def startDocument(self): - self._out.write('<?xml version="1.0" encoding="iso-8859-1"?>\n') - - def startElement(self, name, attrs): - self._out.write('<' + name) - for (name, value) in attrs.items(): - self._out.write(' %s="%s"' % (name, saxutils.escape(value))) - self._out.write('>') - - def endElement(self, name): - self._out.write('</%s>' % name) - - def characters(self, content): - self._out.write(saxutils.escape(content)) - - def ignorableWhitespace(self, content): - self._out.write(content) - - def processingInstruction(self, target, data): - self._out.write('<?%s %s?>' % (target, data)) - -# --- The main program - -if __name__ == '__main__': - parser = make_parser() - parser.setContentHandler(ContentGenerator()) - parser.parse(sys.argv[1]) diff --git a/Demo/xml/rss2html.py b/Demo/xml/rss2html.py deleted file mode 100644 index 49cd154..0000000 --- a/Demo/xml/rss2html.py +++ /dev/null @@ -1,97 +0,0 @@ -""" -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 = """\ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<html> -<head> - <title>%s</title> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -</head> - -<body> -<h1>%s</h1> -""" - -bottom = """ -</ul> - -<hr> -<address> -Converted to HTML by rss2html.py. -</address> - -</body> -</html> -""" - -# --- The ContentHandler - -class RSSHandler(handler.ContentHandler): - - def __init__(self, out=sys.stdout): - handler.ContentHandler.__init__(self) - self._out = out - - self._text = "" - self._parent = None - self._list_started = False - self._title = None - self._link = None - self._descr = "" - - # ContentHandler methods - - def startElement(self, name, attrs): - if name == "channel" or name == "image" or name == "item": - self._parent = name - - self._text = "" - - def endElement(self, name): - if self._parent == "channel": - if name == "title": - self._out.write(top % (self._text, self._text)) - elif name == "description": - self._out.write("<p>%s</p>\n" % self._text) - - elif self._parent == "item": - if name == "title": - self._title = self._text - elif name == "link": - self._link = self._text - elif name == "description": - self._descr = self._text - elif name == "item": - if not self._list_started: - self._out.write("<ul>\n") - self._list_started = True - - self._out.write(' <li><a href="%s">%s</a> %s\n' % - (self._link, self._title, self._descr)) - - self._title = None - self._link = None - self._descr = "" - - if name == "rss": - self._out.write(bottom) - - def characters(self, content): - self._text = self._text + content - -# --- Main program - -if __name__ == '__main__': - parser = make_parser() - parser.setContentHandler(RSSHandler()) - parser.parse(sys.argv[1]) diff --git a/Demo/zlib/minigzip.py b/Demo/zlib/minigzip.py deleted file mode 100755 index 28d8b26..0000000 --- a/Demo/zlib/minigzip.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env python -# Demo program for zlib; it compresses or decompresses files, but *doesn't* -# delete the original. This doesn't support all of gzip's options. -# -# The 'gzip' module in the standard library provides a more complete -# implementation of gzip-format files. - -import zlib, sys, os - -FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16 - -def write32(output, value): - output.write(chr(value & 255)) ; value=value // 256 - output.write(chr(value & 255)) ; value=value // 256 - output.write(chr(value & 255)) ; value=value // 256 - output.write(chr(value & 255)) - -def read32(input): - v = ord(input.read(1)) - v += (ord(input.read(1)) << 8 ) - v += (ord(input.read(1)) << 16) - v += (ord(input.read(1)) << 24) - return v - -def compress (filename, input, output): - output.write('\037\213\010') # Write the header, ... - output.write(chr(FNAME)) # ... flag byte ... - - statval = os.stat(filename) # ... modification time ... - mtime = statval[8] - write32(output, mtime) - output.write('\002') # ... slowest compression alg. ... - output.write('\377') # ... OS (=unknown) ... - output.write(filename+'\000') # ... original filename ... - - crcval = zlib.crc32("") - compobj = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS, - zlib.DEF_MEM_LEVEL, 0) - while True: - data = input.read(1024) - if data == "": - break - crcval = zlib.crc32(data, crcval) - output.write(compobj.compress(data)) - output.write(compobj.flush()) - write32(output, crcval) # ... the CRC ... - write32(output, statval[6]) # and the file size. - -def decompress (input, output): - magic = input.read(2) - if magic != '\037\213': - print('Not a gzipped file') - sys.exit(0) - if ord(input.read(1)) != 8: - print('Unknown compression method') - sys.exit(0) - flag = ord(input.read(1)) - input.read(4+1+1) # Discard modification time, - # extra flags, and OS byte. - if flag & FEXTRA: - # Read & discard the extra field, if present - xlen = ord(input.read(1)) - xlen += 256*ord(input.read(1)) - input.read(xlen) - if flag & FNAME: - # Read and discard a null-terminated string containing the filename - while True: - s = input.read(1) - if s == '\0': break - if flag & FCOMMENT: - # Read and discard a null-terminated string containing a comment - while True: - s=input.read(1) - if s=='\0': break - if flag & FHCRC: - input.read(2) # Read & discard the 16-bit header CRC - - decompobj = zlib.decompressobj(-zlib.MAX_WBITS) - crcval = zlib.crc32("") - length = 0 - while True: - data=input.read(1024) - if data == "": - break - decompdata = decompobj.decompress(data) - output.write(decompdata) - length += len(decompdata) - crcval = zlib.crc32(decompdata, crcval) - - decompdata = decompobj.flush() - output.write(decompdata) - length += len(decompdata) - crcval = zlib.crc32(decompdata, crcval) - - # We've read to the end of the file, so we have to rewind in order - # to reread the 8 bytes containing the CRC and the file size. The - # decompressor is smart and knows when to stop, so feeding it - # extra data is harmless. - input.seek(-8, 2) - crc32 = read32(input) - isize = read32(input) - if crc32 != crcval: - print('CRC check failed.') - if isize != length: - print('Incorrect length of data produced') - -def main(): - if len(sys.argv)!=2: - print('Usage: minigzip.py <filename>') - print(' The file will be compressed or decompressed.') - sys.exit(0) - - filename = sys.argv[1] - if filename.endswith('.gz'): - compressing = False - outputname = filename[:-3] - else: - compressing = True - outputname = filename + '.gz' - - input = open(filename, 'rb') - output = open(outputname, 'wb') - - if compressing: - compress(filename, input, output) - else: - decompress(input, output) - - input.close() - output.close() - -if __name__ == '__main__': - main() diff --git a/Demo/zlib/zlibdemo.py b/Demo/zlib/zlibdemo.py deleted file mode 100755 index 53463dd..0000000 --- a/Demo/zlib/zlibdemo.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python - -# Takes an optional filename, defaulting to this file itself. -# Reads the file and compresses the content using level 1 and level 9 -# compression, printing a summary of the results. - -import zlib, sys - -def main(): - if len(sys.argv) > 1: - filename = sys.argv[1] - else: - filename = sys.argv[0] - print('Reading', filename) - - f = open(filename, 'rb') # Get the data to compress - s = f.read() - f.close() - - # First, we'll compress the string in one step - comptext = zlib.compress(s, 1) - decomp = zlib.decompress(comptext) - - print('1-step compression: (level 1)') - print(' Original:', len(s), 'Compressed:', len(comptext), end=' ') - print('Uncompressed:', len(decomp)) - - # Now, let's compress the string in stages; set chunk to work in smaller steps - - chunk = 256 - compressor = zlib.compressobj(9) - decompressor = zlib.decompressobj() - comptext = decomp = '' - for i in range(0, len(s), chunk): - comptext = comptext+compressor.compress(s[i:i+chunk]) - # Don't forget to call flush()!! - comptext = comptext + compressor.flush() - - for i in range(0, len(comptext), chunk): - decomp = decomp + decompressor.decompress(comptext[i:i+chunk]) - decomp=decomp+decompressor.flush() - - print('Progressive compression (level 9):') - print(' Original:', len(s), 'Compressed:', len(comptext), end=' ') - print('Uncompressed:', len(decomp)) - -if __name__ == '__main__': - main() |