This program is about ordering stuff from a "mail order" house thing.
They sell five products. P1 = 2.98, P2 = 4.5, P3 = 9.98, P4 = 4.49, P5 = 6.87
So this is my code so far.
#Imports: None
#Defs:
def userInput1():
x = int(input("Product Number?"))
return x
def userInput2():
q = int(input("Quantity?"))
return q
def calculations(x,q):
p1 = 2.98
p2 = 4.5
p3 = 9.98
p4 = 4.49
p5 = 6.87
subtotal = q * x
return subtotal
def final(subtotal):
print ("Total:", subtotal)
def loop():
cont = input("Do you want to continue? (yes/no)")
if cont == 'yes':
main()
return
else:
final()
def main():
x = userInput1()
subtotal = calculations(x,q)
final(subtotal)
#Driver:
main()
I have to use a sentinel controlled loop.
Here's my traceback.
Traceback (most recent call last):
File "C:\Documents and Settings\user1\My Documents\Downloads\az_mailorder3.py", line 49, in <module>
main()
File "C:\Documents and Settings\user1\My Documents\Downloads\az_mailorder3.py", line 46, in main
subtotal = calculations(x,q)
NameError: name 'q' is not defined
Here's how it should work.
Product number?: 1
Quantity?: 2
Continue?(yes/no): yes
Product number?: 2
Quantity?: 5
Continue?(yes/no): yes
Product number?: 3
Quantity?: 3
Continue?(yes/no): yes
Product number?: 4
Quantity?: 1
Continue?(yes/no): no
Total: $62.89
There's probably deeper problems.
Assuming you are a newbie to programming (I can feel that from your code) and also this problem seems a school homework which is quite easy and also you don't want to try hard debugging it (You need to debug a lot to be a good programmer)
Here I am presenting your code to you with proper comments why your code is going wrong.
Start reading from the main function (not from the first line)
def userInput1():
x = int(input("Product Number?"))
return x
def userInput2():
q = int(input("Quantity?"))
return q
def calculations(x,q):
p1 = 2.98
p2 = 4.5
p3 = 9.98
p4 = 4.49
p5 = 6.87
subtotal = q * x
#here you are multiplying the item number by quantity
#not the price by quantity (use proper if else to check price for item number
# return to main function again for more comments
return subtotal
def final(subtotal):
print ("Total:", subtotal)
#nothing wrong here but since we have declared subtotal as global (remember that?)
#so no need to pass subtotal by argument.
def loop():
cont = input("Do you want to continue? (yes/no)")
if cont == 'yes':
main()
return
else:
final()
#you are calling final() but you declared with argument (are you mad?)
#now check final function
def main():
x = userInput1()
#Where you are taking input from user for quantity??
#first take quantity as input q = userInput2()
subtotal = calculations(x,q)
#now every time you call main function your subtotal will be revised
#remember teacher talking about global and local variables?
#subtotal needs to be global (declare it somewhere outside the functions
#now even if subtotal is global you need to increment it (not reassign)
# use subtotal += calculations(x,q)
#now check your calculations function
final(subtotal)
#you are calling final subtotal but where the hell you calling your loop?
#call it before calling final and now check your loop function
main()
hopefully by now you are able to write correct code
but even if you are not able to write correct code by now here is something for your help. But try to write code by yourself first. Happy Debugging :)
Related
In my code below, I don't know why when the output total_cost is zero, and why the subroutine doesn't change that variable. Also are the parameters of my subroutine wrong, like should I add them outside the subroutine and then use those defined variables or something?
total_cost = 0
from datetime import date
def valid_integer():
not_valid = True
while not_valid:
try:
number = int(input())
not_valid = False
except ValueError:
print("You must enter a whole number")
return number
print("Welcome to Copington Adventure them park!")
print(
"\n""These are our ticket prices:"
"\n""Adult ticket over 16's £20 "
"\n""Child ticket under 16's £12 "
"\n""Senior ticket over 60's £11" )
print("How many adult tickets do you want?")
adult = int(input())
print("How many child tickets do you want?")
child = int(input())
print("How many Senior tickets do you want?")
senior = int(input())
print("Your total ticket price is:")
print(total_cost)
def entrance(child_total, adult_total, senior_total):
total_child = child * 12
total_senior = senior * 11
total_adult = adult * 20
total_cost = total_child + total_senior + total_adult
return total_cost
print(total_cost)
return exits the function, so any code after a return will not execute. Swap the order of these two lines:
return total_cost
print(total_cost)
The required reading on this is "scope". Code in a function has access to the variables in its own scope, and it has access to its parent scope, which is the file it was defined in. After a function call completes, the scope, and all variables created in it that aren't returned or stashed in a higher scope, tend to be destroyed.
Returned variables are passed back to the caller's scope. So the lifecycle is something like this:
def myfunction(a, b):
a = a * 2
print(a) #this will evaluate later when we call the function
b = a + b
return b
c = myfunction(1, 2) # jumps to the first line of the function with a=1 and b=2
# the function evaluates, which prints "2" and returns 4.
# The label "c" is then created in the outer scope, and 4 is assigned to it. So now c = 4
print(a) # this is an error, a is not part of this outer scope
print(b) # this is an error, b is not part of this outer scope
print(c) # outputs 4
print(myfunction(1, 2)) # what do you think this outputs?
I've seen multiple posts about this same issue but no answers that satisfy my issue. I wrote this code from a pseudo code provided as part of my class assignment, this generally seems to be a common error in my programs and normally I circumvent the issue by taking another route. for this program though i'm required to follow the exact pseudo and its left me boggled. so here goes
def main():
declareVariables(endProgram, endOrder, totalBurger, totalFry, totalSoda, total, tax,
subtotal, option, burgerCount, fryCount, sodaCount)
while endProgram == 'no' or endProgram == 'No':
resetVariables(totalBurger, totalFry, totalSoda, total, tax, subtotal)
while endOrder == 'no' or endOrder == 'No':
print("Enter 1 for Yum Yum Burger")
print("Enter 2 for Grease Yum Fries")
print("Enter 3 for Soda Yum")
option = input("Please make your selection: ")
if option == 1:
getBurger(totalBurger, burgerCount)
return option
elif option == 2:
getFry(totalFry, fryCount)
return option
elif option == 3:
getSoda(totalSoda, sodaCount)
return option
endOrder = input("Do you want to end your order?(Enter no to add more items: ")
return endOrder
calcTotal(burgerTotal, fryTotal, sodaTotal, total, subtotal, tax)
printReceipt(total)
endProgram = input("Do you want to end the program?(Enter no to process a new order)")
return endProgram
def declareVariables(endProgram, endOrder, totalBurger, totalFry, totalSoda, total, tax,
subtotal, option, burgerCount, fryCount, sodaCount):
endProgram = 'no'
endOrder = 'no'
totalBurger = 0
totalFry = 0
totalSoda = 0
total = 0
tax = 0
subtotal = 0
option = 0
burgerCount = 0
fryCount = 0
sodaCount = 0
obviously the rest of the program is much longer but I feel this is the only relevant information
the full error displays as follows:
Traceback (most recent call last):
File "C:/Users/edigi/Desktop/FSW/COP 1000/YumYumBurger.py", line 96, in
main()
File "C:/Users/edigi/Desktop/FSW/COP 1000/YumYumBurger.py", line 15, in main
declareVariables(endProgram, endOrder, totalBurger, totalFry, totalSoda, total, tax,
UnboundLocalError: local variable 'endProgram' referenced before assignment
I cant seem to avoid this issue, just an explanation of what i'm doing wrong will be fine for me.
The very first line in main() is this:
declareVariables(endProgram, endOrder, totalBurger, totalFry, totalSoda, total, tax,
subtotal, option, burgerCount, fryCount, sodaCount)
This means you are calling the declareVariables() function with the given argument values.
But at that point in main(), none of those variables exist. So, you got the error.
So I basically created my functions ( def main(), load(), calc(), and print().
But I do not know how I can allow the user to input the information as many times as he/she wants until they want to stop. Like I they input 5 times, it would also output 5 times. I have tried putting the while loop in the def main() function and the load function but it won't stop when I want it to. Can someone help? Thanks!
def load():
stock_name=input("Enter Stock Name:")
num_share=int(input("Enter Number of shares:"))
purchase=float(input("Enter Purchase Price:"))
selling_price=float(input("Enter selling price:"))
commission=float(input("Enter Commission:"))
return stock_name,num_share,purchase,selling_price,commission
def calc(num_share, purchase, selling_price, commission):
paid_stock = num_share * purchase
commission_purchase = paid_stock * commission
stock_sold = num_share * selling_price
commission_sale = stock_sold * commission
profit = (stock_sold - commission_sale) - ( paid_stock + commission_purchase)
return paid_stock, commission_purchase, stock_sold, commission_sale, profit
def Print(stock_name,paid_stock, commission_purchase, stock_sold, commission_sale, profit):
print("Stock Name:",stock_name)
print("Amount paid for the stock:\t$",format(paid_stock,'10,.2f'))
print("Commission paid on the purchase:$", format(commission_purchase,'10,.2f'))
print("Amount the stock sold for:\t$", format(stock_sold,'10,.2f'))
print("Commission paid on the sale:\t$", format(commission_sale,'10,.2f'))
print("Profit(or loss if negative):\t$", format(profit,'10,.2f'))
def main():
stock_name,num_share,purchase,selling_price,commission = load()
paid_stock,commission_purchase,stock_sold,commission_sale,profit = calc(num_share, purchase, selling_price, commission)
Print(stock_name, paid_stock,commission_purchase, stock_sold, commission_sale, profit)
main()
You have to give the user some kind of way to declare their wish to stop the input. A very simple way for your code would be to include the whole body of the main() function in a while loop:
response = "y"
while response == "y":
stock_name,num_share,purchase,selling_price,commission = load()
paid_stock,commission_purchase,stock_sold,commission_sale,profit = calc(num_share, purchase, selling_price, commission)
Print(stock_name, paid_stock,commission_purchase, stock_sold, commission_sale, profit)
response = input("Continue input? (y/n):")
an even simpler way would be two do the following....
while True:
<do body>
answer = input("press enter to quit ")
if not answer: break
alternatively
initialize a variable and avoid the inner if statement
sentinel = True
while sentinel:
<do body>
sentinel = input("Press enter to quit")
if enter is pressed sentinel is set to the empty str, which will evaluate to False ending the while loop.
I have problem with getting output from another function to use in a function.
I don't know the syntax of function in python. How do i take a output of another function to use in a function when i define it.
def hero_attribute(hero_selection()): #This syntax isn't accepted
#This program will calculate the damge of hero with stats
global hero_str_result
global hero_agi_result
global hero_int_result
def hero_selection():
print """1. Life Stealer (strength hero)\n
2. Phantom lancer (agility hero)\n
3. Phantom Assassin (agility hero)\n
4. Wrait King (strength hero) \n
"""
print "Please enter hero selection: "
hero_num = int(raw_input("> "))
return hero_num
def hero_attribute(hero_selection()): #This syntax isn't accepted
if hero_num == 1: # Life stealer
hero_str = 25
hero_agi = 18
hero_int = 15
#Hero growth stats
str_growth = 2.4
agi_growth = 1.9
int_growth = 1.75
elif hero_num == 2: # Phantom lancer
hero_str =
hero_agi = ?
hero_int = ?
#Hero growth stats
str_growth = 2.4
agi_growth = 1.9
int_growth = 1.75
elif hero_num == 3: # Phantom Assassin
hero_str = ?
hero_agi = ?
hero_int = ?
#Hero growth stats
else: #Wraith King
hero_str = ?
hero_agi = ?
hero_int = ?
#hero growth stats
str_growth = ?
agi_growth = ?
int_growth = ?
return (hero_str,hero_agi,hero_int,str_growth,agi_growth,int_growth)
def hero_type(hero_num):
if hero_num == 1:
hero_type = "str"
elif hero_num == 2
hero_type = "agi"
elif hero_num == 3
hero_type = "agi"
else:
hero_type = "str"
#the function will ask user what to do with the hero
def hero_build():
print "What do you want to do with the hero?"
print """1. Build hero with stat
2. Build hero with item (not yet)
3. Build hero with level
"""
user_choice = int(raw_input("> "))
if user_choice == 1:
print "You want to build hero with stats!"
print "Please enter number of stats that you want to add: "
hero_stats = int(raw_input=("> "))
hero_str, hero_agi, hero_int,str_growth,agi_growth,int_growth = hero_attribute() #This function will take the result of hero_str, hero_agi,hero_int
hero_str_result = hero_str + str_growth * hero_stats
hero_agi_result = hero_agi + agi_growth * hero_stats
hero_int_result = hero_int + int_growth * hero_stats
return hero_str_result, hero_agi_result, hero_int_result
print "This is the result of your build: ", hero_build()
A function is a piece of code that receive arguments, and to those arguments you assign a name. For example:
def square(x):
return x * x
this function computes the square of a number; this unknown number in the body of the function will be called x.
Once you have a function you can call it, passing the values you want as arguments... for example
print( square(12) )
will print 144 because it will call the function square passing x=12 and 12*12 is 144.
You can of course pass a function the result of calling another function, e.g.
def three_times(x):
return 3 * x
print( square( three_times(5) ) )
will display 225 because the function three_times will be passed 5 and it will return 3*5, the function square will be passed 15 and will return 15*15.
In the function definition (the def part) you will always just have names for the parameters. What you want to pass to the function will be written at the call site.
What you want is to be able to pass a function as argument. This, however, is already incorporated into python from design: you simply pass it as you pass any other argument.
Example:
def apply(f,x):
return f(x)
def sq(x):
return x*x
def cb(x):
return x*x*x
apply(sq,2)
4
apply(cb,2)
8
Apply is defined with its first argument being a function. You know that only when you actually read the definition of apply. There you see that f is treated as a function, as opposed to x which is treated "as a number".
I am trying to make a very simple python script that pits two characters together, but while running the script, it executes the first two functions that the script uses to define the two characters stats, but when it gets to the third function, it just hangs.
Here's the code:
#STAPS: Strength Toughness Agility Perception weapon Skill
#A comparative simulator
import random
#Functions used to define character parameters
#Character 1's parameter function
def char1():
global s1
global t1
global a1
global p1
global dam1
global dt1
global dr1
global ac1
global ws1
s1 = int(input("Char1's Strength? "))
t1 = int(input("Char1's Toughness? "))
a1 = int(input("Char1's Agility? "))
p1 = int(input("Char1's Perception? "))
dam1 = int(input("Char1's Damage? "))
dt1 = int(input("Char1's Damage Threshold? "))
dr1 = int(input("Char1's Damage Resistance? "))
ac1 = int(input("Char1's Armor Class? "))
ws1 = int(input("Char1's Weapon Skill? "))
#Character 2's paramter function
def char2():
global s2
global t2
global a2
global p2
global dam2
global dt2
global dr2
global ac2
global ws2
s2 = int(input("Char2's Strength? "))
t2 = int(input("Char2's Toughness? "))
a2 = int(input("Char2's Agility? "))
p2 = int(input("Char2's Perception? "))
dam2 = int(input("Char2's Damage? "))
dt2 = int(input("Char2's Damage Threshold? "))
dr2 = int(input("Char2's Damage Resistance? "))
ac2 = int(input("Char2's Armor Class? "))
ws2 = int(input("Char2's Weapon Skill? "))
#Main battle function. Ordo Xenos calls this "complex and easy to misuse"
#Jury-rigged way of getting names, why did I include them anyways?
def stapsbatt(c1n,c2n,hp1,hp2):
while hp1 > 0 or hp2 > 0:
#determines original raw acc
char1rawacc = ws1 - ac2
#if statement settles it to minimum 95% acc
if char1rawacc > 95:
char1rawacc = 95
#random int used to determine whether it's a hit or not
char1hitnum = random.randint(0, 100)
if char1rawacc > char1hitnum:
moddam1 = dam1 - dt2
if moddam1 < 0:
moddam1 = 0
rawdam1 = moddam1 * (100 - dr2)
hp2 = hp2 - rawdam1
#Now we move on to doing char2's batt calcs
char2rawacc = ws2 - ac1
if char2rawacc > 95:
char2rawacc = 95
char2hitnum = random.randint(0, 100)
if char2rawacc > char2hitnum:
moddam2 = dam2 - dt1
if moddam2 < 0:
moddam2 = 0
rawdam2 = moddam2 * (100 - dr1)
hp1 = hp1 - rawdam2
if hp1 == 0:
print(c2n, "has won!")
else:
print(c1n, "has won!")
char1()
char2()
stapsbatt("Character 1", "Character 2",400,30)
input("Press enter to exit. ")
And yes, this code is completely unedited, I realize my comments aren't very good.
First, your comments must be at the same indentation level as the code.
The problem you're probably looking for:
while hp1 > 0 or hp2 > 0:
#determines original raw acc
char1rawacc = ws1 - ac2
This loop never ends, because whatever you do inside never changes its condition. Probably you wanted an if.
The rest: OMG. Seeing this code hurts. Let's make it a bit better.
Don't use global unless you have a damn good reason to do so. For now, consider this a matter of discipline; as you progress as a programmer you will see why separation of scopes matters.
Use functions to describe similar things once. It's the whole point: removing repeating parts, replacing them with names, with new 'words' that makes your language closer to the problem you're solving.
def get_character_description(name):
print "Describe character %s" % name
# input values here...
return description
char1 = get_character_description('Liu Kang')
char2 = get_character_description('Sub Zero')
Use data structures. In this case, combine stats of a character into a single entity.
# Use a dict to describe character stats
def get_character_description(name):
description = {}
description['name'] = name
print "Describe character %s" % name
description['strength'] = int(input("%s's strength?"))
# input other values here...
return description
char1 = get_character_description('Pikachu')
if char1['strength'] > 100: ...
Consider creating a custom class to describe characters when you learn about classes:
class Character(object):
def __init__(self, name):
self.name = name
def input(self):
print "Let's define stats of %s" % self.name
self.strength = int(input("Strength?"))
# and so on
char1 = Character('J.C. Denton')
if char1.strength > 100: ...
After that, your code might look like this:
char1 = get_character_description('Liu Kang')
char2 = get_character_description('Sub Zero')
if char1.wins_over(char2):
print char1.name, "has won"
else:
print char2.name, "has won"
There are a few problems with your code that are causing it to hang. I would suggest getting familiar with a python debugger, such as pdb. This will allow you to look at values during runtime, stepping through the program execution line-by-line.
Indentation issues aside, here are the problem areas I found:
In your while loop, you use while hp1 > 0 and hp2 > 0 as your condition. You don't want to use or here, or it will keep looping until both chars have < 0 hp, so you should change it to and.
When calculating rawacc (for both chars), you used if char1rawacc > 95, which actually enforces a maximum on the char1rawacc. You did the same thing for char2rawacc. Switch these to if char1rawacc < 95 and if char2rawacc < 95.
As a style note, if you are executing this as a script, you should put the function calls outside the function definitions themselves, a good way to do this is to put a block like this at the end of your script:
if __name__ == "__main__":
# the following only gets executed if the file is run as a script
char1()
char2()
stapsbatt("Character 1", "Character 2", 400, 30)
Hopefully this gets you out of your infinite loop! I got the game working on my computer with these changes.
Now, as Oz123 mentions, you are really abusing global variables. Instead, you should look into creating and passing objects (see 9000's answer). For example, you could define a class for your character, and create two instances of this class (char1 and char2) that get passed to your battle function. This will also save you from a lot of redundant code. This will require some significant restructuring, but it will be worth it. If you run into problems with that, feel free to open a new question.
Two immortal characters (with "or->and" fix) => infinite loop
moddam1 = dam1 - dt2
if moddam1 < 0:
moddam1 = 0 # dam1 <= dt2: moddam1 = 0
rawdam1 = moddam1 * (100 - dr2) # rawdam1 == 0
hp2 = hp2 - rawdam1 # hp2 == const: immortality
If it makes you feel better, it doesn't seem to be an issue with your program. (Nevermind yes it is, it's the while statement)
Traceback (most recent call last):
File "C:\Python32\staps.py", line 89, in <module>
stapsbatt("Character 1", "Character 2",400,30)
File "C:\Python32\staps.py", line 76, in stapsbatt
char2hitnum = random.randint(0,100)
File "C:\Python32\lib\random.py", line 215, in randint
return self.randrange(a, b+1)
File "C:\Python32\lib\random.py", line 191, in randrange
return istart + self._randbelow(width)
File "C:\Python32\lib\random.py", line 221, in _randbelow
getrandbits = self.getrandbits
KeyboardInterrupt
It's hanging inside the random module, and despite trying several other functions (random.randrage(0,100), and random.choice(range(0,100))) the problem still manifests. Oddly, there's no issues calling the functions outside your program.
Try cleaning up your code a bit and see if it improves. Generally, your globals should be declared at the beginning. Also, I think you mean to say "and" instead of "or" in this line: while hp1 > 0 or hp2 > 0:. Using an OR in this case means if char1 or char2 is alive. You only want to go until the fight is over (unless of course, you like beating a dead horse).