You are not logged in.

#1 2007-11-18 01:02:49

ihavenoname
Member
Registered: 2006-01-09
Posts: 198

[python] Generating new variables at run time

I was just wondering if there was a way to have new variables generated at run time. For example, If I am making a program that tallies the cost of someones pizza order, I could have it say

price_of_pizza_1 = input("Please type the price of the first pizza: ")
price_of_pizza_2 = input("Please type the price of the second pizza: ")

total = price_of_pizza_1 + price_of_pizza_2
print "Your total is:", total

Now that would work fine if I knew how many pizzas were being ordered, but what if some one wants three pizzas?

Is there a way to have the program generate new variables (eg. price_of_pizza_3,price_of_pizza_4) as they are needed.

I would like to able to have the program receive inputs from a textbox and generate new pizza variables as the prices are entered and to add the new pizzas to a list. (Using pygtk)

At the same time I would like their to be a command line version of this as well. (By that I mean, if there is a pygtk method and a separate cli method I would like to know both.)

Any ideas?

p.s. The program above is just an example I'm not sure if the code I type would even work in it's current state, I just wrote it to explain what I was trying to do.


In this land of the pain the sane lose not knowing they were part of the game.

~LP

Offline

#2 2007-11-18 04:50:31

MrWeatherbee
Member
Registered: 2007-08-01
Posts: 277

Re: [python] Generating new variables at run time

ihavenoname wrote:

Any ideas?

Not "pythonista" quality, but how about this as a slammed-together example?

#!/usr/bin/env python

import re, sys

# -- Variables
v_replay = 1
v_pricelist = []
v_regpattern1 = re.compile(r"^[0-9]{1,2}\.[0-9]{2}$")
v_regpattern2 = re.compile(r"^[Xx]$")
v_regpattern3 = re.compile(r"^[Yy]es$|^[Yy]$|^""$")
v_regpattern4 = re.compile(r"^[Nn]o$|^[Nn]$")
v_regpattern5 = re.compile(r"^[Cc]$")

# -- Defs
def f_inputerror(input, errnum):
    if errnum == 0:
        print "User-input (%s) was incorrect." \
              "Please use format '0.00' (max: '99.99')." % input
        v_replay = 1
    elif errnum == 1:
        print "User Says Price Is Incorrect. Please Re-enter Correct Price."
        v_getcontinuekey = raw_input("Press 'c' Then 'Enter' To "  \
                                     "Continue; Any Other Key To " \
                                     "Immediately Exit: ")
        v_regtest5 = re.search(v_regpattern5, v_getcontinuekey)
        if v_regtest5:
            v_replay = 1
        else:
            sys.exit()
    elif errnum == 2:
        print "Input (%s) Was Incorrect." % input
        print "Input Should Be Affirmative ('Y','y','Yes','yes' or 'ENTER')\n" \
              "Or Input Should Be Negative ('N','n','No', or 'no')." 
        v_getcontinuekey = raw_input("Press 'c' Then 'Enter' To "  \
                                     "Continue; Any Other Key To " \
                                     "Immediately Exit: ")
        v_regtest5 = re.search(v_regpattern5, v_getcontinuekey)
        if v_regtest5:
            v_replay = 1
        else:
            sys.exit()
    return v_replay


# -- Main
print "-------------------------------------------------------\n" \
      " Please enter the price of each pizza when prompted.\n"    \
      " When finished entering prices, type 'x' at the\n"         \
      " price prompt, then press ENTER to continue.\n"            \
      "-------------------------------------------------------"

while v_replay == 1:
    v_getprice = raw_input("\nPlease enter price of pizza No. %s: " 
                           % (len(v_pricelist) + 1))
    v_regtest1 = re.search(v_regpattern1, v_getprice)
    v_regtest2 = re.search(v_regpattern2, v_getprice)
    if v_regtest1:
        print "-- You have entered '%s'" % v_getprice
        v_getmatchconfirm = raw_input("-- Is this correct? (Y/n): ")
        v_regtest3 = re.search(v_regpattern3, v_getmatchconfirm)
        v_regtest4 = re.search(v_regpattern4, v_getmatchconfirm)
        v_regtest5 = re.search(v_regpattern5, v_getmatchconfirm)
        if v_regtest3:
            v_pricelist.append(float(v_getprice))
        elif v_regtest4: 
            v_replay = f_inputerror(v_getmatchconfirm, 1)
        else: 
            v_replay = f_inputerror(v_getmatchconfirm, 2)
    elif v_regtest2:
        print ">> User has finished entering prices."
        print "-------------------------------------"
        v_replay = 0
    else:
        v_replay = f_inputerror(v_getprice, 0)

v_totprice = (sum(v_pricelist))
for (v_index, v_price) in enumerate (v_pricelist):
    print "* Price of Pizza No. %s: $%.2f" % (v_index + 1, v_price)
print "-----"
print "** Total Price: $%.2f" % v_totprice

Sample output:

-------------------------------------------------------
 Please enter the price of each pizza when prompted.
 When finished entering prices, type 'x' at the
 price prompt, then press ENTER to continue.
-------------------------------------------------------

Please enter price of pizza No. 1: 5.10
-- You have entered '5.10'
-- Is this correct? (Y/n): 

Please enter price of pizza No. 2: 5.10
-- You have entered '5.10'
-- Is this correct? (Y/n): 

Please enter price of pizza No. 3: 5.10
-- You have entered '5.10'
-- Is this correct? (Y/n): 

Please enter price of pizza No. 4: 5.10
-- You have entered '5.10'
-- Is this correct? (Y/n): 

Please enter price of pizza No. 5: x
>> User has finished entering prices.
-------------------------------------
* Price of Pizza No. 1: $5.10
* Price of Pizza No. 2: $5.10
* Price of Pizza No. 3: $5.10
* Price of Pizza No. 4: $5.10
-----
** Total Price: $20.40

Edit:
Shorten some long lines of code by adding line continuations

Last edited by MrWeatherbee (2007-11-18 13:19:03)

Offline

#3 2007-11-18 20:48:58

ihavenoname
Member
Registered: 2006-01-09
Posts: 198

Re: [python] Generating new variables at run time

MrWeatherbee wrote:
ihavenoname wrote:

Any ideas?

Not "pythonista" quality, but how about this as a slammed-together example?

#!/usr/bin/env python

import re, sys

# -- Variables
v_replay = 1
v_pricelist = []
v_regpattern1 = re.compile(r"^[0-9]{1,2}\.[0-9]{2}$")
v_regpattern2 = re.compile(r"^[Xx]$")
v_regpattern3 = re.compile(r"^[Yy]es$|^[Yy]$|^""$")
v_regpattern4 = re.compile(r"^[Nn]o$|^[Nn]$")
v_regpattern5 = re.compile(r"^[Cc]$")

# -- Defs
def f_inputerror(input, errnum):
    if errnum == 0:
        print "User-input (%s) was incorrect." \
              "Please use format '0.00' (max: '99.99')." % input
        v_replay = 1
    elif errnum == 1:
        print "User Says Price Is Incorrect. Please Re-enter Correct Price."
        v_getcontinuekey = raw_input("Press 'c' Then 'Enter' To "  \
                                     "Continue; Any Other Key To " \
                                     "Immediately Exit: ")
        v_regtest5 = re.search(v_regpattern5, v_getcontinuekey)
        if v_regtest5:
            v_replay = 1
        else:
            sys.exit()
    elif errnum == 2:
        print "Input (%s) Was Incorrect." % input
        print "Input Should Be Affirmative ('Y','y','Yes','yes' or 'ENTER')\n" \
              "Or Input Should Be Negative ('N','n','No', or 'no')." 
        v_getcontinuekey = raw_input("Press 'c' Then 'Enter' To "  \
                                     "Continue; Any Other Key To " \
                                     "Immediately Exit: ")
        v_regtest5 = re.search(v_regpattern5, v_getcontinuekey)
        if v_regtest5:
            v_replay = 1
        else:
            sys.exit()
    return v_replay


# -- Main
print "-------------------------------------------------------\n" \
      " Please enter the price of each pizza when prompted.\n"    \
      " When finished entering prices, type 'x' at the\n"         \
      " price prompt, then press ENTER to continue.\n"            \
      "-------------------------------------------------------"

while v_replay == 1:
    v_getprice = raw_input("\nPlease enter price of pizza No. %s: " 
                           % (len(v_pricelist) + 1))
    v_regtest1 = re.search(v_regpattern1, v_getprice)
    v_regtest2 = re.search(v_regpattern2, v_getprice)
    if v_regtest1:
        print "-- You have entered '%s'" % v_getprice
        v_getmatchconfirm = raw_input("-- Is this correct? (Y/n): ")
        v_regtest3 = re.search(v_regpattern3, v_getmatchconfirm)
        v_regtest4 = re.search(v_regpattern4, v_getmatchconfirm)
        v_regtest5 = re.search(v_regpattern5, v_getmatchconfirm)
        if v_regtest3:
            v_pricelist.append(float(v_getprice))
        elif v_regtest4: 
            v_replay = f_inputerror(v_getmatchconfirm, 1)
        else: 
            v_replay = f_inputerror(v_getmatchconfirm, 2)
    elif v_regtest2:
        print ">> User has finished entering prices."
        print "-------------------------------------"
        v_replay = 0
    else:
        v_replay = f_inputerror(v_getprice, 0)

