Code included below.

Basically, I've created a series of "question" descriptors, which each
hold a managed value. This is so I can implement validation, and render
each field into html automatically for forms.

My problem is this: every instance of my "wizard" class has unique self
values, but they share the exact same descriptor values.

Meaning, if

t = Test("ar")
y = Test("ar")

t is y
False

t.age is y.age
True

t.age = 9
y.age
9

Code below. What am I not understanding?
-----------------------------------------

import datetime, re

class Question(object):
        def __init__(self, qtext, name, default=None, required=False,
max_length=None, choices=None):
                self._name = name
                self._qtext = qtext
                self._value = default
                self._error = None
                self._max_length = max_length
                self._required = required
                self._choices = choices

        def __get__(self, instance, owner):
                return self

        def __set__(self, instance, value):
                error = self.validate(value)
                if not error:
                        self._value = self.cast(value)
                        self._error = None
                else:
                        self._value = value
                        self._error = error
                        print error

        def __str__(self):
                return str(self._value)

        def __repr__(self):
                return str(self._value)

        def cast(self, value):
                return value

        def validate(self, value):
                return True

        def html(self):
                #ugly html renderer removed; irrelevant to problem
                return html

        def error(self):
                if self._error:
                        return True


class Q_Integer(Question):
        def validate(self, value):
                if self._required and not value:
                        return "Field is required."
                elif not value:
                        return None
                try:
                        int(value)
                        return None
                except:
                        return "Answer must be a whole number."

        def cast(self, value):
                if value:
                        return int(value)

class Q_Float(Question):
        def validate(self, value):
                if self._required and not value:
                        return "Field is required."
                elif not value:
                        return None
                try:
                        float(value)
                        return None
                except:
                        return "Answer must be a decimal number."

        def cast(self, value):
                if value:
                        return float(value)

class Q_Chars(Question):
        def validate(self, value):
                try:
                        if self._required and not value:
                                return "Field is required."
                        elif not value:
                                return None
                        if self._max_length:
                                if len(value) > self._max_length:
                                        return "Too many characters; max of %s 
allowed." %
self._max_length
                        return None
                except:
                        return "Invalid entry."

        def cast(self, value):
                if value:
                        return str(value)

class Q_Long(Question):
        def validate(self, value):
                try:
                        if self._required and not value:
                                return "Field is required."
                        elif not value:
                                return None
                except:
                        return "Invalid entry."

        def cast(self, value):
                if value:
                        return str(value)

        def html(self):
                #ugly html renderer removed; irrelevant to problem
                return html

class Q_Bool(Question):
        def validate(self, value):
                return None

        def cast(self, value):
                return bool(value)

        def html(self):
                #ugly html renderer removed; irrelevant to problem
                return html

class Q_Phone(Question):
        def validate(self, value):
                try:
                        if self._required and not value:
                                return "Field is required."
                        elif not value:
                                return None

                        pieces = value.split("-")
                        if len(pieces[0]) == 3 and len(pieces[1]) == 3 and 
len(pieces[2]) ==
4:
                                int(pieces[0])
                                int(pieces[1])
                                int(pieces[2])
                                return None
                        else:
                                return "Requires Valid Phone Number in 
XXX-XXX-XXXX format."
                except:
                        return "Requires Valid Phone Number in XXX-XXX-XXXX 
format."


class Q_Date(Question):
        def validate(self, value):
                try:
                        if self._required and not value:
                                return "Field is required."
                        elif not value:
                                return None

                        r = re.compile(r"\d{1,2}[-/.]\d{1,2}[-/.]\d{1,4}")
                        month, day, year =
r.findall(value)[0].replace("/","-").replace(".","-").split("-")
                        date = datetime.date(year=int(year), month=int(month), 
day=int(day)
)
                        return None
                except:
                        return "Requires valid date in mm-dd-yy format."

        def cast(self, value):
                if value:
                        r = re.compile(r"\d{1,2}[-/.]\d{1,2}[-/.]\d{1,4}")
                        month, day, year =
r.findall(value)[0].replace("/","-").replace(".","-").split("-")

                        year = int(year)
                        if year < 70:
                                year += 2000
                        elif year < 100:
                                year += 1000

                        date = datetime.date(year=int(year), month=int(month), 
day=int(day)
)

                        return date

        def __str__(self):
                date = self._value
                return "%s/%s/%s" % (date.month, date.day, date.year)

## Wizard Base Object

class Wizard(object):
        def __init__(self, action):
                self.action = action
                self.init_time = datetime.datetime.now()

        pagediv = "box"
        title = "A Dynamic Wizard"
        instructions = "There are no real instructions here. Sorry."

        grouping = [ ]

        def render_form(self):
                #ugly html renderer removed; irrelevant to problem
                return form

        def flatten(self, post):
                for key in post:
                        if not key == "command":
                                errors = ""
                                cblock = "self.%s = '%s'\n" % (key, post[key])
                                ab_save = compile( cblock, errors, 'exec')
                                exec(ab_save)

        def errorcheck(self):
                error = 0
                for section in self.grouping:
                        for question in section:
                                t = eval( "self.%s.validate(self.%s._value)" % 
(question, question)
)
                                if t:
                                        error = 1
                return error



C_CHOICES = (
        ("red", "Red"),
        ("blue", "Blue"),
        ("green", "Green"),
        )

class Test(Wizard):
        grouping = [
                [ 'age', 'weight' ],
                [ 'feet', 'inches' ],
                ['name', 'cash', 'fav_color', 'happy', 'birthday'] ]

        def __new__(self):
                age = Q_Integer("Your Age:", "age", 99)
                weight = Q_Integer("Your Weight:", "weight", 200)
                feet = Q_Integer("Feet tall:", "feet", 6)
                inches = Q_Integer("Inches Tall:", "inches", 0)
                name = Q_Chars("Your Name:", "name", max_length=15, 
required=True)
                cash = Q_Float("Money in hand?", "cash", required=True,
default=55.50)
                fav_color = Q_Chars("Your favorite color?", "fav_color",
required=True, max_length=50, choices=C_CHOICES)
                homezip = Q_Zip("Your zip code?", "homezip", required=True, )
                happy = Q_Bool("Are you happy?", "happy", default=False)
                birthday = Q_Date("Your Birthday:", "birthday")

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to