Kaydet (Commit) 856898b3 authored tarafından Georg Brandl's avatar Georg Brandl

Harmonize docstrings. Move redemo from Tools/scripts to Tools/demo. Add a…

Harmonize docstrings.  Move redemo from Tools/scripts to Tools/demo.  Add a README file to Tools/demo.
üst a3fe8e0b
This directory contains a collection of demonstration scripts for
various aspects of Python programming.
beer.py Well-known programming example: Bottles of beer.
eiffel.py Python advanced magic: A metaclass for Eiffel post/preconditions.
hanoi.py Well-known programming example: Towers of Hanoi.
life.py Curses programming: Simple game-of-life.
markov.py Algorithms: Markov chain simulation.
mcast.py Network programming: Send and receive UDP multicast packets.
queens.py Well-known programming example: N-Queens problem.
redemo.py Regular Expressions: GUI script to test regexes.
rpython.py Network programming: Small client for remote code execution.
rpythond.py Network programming: Small server for remote code execution.
sortvisu.py GUI programming: Visualization of different sort algorithms.
ss1.py GUI/Application programming: A simple spreadsheet application.
vector.py Python basics: A vector class with demonstrating special methods.
\ No newline at end of file
#! /usr/bin/env python3 #!/usr/bin/env python3
# By GvR, demystified after a version by Fredrik Lundh. """
A Python version of the classic "bottles of beer on the wall" programming
example.
By Guido van Rossum, demystified after a version by Fredrik Lundh.
"""
import sys import sys
......
"""Support Eiffel-style preconditions and postconditions.""" #!/usr/bin/env python3
"""
Support Eiffel-style preconditions and postconditions for functions.
An example for Python metaclasses.
"""
import unittest
from types import FunctionType as function from types import FunctionType as function
class EiffelBaseMetaClass(type): class EiffelBaseMetaClass(type):
def __new__(meta, name, bases, dict): def __new__(meta, name, bases, dict):
meta.convert_methods(dict) meta.convert_methods(dict)
return super(EiffelBaseMetaClass, meta).__new__(meta, name, bases, return super(EiffelBaseMetaClass, meta).__new__(
dict) meta, name, bases, dict)
@classmethod @classmethod
def convert_methods(cls, dict): def convert_methods(cls, dict):
...@@ -31,6 +38,7 @@ class EiffelBaseMetaClass(type): ...@@ -31,6 +38,7 @@ class EiffelBaseMetaClass(type):
if pre or post: if pre or post:
dict[k] = cls.make_eiffel_method(dict[m], pre, post) dict[k] = cls.make_eiffel_method(dict[m], pre, post)
class EiffelMetaClass1(EiffelBaseMetaClass): class EiffelMetaClass1(EiffelBaseMetaClass):
# an implementation of the "eiffel" meta class that uses nested functions # an implementation of the "eiffel" meta class that uses nested functions
...@@ -39,16 +47,17 @@ class EiffelMetaClass1(EiffelBaseMetaClass): ...@@ -39,16 +47,17 @@ class EiffelMetaClass1(EiffelBaseMetaClass):
def method(self, *args, **kwargs): def method(self, *args, **kwargs):
if pre: if pre:
pre(self, *args, **kwargs) pre(self, *args, **kwargs)
x = func(self, *args, **kwargs) rv = func(self, *args, **kwargs)
if post: if post:
post(self, x, *args, **kwargs) post(self, rv, *args, **kwargs)
return x return rv
if func.__doc__: if func.__doc__:
method.__doc__ = func.__doc__ method.__doc__ = func.__doc__
return method return method
class EiffelMethodWrapper: class EiffelMethodWrapper:
def __init__(self, inst, descr): def __init__(self, inst, descr):
...@@ -58,7 +67,8 @@ class EiffelMethodWrapper: ...@@ -58,7 +67,8 @@ class EiffelMethodWrapper:
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
return self._descr.callmethod(self._inst, args, kwargs) return self._descr.callmethod(self._inst, args, kwargs)
class EiffelDescriptor(object):
class EiffelDescriptor:
def __init__(self, func, pre, post): def __init__(self, func, pre, post):
self._func = func self._func = func
...@@ -79,63 +89,58 @@ class EiffelDescriptor(object): ...@@ -79,63 +89,58 @@ class EiffelDescriptor(object):
self._post(inst, x, *args, **kwargs) self._post(inst, x, *args, **kwargs)
return x return x
class EiffelMetaClass2(EiffelBaseMetaClass): class EiffelMetaClass2(EiffelBaseMetaClass):
# an implementation of the "eiffel" meta class that uses descriptors # an implementation of the "eiffel" meta class that uses descriptors
make_eiffel_method = EiffelDescriptor make_eiffel_method = EiffelDescriptor
def _test(metaclass):
class Eiffel(metaclass=metaclass): class Tests(unittest.TestCase):
pass
def testEiffelMetaClass1(self):
class Test(Eiffel): self._test(EiffelMetaClass1)
def m(self, arg): def testEiffelMetaClass2(self):
"""Make it a little larger""" self._test(EiffelMetaClass2)
return arg + 1
def _test(self, metaclass):
def m2(self, arg): class Eiffel(metaclass=metaclass):
"""Make it a little larger""" pass
return arg + 1
class Test(Eiffel):
def m2_pre(self, arg): def m(self, arg):
assert arg > 0 """Make it a little larger"""
return arg + 1
def m2_post(self, result, arg):
assert result > arg def m2(self, arg):
"""Make it a little larger"""
class Sub(Test): return arg + 1
def m2(self, arg):
return arg**2 def m2_pre(self, arg):
def m2_post(self, Result, arg): assert arg > 0
super(Sub, self).m2_post(Result, arg)
assert Result < 100 def m2_post(self, result, arg):
assert result > arg
t = Test()
t.m(1) class Sub(Test):
t.m2(1) def m2(self, arg):
try: return arg**2
t.m2(0)
except AssertionError: def m2_post(self, Result, arg):
pass super(Sub, self).m2_post(Result, arg)
else: assert Result < 100
assert False
t = Test()
s = Sub() self.assertEqual(t.m(1), 2)
try: self.assertEqual(t.m2(1), 2)
s.m2(1) self.assertRaises(AssertionError, t.m2, 0)
except AssertionError:
pass # result == arg s = Sub()
else: self.assertRaises(AssertionError, s.m2, 1)
assert False self.assertRaises(AssertionError, s.m2, 10)
try: self.assertEqual(s.m2(5), 25)
s.m2(10)
except AssertionError:
pass # result == 100
else:
assert False
s.m2(5)
if __name__ == "__main__": if __name__ == "__main__":
_test(EiffelMetaClass1) unittest.main()
_test(EiffelMetaClass2)
# Animated Towers of Hanoi using Tk with optional bitmap file in #!/usr/bin/env python3
# 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 * Animated Towers of Hanoi using Tk with optional bitmap file in background.
Usage: hanoi.py [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.
"""
from tkinter import Tk, Canvas
# Basic Towers-of-Hanoi algorithm: move n pieces from a to b, using c # Basic Towers-of-Hanoi algorithm: move n pieces from a to b, using c
# as temporary. For each move, call report() # as temporary. For each move, call report()
...@@ -123,7 +124,6 @@ class Tkhanoi: ...@@ -123,7 +124,6 @@ class Tkhanoi:
self.pegstate[b].append(i) self.pegstate[b].append(i)
# Main program
def main(): def main():
import sys import sys
......
#!/usr/bin/env python3 #!/usr/bin/env python3
# life.py -- A curses-based version of Conway's Game of Life.
# Contributed by AMK """
# Mouse support and color by Dafydd Crosby A curses-based version of Conway's Game of Life.
#
# An empty board will be displayed, and the following commands are available: An empty board will be displayed, and the following commands are available:
# E : Erase the board E : Erase the board
# R : Fill the board randomly R : Fill the board randomly
# S : Step for a single generation S : Step for a single generation
# C : Update continuously until a key is struck C : Update continuously until a key is struck
# Q : Quit Q : Quit
# Cursor keys : Move the cursor around the board Cursor keys : Move the cursor around the board
# Space or Enter : Toggle the contents of the cursor's position Space or Enter : Toggle the contents of the cursor's position
#
# TODO : Contributed by Andrew Kuchling, Mouse support and color by Dafydd Crosby.
# Make board updates faster """
#
import random, string, traceback
import curses import curses
import random
class LifeBoard: class LifeBoard:
"""Encapsulates a Life board """Encapsulates a Life board
...@@ -31,7 +31,7 @@ class LifeBoard: ...@@ -31,7 +31,7 @@ class LifeBoard:
next generation. Then display the state next generation. Then display the state
of the board and refresh the screen. of the board and refresh the screen.
erase() -- clear the entire board erase() -- clear the entire board
makeRandom() -- fill the board randomly make_random() -- fill the board randomly
set(y,x) -- set the given cell to Live; doesn't refresh the screen 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 toggle(y,x) -- change the given cell from live to dead, or vice
versa, and refresh the screen display versa, and refresh the screen display
...@@ -53,7 +53,7 @@ class LifeBoard: ...@@ -53,7 +53,7 @@ class LifeBoard:
# Draw a border around the board # Draw a border around the board
border_line = '+'+(self.X*'-')+'+' border_line = '+'+(self.X*'-')+'+'
self.scr.addstr(0, 0, border_line) self.scr.addstr(0, 0, border_line)
self.scr.addstr(self.Y+1,0, border_line) self.scr.addstr(self.Y+1, 0, border_line)
for y in range(0, self.Y): for y in range(0, self.Y):
self.scr.addstr(1+y, 0, '|') self.scr.addstr(1+y, 0, '|')
self.scr.addstr(1+y, self.X+1, '|') self.scr.addstr(1+y, self.X+1, '|')
...@@ -62,21 +62,21 @@ class LifeBoard: ...@@ -62,21 +62,21 @@ class LifeBoard:
def set(self, y, x): def set(self, y, x):
"""Set a cell to the live state""" """Set a cell to the live state"""
if x<0 or self.X<=x or y<0 or self.Y<=y: if x<0 or self.X<=x or y<0 or self.Y<=y:
raise ValueError("Coordinates out of range %i,%i"% (y,x)) raise ValueError("Coordinates out of range %i,%i"% (y, x))
self.state[x,y] = 1 self.state[x,y] = 1
def toggle(self, y, x): def toggle(self, y, x):
"""Toggle a cell's state between live and dead""" """Toggle a cell's state between live and dead"""
if x<0 or self.X<=x or y<0 or self.Y<=y: if x < 0 or self.X <= x or y < 0 or self.Y <= y:
raise ValueError("Coordinates out of range %i,%i"% (y,x)) raise ValueError("Coordinates out of range %i,%i"% (y, x))
if (x,y) in self.state: if (x, y) in self.state:
del self.state[x,y] del self.state[x, y]
self.scr.addch(y+1, x+1, ' ') self.scr.addch(y+1, x+1, ' ')
else: else:
self.state[x,y] = 1 self.state[x, y] = 1
if curses.has_colors(): if curses.has_colors():
#Let's pick a random color! # Let's pick a random color!
self.scr.attrset(curses.color_pair(random.randrange(1,7))) self.scr.attrset(curses.color_pair(random.randrange(1, 7)))
self.scr.addch(y+1, x+1, self.char) self.scr.addch(y+1, x+1, self.char)
self.scr.attrset(0) self.scr.attrset(0)
self.scr.refresh() self.scr.refresh()
...@@ -115,8 +115,9 @@ class LifeBoard: ...@@ -115,8 +115,9 @@ class LifeBoard:
# Birth # Birth
d[i,j] = 1 d[i,j] = 1
if curses.has_colors(): if curses.has_colors():
#Let's pick a random color! # Let's pick a random color!
self.scr.attrset(curses.color_pair(random.randrange(1,7))) self.scr.attrset(curses.color_pair(
random.randrange(1, 7)))
self.scr.addch(j+1, i+1, self.char) self.scr.addch(j+1, i+1, self.char)
self.scr.attrset(0) self.scr.attrset(0)
if not live: self.boring = 0 if not live: self.boring = 0
...@@ -128,7 +129,7 @@ class LifeBoard: ...@@ -128,7 +129,7 @@ class LifeBoard:
self.state = d self.state = d
self.scr.refresh() self.scr.refresh()
def makeRandom(self): def make_random(self):
"Fill the board with a random pattern" "Fill the board with a random pattern"
self.state = {} self.state = {}
for i in range(0, self.X): for i in range(0, self.X):
...@@ -152,9 +153,9 @@ def display_menu(stdscr, menu_y): ...@@ -152,9 +153,9 @@ def display_menu(stdscr, menu_y):
if curses.has_colors(): if curses.has_colors():
stdscr.attrset(curses.color_pair(1)) stdscr.attrset(curses.color_pair(1))
stdscr.addstr(menu_y, 4, stdscr.addstr(menu_y, 4,
'Use the cursor keys to move, and space or Enter to toggle a cell.') 'Use the cursor keys to move, and space or Enter to toggle a cell.')
stdscr.addstr(menu_y+1, 4, stdscr.addstr(menu_y+1, 4,
'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit') 'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit')
stdscr.attrset(0) stdscr.attrset(0)
def keyloop(stdscr): def keyloop(stdscr):
...@@ -186,10 +187,10 @@ def keyloop(stdscr): ...@@ -186,10 +187,10 @@ def keyloop(stdscr):
xpos, ypos = board.X//2, board.Y//2 xpos, ypos = board.X//2, board.Y//2
# Main loop: # Main loop:
while (1): while True:
stdscr.move(1+ypos, 1+xpos) # Move the cursor stdscr.move(1+ypos, 1+xpos) # Move the cursor
c = stdscr.getch() # Get a keystroke c = stdscr.getch() # Get a keystroke
if 0<c<256: if 0 < c < 256:
c = chr(c) c = chr(c)
if c in ' \n': if c in ' \n':
board.toggle(ypos, xpos) board.toggle(ypos, xpos)
...@@ -201,14 +202,14 @@ def keyloop(stdscr): ...@@ -201,14 +202,14 @@ def keyloop(stdscr):
# Activate nodelay mode; getch() will return -1 # Activate nodelay mode; getch() will return -1
# if no keystroke is available, instead of waiting. # if no keystroke is available, instead of waiting.
stdscr.nodelay(1) stdscr.nodelay(1)
while (1): while True:
c = stdscr.getch() c = stdscr.getch()
if c != -1: if c != -1:
break break
stdscr.addstr(0,0, '/') stdscr.addstr(0, 0, '/')
stdscr.refresh() stdscr.refresh()
board.display() board.display()
stdscr.addstr(0,0, '+') stdscr.addstr(0, 0, '+')
stdscr.refresh() stdscr.refresh()
stdscr.nodelay(0) # Disable nodelay mode stdscr.nodelay(0) # Disable nodelay mode
...@@ -219,18 +220,19 @@ def keyloop(stdscr): ...@@ -219,18 +220,19 @@ def keyloop(stdscr):
elif c in 'Qq': elif c in 'Qq':
break break
elif c in 'Rr': elif c in 'Rr':
board.makeRandom() board.make_random()
board.display(update_board=False) board.display(update_board=False)
elif c in 'Ss': elif c in 'Ss':
board.display() board.display()
else: pass # Ignore incorrect keys else: pass # Ignore incorrect keys
elif c == curses.KEY_UP and ypos>0: ypos -= 1 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_DOWN and ypos < board.Y-1: ypos += 1
elif c == curses.KEY_LEFT and xpos>0: xpos -= 1 elif c == curses.KEY_LEFT and xpos > 0: xpos -= 1
elif c == curses.KEY_RIGHT and xpos<board.X-1: xpos += 1 elif c == curses.KEY_RIGHT and xpos < board.X-1: xpos += 1
elif c == curses.KEY_MOUSE: elif c == curses.KEY_MOUSE:
(mouse_id, mouse_x, mouse_y, mouse_z, button_state) = curses.getmouse() mouse_id, mouse_x, mouse_y, mouse_z, button_state = curses.getmouse()
if (mouse_x>0 and mouse_x<board.X+1) and (mouse_y>0 and mouse_y<board.Y+1): if (mouse_x > 0 and mouse_x < board.X+1 and
mouse_y > 0 and mouse_y < board.Y+1):
xpos = mouse_x - 1 xpos = mouse_x - 1
ypos = mouse_y - 1 ypos = mouse_y - 1
board.toggle(ypos, xpos) board.toggle(ypos, xpos)
...@@ -245,6 +247,5 @@ def keyloop(stdscr): ...@@ -245,6 +247,5 @@ def keyloop(stdscr):
def main(stdscr): def main(stdscr):
keyloop(stdscr) # Enter the main loop keyloop(stdscr) # Enter the main loop
if __name__ == '__main__': if __name__ == '__main__':
curses.wrapper(main) curses.wrapper(main)
#! /usr/bin/env python3 #!/usr/bin/env python3
"""
Markov chain simulation of words or characters.
"""
class Markov: class Markov:
def __init__(self, histsize, choice): def __init__(self, histsize, choice):
......
#!/usr/bin/env python3 #!/usr/bin/env python3
#
# Send/receive UDP multicast packets. """
# Requires that your OS kernel supports IP multicast. Send/receive UDP multicast packets.
# Requires that your OS kernel supports IP multicast.
# Usage:
# mcast -s (sender, IPv4) Usage:
# mcast -s -6 (sender, IPv6) mcast -s (sender, IPv4)
# mcast (receivers, IPv4) mcast -s -6 (sender, IPv6)
# mcast -6 (receivers, IPv6) mcast (receivers, IPv4)
mcast -6 (receivers, IPv6)
"""
MYPORT = 8123 MYPORT = 8123
MYGROUP_4 = '225.0.0.250' MYGROUP_4 = '225.0.0.250'
......
#! /usr/bin/env python3 #!/usr/bin/env python3
"""N queens problem. """
N queens problem.
The (well-known) problem is due to Niklaus Wirth. The (well-known) problem is due to Niklaus Wirth.
This solution is inspired by Dijkstra (Structured Programming). It is This solution is inspired by Dijkstra (Structured Programming). It is
a classic recursive backtracking approach. a classic recursive backtracking approach.
""" """
N = 8 # Default; command line overrides N = 8 # Default; command line overrides
......
#! /usr/bin/env python3 #!/usr/bin/env python3
# Remote python client. """
# Execute Python commands remotely and send output back. Remote python client.
Execute Python commands remotely and send output back.
"""
import sys import sys
from socket import socket, AF_INET, SOCK_STREAM, SHUT_WR from socket import socket, AF_INET, SOCK_STREAM, SHUT_WR
......
#! /usr/bin/env python3 #!/usr/bin/env python3
# Remote python server. """
# Execute Python commands remotely and send output back. Remote python server.
# WARNING: This version has a gaping security hole -- it accepts requests Execute Python commands remotely and send output back.
# from any host on the Internet!
WARNING: This version has a gaping security hole -- it accepts requests
from any host on the Internet!
"""
import sys import sys
from socket import socket, AF_INET, SOCK_STREAM from socket import socket, AF_INET, SOCK_STREAM
......
#! /usr/bin/env python3 #!/usr/bin/env python3
"""Sorting algorithms visualizer using Tkinter. """
Sorting algorithms visualizer using Tkinter.
This module is comprised of three ``components'': This module is comprised of three ``components'':
...@@ -15,13 +16,11 @@ to its annotation methods; ...@@ -15,13 +16,11 @@ to its annotation methods;
- and a ``driver'' class which can be used as a Grail applet or as a - and a ``driver'' class which can be used as a Grail applet or as a
stand-alone application. stand-alone application.
""" """
from tkinter import * from tkinter import *
import random import random
XGRID = 10 XGRID = 10
YGRID = 10 YGRID = 10
WIDTH = 6 WIDTH = 6
......
"""SS1 -- a spreadsheet.""" #!/usr/bin/env python3
"""
SS1 -- a spreadsheet-like application.
"""
import os import os
import re import re
......
#!/usr/bin/env python3
"""
A demonstration of classes and their special methods in Python.
"""
class Vec: class Vec:
""" A simple vector class """A simple vector class.
Instances of the Vec class can be constructed from numbers Instances of the Vec class can be constructed from numbers
>>> a = Vec(1, 2, 3) >>> a = Vec(1, 2, 3)
>>> b = Vec(3, 2, 1) >>> b = Vec(3, 2, 1)
......
...@@ -2,8 +2,6 @@ This directory contains a collection of executable Python scripts that are ...@@ -2,8 +2,6 @@ This directory contains a collection of executable Python scripts that are
useful while building, extending or managing Python. Some (e.g., dutree or lll) useful while building, extending or managing Python. Some (e.g., dutree or lll)
are also generally useful UNIX tools. are also generally useful UNIX tools.
See also the Demo/scripts directory!
2to3 Main script for running the 2to3 conversion tool 2to3 Main script for running the 2to3 conversion tool
analyze_dxp.py Analyzes the result of sys.getdxp() analyze_dxp.py Analyzes the result of sys.getdxp()
byext.py Print lines/words/chars stats of files by extension byext.py Print lines/words/chars stats of files by extension
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment