durusmail: qp: Re: Fwd: qp Sudoku - a Session demo
Re: Fwd: qp Sudoku - a Session demo
2006-04-27
2006-04-28
Re: Fwd: qp Sudoku - a Session demo
Tristan Short
2006-04-27
David,

That is a much better way of putting a dictionary in a Session - thanks, new
source included below. Is there anything else you would do differently/better,
not that there is much to this app? Also is there a qp site for qp addons and
recipes similar to this?

--------------------------------
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.session import Session
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
from qp.lib.spec import add_getters
from durus.persistent_dict import PersistentDict

class MySession(Session):
     game_is = PersistentDict
     def __init__(self):
         Session.__init__(self)
         self.game = PersistentDict()

add_getters(MySession)

class SitePublisher (Publisher):
    configuration = dict(
        durus_address=('localhost', 7000),
        http_address=('', 8000),
        as_https_address=('localhost', 9000),
        https_address=('localhost', 10000),
        )

    def create_session(self):
        return MySession()

class Cell:
    def __init__(self, id):
        self.id = id
        self.poss = [1,2,3,4,5,6,7,8,9]
        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 demonstrates a qp Session.
    Provided as is by Tristan Short - hope you enjoy.
    """

    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()
        game = sess.get_game()
        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 game.has_key('cells'):
            cells = game['cells']
        else:
            cells = {}
            for cell_name in cnames:
                cell = Cell(cell_name)
                cells[cell_name] = cell
            game['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" "" "
" for poss in cells[cname].poss: '%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 do clear_authentication() sess.clear_authentication() resp.expire_cookie(get_site().get_name()) redirect('.')
reply