Begin forwarded message:
> From: Tristan Short
> Date: April 26, 2006 7:53:19 PM EDT
> To: dbinger@mems-exchange.org
> Subject: Fw: qp Sudoku - a Session demo
>
> David,
>
> Forwarding this on to you just in case the durusmail spam filter
> gets the better of me...
The trick, I think, is to send it from the address of your
list subscription. Thanks for the post.
>
> Regards,
>
> Tristan
>
>
>
>
>
> Begin forwarded message:
>
> Date: Thu, 27 Apr 2006 00:42:46 +0100
> From: Tristan Short
> To: qp@mems-exchange.org
> Subject: qp Sudoku - a Session demo
>
>
>
> Just thought I'd share this simple Sudoku app I put together to
> explore basic Session handling in qp. Not even sure if I am using
> the Session class correctly, but anyway...
>
> (the page layout works fine in firefox (but only just). I do not
> expect it to look any good in IE)
>
> ps. Thanks for giving us qp. I really like it.
>
> --------------------------------
> qp_sites/sudoku/__init__.py
> --------------------------------
> from qpy.compile import compile_qpy_files
> compile_qpy_files(__path__[0])
>
> from qp.sites.sudoku.slash import SitePublisher, SiteRootDirectory
> used = [SitePublisher, SiteRootDirectory] # To mute qpcheck.py
>
> --------------------------------
> qp_sites/sudoku/slash.qpy
> --------------------------------
>
> from qp.pub.publish import Publisher
> from qp.pub.common import get_site, get_session, header, footer,
> get_request, get_response, redirect, get_path
> from qp.fill.directory import Directory
> from qp.pub.user import User
>
>
> class SitePublisher (Publisher):
> configuration = dict(
> durus_address=('localhost', 7000),
> http_address=('', 8000),
> as_https_address=('localhost', 9000),
> https_address=('localhost', 10000),
> )
>
> class Cell:
> def __init__(self, id):
> self.id = id
> self.poss = [1,2,3,4,5,6,7,8,9] # list of possible values
> self.val = "_"
> self.msg = None
>
> def del_poss(self, num):
> num = int(num)
> if num in self.poss:
> del self.poss[self.poss.index(num)]
>
> class SiteRootDirectory (Directory):
> """
> This site is a simple Sudoku app (only 3 rules computed). It
> can solve easy-medium difficulty puzzles and helps remove the cruft
> in hard puzzles.
>
> The app also demonstrates a qp Session.
> Provided as is by Tristan Short - hope you enjoy, feel free to
> hack it.
>
> ps. I guess I need to mention that qp.pub.session.Session must
> be changed to inherit from
> durus.persistent.persistent_dict.PersistentDict and not just
> Persistent.
> i.e.
> class Session(PersistentDict):
> and not... class Session(Persistent):
>
> If there is a better way to store data in Session without
> changing the qp.pub.session.Session class please let me know. (I am
> not a programmer, well not a good one at any rate)
> """
>
> def get_exports(self):
> yield ('', '_q_index', None, None)
> yield ('start_session', 'start_session', None, None)
> yield ('end_session', 'end_session', None, None)
>
>
> def _q_index [html] (self):
>
> sess = get_session()
> req = get_request()
> fields = req.fields
>
> cnames = []
> for a in range(1 , 10):
> for b in range(1 , 10):
> cell_name = 'c'+`a`+`b`
> cnames.append(cell_name)
>
> if sess.has_key('cells'): # IMPORTANT! #
> qp.pub.session.Session must inherit from
> durus.persistent.persistent_dict.PersistentDict and not just
> Persistent.
> cells = sess['cells']
> else:
> cells = {}
> for cell_name in cnames:
> cell = Cell(cell_name)
> cells[cell_name] = cell
> sess['cells'] = cells
>
>
> # create sets
> sets = {}
> # box sets
> sets['box1'] = ['c11', 'c12', 'c13', 'c14', 'c15', 'c16',
> 'c17', 'c18', 'c19']
> sets['box2'] = ['c21', 'c22', 'c23', 'c24', 'c25', 'c26',
> 'c27', 'c28', 'c29']
> sets['box3'] = ['c31', 'c32', 'c33', 'c34', 'c35', 'c36',
> 'c37', 'c38', 'c39']
> sets['box4'] = ['c41', 'c42', 'c43', 'c44', 'c45', 'c46',
> 'c47', 'c48', 'c49']
> sets['box5'] = ['c51', 'c52', 'c53', 'c54', 'c55', 'c56',
> 'c57', 'c58', 'c59']
> sets['box6'] = ['c61', 'c62', 'c63', 'c64', 'c65', 'c66',
> 'c67', 'c68', 'c69']
> sets['box7'] = ['c71', 'c72', 'c73', 'c74', 'c75', 'c76',
> 'c77', 'c78', 'c79']
> sets['box8'] = ['c81', 'c82', 'c83', 'c84', 'c85', 'c86',
> 'c87', 'c88', 'c89']
> sets['box9'] = ['c91', 'c92', 'c93', 'c94', 'c95', 'c96',
> 'c97', 'c98', 'c99']
> # row sets
> sets['row1'] = ['c11', 'c12', 'c13', 'c21', 'c22', 'c23',
> 'c31', 'c32', 'c33']
> sets['row2'] = ['c14', 'c15', 'c16', 'c24', 'c25', 'c26',
> 'c34', 'c35', 'c36']
> sets['row3'] = ['c17', 'c18', 'c19', 'c27', 'c28', 'c29',
> 'c37', 'c38', 'c39']
> sets['row4'] = ['c41', 'c42', 'c43', 'c51', 'c52', 'c53',
> 'c61', 'c62', 'c63']
> sets['row5'] = ['c44', 'c45', 'c46', 'c54', 'c55', 'c56',
> 'c64', 'c65', 'c66']
> sets['row6'] = ['c47', 'c48', 'c49', 'c57', 'c58', 'c59',
> 'c67', 'c68', 'c69']
> sets['row7'] = ['c71', 'c72', 'c73', 'c81', 'c82', 'c83',
> 'c91', 'c92', 'c93']
> sets['row8'] = ['c74', 'c75', 'c76', 'c84', 'c85', 'c86',
> 'c94', 'c95', 'c96']
> sets['row9'] = ['c77', 'c78', 'c79', 'c87', 'c88', 'c89',
> 'c97', 'c98', 'c99']
> # column sets
> sets['col1'] = ['c11', 'c14', 'c17', 'c41', 'c44', 'c47',
> 'c71', 'c74', 'c77']
> sets['col2'] = ['c12', 'c15', 'c18', 'c42', 'c45', 'c48',
> 'c72', 'c75', 'c78']
> sets['col3'] = ['c13', 'c16', 'c19', 'c43', 'c46', 'c49',
> 'c73', 'c76', 'c79']
> sets['col4'] = ['c21', 'c24', 'c27', 'c51', 'c54', 'c57',
> 'c81', 'c84', 'c87']
> sets['col5'] = ['c22', 'c25', 'c28', 'c52', 'c55', 'c58',
> 'c82', 'c85', 'c88']
> sets['col6'] = ['c23', 'c26', 'c29', 'c53', 'c56', 'c59',
> 'c83', 'c86', 'c89']
> sets['col7'] = ['c31', 'c34', 'c37', 'c61', 'c64', 'c67',
> 'c91', 'c94', 'c97']
> sets['col8'] = ['c32', 'c35', 'c38', 'c62', 'c65', 'c68',
> 'c92', 'c95', 'c98']
> sets['col9'] = ['c33', 'c36', 'c39', 'c63', 'c66', 'c69',
> 'c93', 'c96', 'c99']
>
> ## deal with entered data
> if fields.has_key('action'):
> if fields['action'] == 'select':
> cname = fields['cname']
> value = fields['value']
> cells[cname].val = value
> cells[cname].poss = []
>
> for set in sets.itervalues():
> if cname in set:
> for cellid in set:
> cells[cellid].del_poss(value)
>
> ## add tips
> for cname in cnames:
> p = 0 # numbers 1 to 10
> #cnt = 0 # count number of copies of number p
> cid_lst = []
> cellid_single = ('','') # holder for cellid that
> (potentially) has only copy of number p tup = (cellid, p)
> for set in sets.iteritems():
> if cname in set[1]:
> for p in range(1, 11):
> cid_lst = []
> for cellid in set[1]:
> if p in cells[cellid].poss:
> cid_lst.append(cellid)
> cellid_single = (cellid, p)
> if len(cid_lst) == 1:
> cells[cellid_single[0]].msg = "Only
> cell in set %s that can have value: %i" %(set[0], cellid_single[1])
>
> if ( len(cid_lst) == 2
> and set[0] in ['box1', 'box2', 'box3',
> 'box4', 'box5', 'box6', 'box7', 'box8', 'box9'] ):
> for set2 in sets.iteritems():
> if set2[0] == set[0]:
> pass
> elif cid_lst[0] in set2[1] and
> cid_lst[1] in set2[1]:
> for cellid2 in set2[1]:
> if cellid2 in cid_lst:
> pass # skip the double
> cells
> else:
> cells[cellid2].del_poss(p)
>
> if ( len(cid_lst) == 3
> and set[0] in ['box1', 'box2', 'box3',
> 'box4', 'box5', 'box6', 'box7', 'box8', 'box9'] ):
> for set2 in sets.iteritems():
> if set2[0] == set[0]:
> pass # skip box 'n' sets
> elif cid_lst[0] in set2[1] and
> cid_lst[1] in set2[1] and cid_lst[2] in set2[1]:
> for cellid2 in set2[1]:
> if cellid2 in cid_lst:
> pass # skip the double
> cells
> else:
> cells[cellid2].del_poss(p)
>
> # start rendering the page
> header(get_site().get_name())
> """
>
> """
>
>
> ''
> ' '
> ' '
> ' '
> 'A simple app to demonstrate qp
> session handling.'
> '
'
> ''
>
> ''
> ' '
>
> if sess.effective_user:
> ''
> 'Session active'
> else:
> ' '
> 'Session inactive'
>
> ' '
> ' | '
> ' '
> "qp Sudoku"
> ""
>
> a = 1
> for a in range(1 , 10):
> if a == 1 or a == 4 or a == 7:
> "\n"
> ""
> ""
> for b in range(1 , 10):
> cname = 'c'+`a`+`b`
> if b == 1 or b == 4 or b == 7:
> "\n"
>
> # paint boxes alternating background colours
> bgcolor = ""
> if (cname in sets['box1']
> or cname in sets['box3']
> or cname in sets['box5']
> or cname in sets['box7']
> or cname in sets['box9']):
> bgcolor = "bgcolor=#ffffdd"
> else:
> bgcolor = "bgcolor=#ffffff"
>
> tip = ""
> if cells[cname].msg or len(cells[cname].poss) == 1:
> tip = cells[cname].msg
> cells[cname].msg = None
> bgcolor = "bgcolor=pink"
> elif len(cells[cname].poss) == 0 and cells
> [cname].val == '_':
> bgcolor = "bgcolor=maroon"
>
> " height='58px'>"
>
> for poss in cells[cname].poss:
> ' title="%s" >%s ' %(cname, poss, tip, poss)
> ""
> " "
> "%s" %(cells[cname].val)
> " | "
> " "
> " | "
> " "
> ' |
'
> footer()
>
>
> def start_session(self):
> sess = get_session()
> user = User('anonymous')
> sess.set_authenticated(user)
> redirect(".")
>
>
> def end_session [html] (self):
> resp = get_response()
>
> sess = get_session() # just being clean. Not necessary
> to clear_authentication
> sess.clear_authentication()
>
> resp.expire_cookie(get_site().get_name())
> redirect('.')
>