v_totprice = (sum(v_pricelist))
for (v_index, v_price) in enumerate (v_pricelist):
    print "* Price of Pizza No. %s: $%.2f" % (v_index + 1, v_price)
print "-----"
print "** Total Price: $%.2f" % v_totprice

Sample output:

-------------------------------------------------------
 Please enter the price of each pizza when prompted.
 When finished entering prices, type 'x' at the
 price prompt, then press ENTER to continue.
-------------------------------------------------------

Please enter price of pizza No. 1: 5.10
-- You have entered '5.10'
-- Is this correct? (Y/n): 

Please enter price of pizza No. 2: 5.10
-- You have entered '5.10'
-- Is this correct? (Y/n): 

Please enter price of pizza No. 3: 5.10
-- You have entered '5.10'
-- Is this correct? (Y/n): 

Please enter price of pizza No. 4: 5.10
-- You have entered '5.10'
-- Is this correct? (Y/n): 

Please enter price of pizza No. 5: x
>> User has finished entering prices.
-------------------------------------
* Price of Pizza No. 1: $5.10
* Price of Pizza No. 2: $5.10
* Price of Pizza No. 3: $5.10
* Price of Pizza No. 4: $5.10
-----
** Total Price: $20.40

Edit:
Shorten some long lines of code by adding line continuations

wow! Thanks!


In this land of the pain the sane lose not knowing they were part of the game.

~LP

Offline

#4 2007-11-18 23:58:37

iphitus
Forum Fellow
From: Melbourne, Australia
Registered: 2004-10-09
Posts: 4,927

Re: [python] Generating new variables at run time

woo! bikeshed!

ihavenoname: To answer your topic... look up python's lists and dictionaries in the python tutorial:
http://docs.python.org/tut/tut.html
And Dive Into Python has some really useful tricks and pythonic things:
http://www.diveintopython.org/toc/index.html

here's a slightly simpler, slightly more pythonic way without resorting to regex:

#! /usr/bin/python

print "Please enter the price of each pizza when prompted, Ctrl-D to end"

pizza_prices=list()

while True:
    try:
        cost=raw_input("Please enter price of pizza: ")
    except EOFError: 
        # raw_input raises this upon ctrl-D"
        print       # just pretty printing, putting a new line in"
        break      # break out of the loop.

    try: 
        pizza_prices.append(float(cost))
    except ValueError: 
        # float() raises ValueError when it's not a valid number
        print "Invalid price, please enter a number"


for num in range(len(pizza_prices)): 
    # loop over pizza numbers
    print "Price of pizza", num, "is:", pizza_prices[num]

print "Total Price:", sum(pizza_prices)

Last edited by iphitus (2007-11-19 00:03:22)

Offline

#5 2007-11-19 00:28:12

ihavenoname
Member
Registered: 2006-01-09
Posts: 198

Re: [python] Generating new variables at run time

iphitus wrote:

woo! bikeshed!

ihavenoname: To answer your topic... look up python's lists and dictionaries in the python tutorial:
http://docs.python.org/tut/tut.html
And Dive Into Python has some really useful tricks and pythonic things:
http://www.diveintopython.org/toc/index.html

here's a slightly simpler, slightly more pythonic way without resorting to regex:

#! /usr/bin/python

print "Please enter the price of each pizza when prompted, Ctrl-D to end"

pizza_prices=list()

while True:
    try:
        cost=raw_input("Please enter price of pizza: ")
    except EOFError: 
        # raw_input raises this upon ctrl-D"
        print       # just pretty printing, putting a new line in"
        break      # break out of the loop.

    try: 
        pizza_prices.append(float(cost))
    except ValueError: 
        # float() raises ValueError when it's not a valid number
        print "Invalid price, please enter a number"


for num in range(len(pizza_prices)): 
    # loop over pizza numbers
    print "Price of pizza", num, "is:", pizza_prices[num]

print "Total Price:", sum(pizza_prices)

Ah, much simpler. I must admit some of the regex stuff was throwing me. Still it's been a nice learning experience.  Thank you both.


In this land of the pain the sane lose not knowing they were part of the game.

~LP

Offline

#6 2007-11-19 00:43:04

MrWeatherbee
Member
Registered: 2007-08-01
Posts: 277

