You are not logged in.
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
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
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
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
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.htmlhere'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
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.htmlhere'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
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.
Offline
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
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
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
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.
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
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
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
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