Re: [python] Generating new variables at run time

iphitus wrote:

woo! bikeshed!

ihavenoname: To answer your topic... look up python's lists and dictionaries in the python tutorial:
http://docs.python.org/tut/tut.html
And Dive Into Python has some really useful tricks and pythonic things:
http://www.diveintopython.org/toc/index.html

here's a slightly simpler, slightly more pythonic way without resorting to regex:

<snip excellent code>

Glad you stopped by and took the time to "pythonize" the code I posted. I'd only just begun reading the docs you mentioned above about the same time you posted the "pythonista" article (first part of November):

http://bbs.archlinux.org/viewtopic.php?id=39353

so I'm very, very green. It really does help to see a side-by-side comparison of novice code and code written by a more experienced programmer.

I definitely learned a lot from this post.

Thanks.

Offline

#7 2007-11-19 01:03:45

MrWeatherbee
Member
Registered: 2007-08-01
Posts: 277

Re: [python] Generating new variables at run time

ihavenoname wrote:

Ah, much simpler. I must admit some of the regex stuff was throwing me. Still it's been a nice learning experience.  Thank you both.

You're welcome, even if I only served to show how *not* to do it.

As you can see from my response to Iphitus, I took your request as a challenge and learning experience for myself as much as I did it to help ... I'm not that much of an altruist. smile

Offline

#8 2007-11-19 01:30:22

Dusty
Schwag Merchant
From: Medicine Hat, Alberta, Canada
Registered: 2004-01-18
Posts: 5,986
Website

Re: [python] Generating new variables at run time

iphitus wrote:

woo! bikeshed!
<snip>
for num in range(len(pizza_prices)):
    # loop over pizza numbers
    print "Price of pizza", num, "is:", pizza_prices[num]

This looks a wee bit better if you use:

for num, price in enumerate(pizza_prices):
    print "Price of pizza", num, "is", price

or, in few characters but possibly with less clarity:

for item in enumerate(x):
    print "Price of pizza %d is %f" % i

Dusty

Offline

#9 2007-11-19 03:16:28

iphitus
Forum Fellow
From: Melbourne, Australia
Registered: 2004-10-09
Posts: 4,927

Re: [python] Generating new variables at run time

Dusty wrote:

This looks a wee bit better if you use:

for num, price in enumerate(pizza_prices):
    print "Price of pizza", num, "is", price

or, in few characters but possibly with less clarity:

for item in enumerate(x):
    print "Price of pizza %d is %f" % i

Dusty

thanks, I thought there'd be a nicer way. *files that away* That's the thing about python... if you see something that looks odd/messy, it probably is. So many useful little things tucked away that you find if you google a bit.

Last edited by iphitus (2007-11-19 03:19:12)

Offline

#10 2007-11-19 03:41:54

Dusty
Schwag Merchant
From: Medicine Hat, Alberta, Canada
Registered: 2004-01-18
Posts: 5,986
Website

Re: [python] Generating new variables at run time

Yeah, I periodically reread the python tutorial just to see what I've forgotten. :-D

And just for the record, I was reminded of the enumerate function because of your pythonista post, so its payback for a good link to remind you of it too. :-)

Dusty

Offline

#11 2007-11-19 04:19:39

MrWeatherbee
Member
Registered: 2007-08-01
Posts: 277

Re: [python] Generating new variables at run time

Dusty wrote:

Yeah, I periodically reread the python tutorial just to see what I've forgotten. :-D

And just for the record, I was reminded of the enumerate function because of your pythonista post, so its payback for a good link to remind you of it too. :-)

Dusty

Guess you could have just looked at my code to be reminded of it (if it doesn't turn you to stone):

v_totprice = (sum(v_pricelist))
for (v_index, v_price) in enumerate (v_pricelist):
    print "* Price of Pizza No. %s: $%.2f" % (v_index + 1, v_price)
print "-----"
print "** Total Price: $%.2f" % v_totprice

But I got it from the "pythonista" post, too. smile

It looks dirtier, but without some of the the "dirt" (e.g., v_index + 1), you get pizza 0, pizza 1, etc. instead of pizza 1, pizza 2, etc. No big deal.

Last edited by MrWeatherbee (2007-11-19 04:35:04)

Offline

#12 2007-11-19 04:55:55

MrWeatherbee
Member
Registered: 2007-08-01
Posts: 277

Re: [python] Generating new variables at run time

MrWeatherbee wrote:
v_totprice = (sum(v_pricelist))
for (v_index, v_price) in enumerate (v_pricelist):
    print "* Price of Pizza No. %s: $%.2f" % (v_index + 1, v_price)
print "-----"
print "** Total Price: $%.2f" % v_totprice

By the way, while we're on this particular part of the code, below is what I originally attempted to do in an early version:

v_totprice = (sum(v_pricelist))
for v_price in v_pricelist:
    v_index = v_pricelist.index(v_price)
    print "* Price of Pizza No. %s: $%.2f" % (v_index + 1, v_price)
print "-----"
print "** Total Price: $%.2f" % v_totprice

Of course, using the 'index' method in this way is not good when items in the list might be the same (e.g., all pizzas might cost the same for a particular order in a worst case scenario).

Perhaps there is something in itertools that will work as cleanly and with minimal code, but I haven't had time to look into it yet.

Thanks.

Last edited by MrWeatherbee (2007-11-19 06:43:56)

Offline

#13 2007-11-19 05:28:57

MrWeatherbee
Member
Registered: 2007-08-01
Posts: 277

Re: [python] Generating new variables at run time

Followup

Okay, here's my itertools version:

from itertools import izip, count

v_pricelist = [10.50,10.50,10.50]
for v_index, v_price in izip(count(1), v_pricelist):
    print "* Price of Pizza No. %s: $%.2f" % (v_index, v_price)

That gets the pizza count correct (starting at 1 rather than 0) without having to futz with adding an increment to the list index (i.e., no v_index +1 required).

Last edited by MrWeatherbee (2007-11-19 05:33:08)

Offline

#14 2007-11-19 18:24:19

MrWeatherbee
Member
Registered: 2007-08-01
Posts: 277

Re: [python] Generating new variables at run time

I might as well post this since I spent a little time cleaning up my original code.

My goal was to see if I could put back the functionality that Iphitus removed while still keeping the code somewhat more "pythonized" than my first attempt.

The functionality removed in Iphitus' code was mostly related to input validation, and certainly, at least for me, the more validation, the more complex / kludgy-looking the code becomes. Remove it, and things look all nice and neat again. To be sure, the validation I included was for demonstration purposes more than anything else.

My original code used regular expressions exclusively for testing input, but for the new incarnation, I removed all the regex and used a combination of searching through pre-defined lists of acceptable input values and using the built in error-raising facility (the latter effectively demonstrated by Iphitus). For very complex input validation, I would have to add back some regex code.

I'm not sure I achieved my goal, but I think the code is easier to read now, has fewer lines and even has the same functionality PLUS the added ability to toggle extended input validation.

On to the next project.

#!/usr/bin/env python

from itertools import count, izip

# -- Variables
v_pricelist = []
v_affirm = ['YES', 'Yes', 'Y', 'y', '']
v_neg = ['NO', 'No', 'N', 'n']
v_mode = False  # Set to 'True' to include extra input verification procedures 

# -- Main
print "-------------------------------------------------------"
print " Please enter the price of each pizza when prompted."
print " Pressing 'ctrl-D' will exit and present a summary"
print " of input items and total cost of pizzas."
print "-------------------------------------------------------"

while True:
    try:
        v_getprice = raw_input("\nPlease enter price of pizza No. %s: " 
                               % (len(v_pricelist) + 1))
    except EOFError:
        # raw_input raises EOFError upon ctrl-D"
        print
        print "----------------------------------------"
        print " >> User has requested exit with 'ctrl-D."
        print "----------------------------------------"
        break       # break out of the loop.

    try: 
        v_getprice = float(v_getprice)
    except ValueError:
        # float() raises ValueError when it's not a valid number
        print " >> Invalid price; please enter a number"
    else:
        if v_mode:
            # verify price input if v_mode = True; skip verification if False
            print "-- You have entered '%s'" % v_getprice
            while True:
                try:
                    v_getinput = raw_input("-- Is the price correct? (Y/n): ")
                except EOFError:
                    # raw_input raises EOFError upon ctrl-D"
                    print
                else:
                    if v_getinput in v_affirm:
                        v_pricelist.append(v_getprice)
                        break
                    elif v_getinput in v_neg:
                        print " >> Please re-enter the pizza price."
                        break
                    else:
                        print " >> Incorrect response (%s); try the question again." % v_getinput
        else:
            v_pricelist.append(v_getprice)

v_totprice = (sum(v_pricelist))
print "----- Summary"
for v_index, v_price in izip(count(1), v_pricelist):
    print "* Price of Pizza No. %s: $%.2f" % (v_index, v_price)
print "-----"
print "** Total Price: $%.2f" % v_totprice
print "-----"

Offline

Board footer

Powered by FluxBB