I am currently trying to write a program where the user inputs what colour carpet they would like and then depending on what carpet and what area they have inputted it will give them a different price, However my current issue is using the parameters correctly since I am very new to both using python and to programming. The current program specification requires the use of subroutines. An example problem is with my last line main(exit1) where it says that exit1 isn't defined and if I try to edit the code to main() it says that exit1 is required. Any help will be greatly appreciated.
def prices():
PriceA = 40
PriceB = 50
PriceC = 60
def main(exit1):
exit1 = False
while exit1 == False:
carpet = str(input("What carpet would you like blue, red or yellow "))
carpet = carpet.upper()
if carpet == "X":
exit1 = True
else:
width = int(input("What is the width of the room in M^2 "))
height = int(input("What is the height of the room in M^2 "))
area = width * height
if carpet == "BLUE":
a(area)
elif carpet == "RED":
b(area)
elif carpet == "YELLOW":
c(area)
else:
print("Invalid carpet")
cost = 0
output(cost)
def output(cost, exit1):
print ("the price is £", cost)
def a(area, PriceA):
cost = PriceA * area
output(cost)
def b(area, PriceB):
cost = PriceB * area
output(cost)
def c(area, PriceC):
cost = PriceC * area
output(cost)
main(exit1)
You are trying to pass in a variable as an argument to the main function on the last line of your program, but you have not defined the exit1 variable before that line is executed (you define it within the scope of the main function). To achieve what you want to do you don't need to provide main with the exit1 argument, so you can just remove it from the function definition and the function call.
def main():
...
...
main()
The problem you are having is that a variable needs to be defined before it can be entered into a function. I fixed the code and made a few corrections it also appeared that you had an indentation error and didn't feed in enough arguments into your functions when you called them. The code ive written is a bit easier to follwo. If I have done anything you dont understand send me a message, otherwise I recommend sites such as code acadamy and pythonprogramming .net.
def main():
PriceA = 40
PriceB = 50
PriceC = 60
while True:
carpet = str(input('What carpet would you like blue, red or yellow? '))
carpet = carpet.upper()
if carpet == 'X':
break
else:
width = int(input("What is the width of the room in M? "))
height = int(input("What is the height of the room in M? "))
area = width * height
if carpet == "BLUE":
output(area,PriceA)
elif carpet == "RED":
output(area,PriceB)
elif carpet == "YELLOW":
output(area,PriceC)
else:
print('Invalid carpet')
def output(area,Price):
cost = area*Price
print('the price is £',cost)
main()
Related
# Import Modules
from Dice import dice
d10 = dice(10,1) #I use dice, but you could just as easily use random.randint()
d4 = dice(4,1)
d20 = dice(20,1)
# Assign Classes
class Player_Character:
inventory = []
def __init__(self, HP, MaxHP, AC, ToHitAdjustment, Surprise_Adjustment,
Initiative_Adjustment, Exp, \
MaxExp, Gold, Damage):
self.HP = int(HP)
self.MaxHP = int(MaxHP)
self.AC = int(AC)
self.ToHitAdjustment = int(ToHitAdjustment)
self.Surprise_Adjustment = int(Surprise_Adjustment)
self.Initiative_Adjustment = int(Initiative_Adjustment)
self.Exp = int(Exp)
self.MaxExp = int(MaxExp)
self.Gold = int(Gold)
self.Damage = int(Damage)
this next section may be where the error is, although I doubt it because when I run through the code the character is assigned exp and gold and they seem to grow at the correct rate.
def attack(self, goblin, Player_Character):
Player_attack_roll = d20.die_roll() + Player_Character.ToHitAdjustment
if (Player_attack_roll >= goblin.AC):
print('you did', Player_Character.Damage, 'damage')
goblin.HP -= Player_Character.Damage
if (goblin.HP <= 0):
print("congratulations you killed the goblin")
Player_Character.Exp += goblin.ExpReward
if (Player_Character.Exp >= Player_Character.MaxExp):
print("Congratulations you have leveled up")
Player_Character.LevelUp()
print('you have', Player_Character.Exp, 'exp ')
Player_Character.Gold += goblin.Gold
print("you have", Player_Character.Gold, 'gold ')
del goblin
else:
print("You miss ")
def flee(self):
print("you run away ")
quit()
def heal(self, Player_Character):
Player_Character.HP += d10.die_roll()
if Player_Character.HP >= Player_Character.MaxHP:
Player_Character.HP = Player_Character.MaxHP
print("You have reached max HP ")
this may be where the error is, I expect it to assign the variable name 'MrHezy' which was previously assigned to Player_Character to FighterLvl1, but when I run the code it continuously says that I am leveling up, which I am unsure if that means that the character is remaining as Player_Character, or if there is something else wrong
def LevelUp(self):
MrHezy = FighterLvl1(25, 25, 15, 10, 2, 2, 25, 75, 20, d10.die_roll()+5)
This next section has code is where my question of inheritance comes into play. Even though FighterLvl1 has inherited from (Player_Character) my IDE says things like "unresolved attribute reference 'Exp' for FighterLvl1" Also I am unsure if adding the 'attack' method under FighterLvl1 does anything; I expect it to overwrite the 'attack' method from Player_Character
class FighterLvl1(Player_Character):
def attack(self, goblin, Player_Character):
Player_attack_roll = d20.die_roll() + Player_Character.ToHitAdjustment
if (Player_attack_roll >= goblin.AC):
print('you did', Player_Character.Damage, 'damage')
goblin.HP -= Player_Character.Damage
if (goblin.HP <= 0):
print("congratulations you killed the goblin")
FighterLvl1.Exp += goblin.ExpReward
if (FighterLvl1.Exp >= FighterLvl1.MaxExp):
print("Congratulations you have leveled up")
FighterLvl1.LevelUp()
print('you have', FighterLvl1.Exp, 'exp ')
FighterLvl1.Gold += goblin.Gold
print("you have", FighterLvl1.Gold, 'gold ')
del goblin
def LevelUp(self):
MrHezy = FighterLvl2(Player_Character)
class FighterLvl2(Player_Character):
def LevelUp(self):
MrHezy = FighterLvl3(Player_Character)
class FighterLvl3(Player_Character):
def MaxLevel(self):
print("Congratulations you are level 3, this is the highest programmed level in the game
")
class goblin:
def __init__(self, HP, MaxHP, AC, ToHitAdjustment, Surprise_Adjustment,
Initiative_Adjustment, \
ExpReward, Gold, Damage):
self.HP = int(HP)
self.MaxHP = int(MaxHP)
self.AC = int(AC)
self.ToHitAdjustment = int(ToHitAdjustment)
self.Surprise_Adjustment = int(Surprise_Adjustment)
self.Initiative_Adjustment = int(Initiative_Adjustment)
self.ExpReward = int(ExpReward)
self.Gold = int(Gold)
self.Damage = int(Damage)
def attack(self, Player_Character, goblin):
if (goblin.HP <= 0):
print("the goblin is inert")
else:
goblin_attack_roll = d20.die_roll() + goblin.ToHitAdjustment
if (goblin_attack_roll >= Player_Character.AC):
goblin_damage = d4.die_roll()
print("you take", goblin_damage, 'damage')
Player_Character.HP -= goblin_damage
if (Player_Character.HP <= 0):
print("oh dear you have died")
del Player_Character
quit()
else:
print("the goblin misses ")
MrHezy = Player_Character(20, 20, 10, 5, 0, 0, 0, 25, 0, d10.die_roll())
def spawn_goblin(goblin):
G1 = goblin(5, 10, 8, 2, 0, 0, 25, 5, d4.die_roll())
return G1
goblin1 = spawn_goblin(goblin)
def battle(goblin1):
# user input
player_initiative_adjustment = MrHezy.Initiative_Adjustment
monster_initiative_adjustment = goblin1.Initiative_Adjustment
#define while loop for the battle
while True:
if (goblin1.HP <= 0):
print('oh dear looks like we need a new goblin')
break
#use random.randint(a,b) to generate player and monster base initiative
player_base_initiative = d10.die_roll()
monster_base_initiative = d10.die_roll()
#subtract the adjustment to get player and monster initiative
player_initiative = player_base_initiative - player_initiative_adjustment
monster_initiative = monster_base_initiative - monster_initiative_adjustment
#compare the initiatives and display the results
if (player_initiative < monster_initiative):
attack_flee_heal = input("congratulations you go first. Would you like to attack,
flee, or heal?")
if attack_flee_heal == 'attack':
MrHezy.attack(goblin1, MrHezy)
elif attack_flee_heal == 'heal':
MrHezy.heal(MrHezy)
print("the goblin attacks")
goblin1.attack(MrHezy)
elif attack_flee_heal == 'flee':
MrHezy.flee()
else:
print("uhoh, the monsters go first, they attack!")
goblin1.attack(MrHezy, goblin1)
attack_flee_heal = input("Would you like to attack, flee, or heal? ")
if attack_flee_heal == 'attack':
MrHezy.attack(goblin1, MrHezy)
elif attack_flee_heal == 'heal':
MrHezy.heal(MrHezy)
print("the goblin attacks")
goblin1.attack(MrHezy, goblin1)
elif attack_flee_heal == 'flee':
MrHezy.flee()
#main game loop
while True:
spawn_goblin(goblin)
battle(goblin1)
print("spawn another goblin")
goblin1.HP = 0
goblin1.HP += d10.die_roll()
This code runs perfectly well, please enter it into your IDE.
The problem that I have is a logic error, when a goblin is killed instead of leveling up the character first to level 1 then level 2 then level 3 instead the character levels up to level 1 over and over and over.
I agree with Danny Varod, in that there are very many improvements that need to be made, and I definitely recommend following his advice.
However if you are simply looking to make what you have work you need to specify in your level up methods that you are referencing the global MrHezy variable.
eg:
def LevelUp(self):
global MrHezy
MrHezy = FighterLvl2(Player_Character)
The level up replaces a variable in the object, what you should do, if you want to use a class per level (not necessarily a good idea) is:
Create a Character class.
In Character class define an implementation field.
Initialize implementation field e.g. implementation = SomeSpeciesLevel1().
To "level-up": implementation = implementation.level_up()
This way you have a constant wrapper that doesn't change which wraps the level-changing implementation.
A better design would be to have one class with functionality based on level-dependant formulas.
class CharImpl:
#abstractmethod
def can_level_up() -> bool:
return NotImplemented
#abstractmethod
def next_level() -> CharImpl:
return NotImplemented
pass
class Character:
def __init__(initial_impl: CharImpl=None):
self.impl = initial_impl.copy() if initial_impl else HumanLevel1()
pass
def level_up():
if self.impl.can_level_up():
self.impl = self.impl.next_level()
pass
pass
class Human(CharImpl):
pass
class HumanLevel1(Human):
def __init__(src: Human):
# TODO: copy relevant fields from src
pass
def can_level_up() -> bool:
return True
def next_level() -> CharImpl:
return HumanLevel2(self)
pass
class HumanLevel2(Human):
def __init__(src: Human):
# TODO: copy relevant fields
pass
def can_level_up() -> bool:
return False
def next_level() -> CharImpl:
return self
pass
Whenever I run this is get:
Traceback (most recent call last):
File "main.py", line 130, in <module>
while is_playing_cg:
NameError: name 'is_playing_cg' is not defined
I want the user to be able to press 1 or 2 to select which game mode to use and then once pressed it starts. I don't know why it's doing this. Whenever it's fixed it should run through just fine.
New edit
Now it just loops and says 1 or 2 over and over again.
import random
is_playing_cg = False
is_playing_hg = False
def game_select_screen():
#Game Select Screen
print("""
._________________________________.
| |
| ~ Welcome To Guess-A-Number ~ |
| ~~~ |
| ~ Press 1 OR Press 2 ~ |
| You ^ Guess | PC ^ Guess |
|_________________________________|""")
selecting = True
while selecting:
print()
game_mode = input("1 OR 2: ")
try:
int(game_mode)
except ValueError:
print("This is not a Number.")
else:
game_mode = int(game_mode)
if game_mode == 1:
is_playing_hg = True
elif game_mode == 2:
is_playing_cg = True
#Defining Random Number for human guess
def play_human_guess():
num = random.randint (1,10)
print()
print("Im Thinking of a Number 1 Through 10.")
print("You Have 3 Chances.")
chances = 3
game_fisnished = False
#Game is playing (Human Guesses)
while not game_fisnished:
guess = input("> Take A Guess: ")
#Accept only numbers
try:
int(guess)
except ValueError:
print("This is not a Number.")
else:
guess = int(guess)
if guess < num:
chances -=1
if chances == 0:
print()
print("Sorry You Guessed Too Many Times.")
game_fisnished = True
elif chances !=0:
print()
print("You Guessed Too Low. ("+str(chances)+") Chance(s) Remaining.")
elif guess > num:
chances -=1
if chances == 0:
print()
print("Sorry You Guessed Too Many Times.")
game_fisnished = True
elif chances !=0:
print()
print("You Guessed Too High. ("+str(chances)+") Chance(s) Remaining.")
else:
print()
print("Congradulations, You Won!")
game_fisnished = True
#Game Ended
def end():
print()
print("Thanks For Playing!")
#Setting up for computer guess
def play_computer_guess():
print()
print("Pick a Number 1 Through 10")
print("I Have 3 Chances to Guess Your Number.")
chances = 3
game_fisnished = False
#Game is playing (Computer Guess)
while not game_fisnished:
guess1 = input("Is your number 5?")
#Show Game Select Screen
game_select_screen()
while is_playing_cg:
#Start Game
selecting = False
play_computer_guess()
answer = input("""
Do You Want to Play Again? (y/n) : """)
if answer == "n":
is_playing_cg = False
while is_playing_hg:
#Start Game
selecting = False
play_human_guess()
answer = input("""
Do You Want to Play Again? (y/n) : """)
if answer == "n":
is_playing_hg = False
end()
The variable is_playing_cg is only available in the "block" that creates it.
Block is function / loop / if statement / etc.
In your program you need to initialize the variable globally so you can call them in multiple functions.
Good luck!
You are defining is_playing_cg inside of a conditional statement at the top of your code. So if that option is not selected, then when you get to the latter conditional statement, it has never heard of that variable.... and it is not defined in the namespace. So you could either define it at the top and give it a default (False) or more better, because you only have 2 options, just use one variable to control the computer / human.
Here is a toy example:
selection = int(input('enter 1 for human, 2 for computer: '))
if selection == 1:
human_play = True
elif selection == 2:
human_play = False
else:
# make some loop that asks for input again or such...
pass
# later on...
if human_play:
# ask human for input...
else:
# have AI make turn
#if needed, you can also handle special cases like this:
if not human_play:
# do something unique to computer turn ...
Additional info...
So you got bit by the scope of the variables in your update. You are defining these variables inside of a function and when you put the defaults outside of the function, they are not in the same scope, so whatever you do inside the function is lost. So, you need to change your function into something that returns the mode you want, and catch that in the function call like such:
def ... :
# input ...
if game_mode == 1:
human_playing = True
selecting = False
elif game_mode == 2:
human_playing = False
selecting = False
return human_playing # this will return T/F back to the function call
And then later:
#Show Game Select Screen
human_playing = game_select_screen()
while not human_playing:
#Start Game
selecting = False
play_computer_guess()
answer = input("""
Do You Want to Play Again? (y/n) : """)
if answer == "n":
is_playing_cg = False
while human_playing:
#Start Game
This (above) works for me, but there are still other logic errors popping up! :) Have fun
This particular error is probably there because you have not defined is_playing_cg as global before using it in your function game_select_screen. Simply put global is_playing_cg at the start of your game_select_screen function to tell python you want to use the global variable instead of creating a scoped variable.
I am building a GUI BMI Calculator app using Python and tkinter and I need some help.
Since there must be no special characters in the user given string, I want an efficient way to detect special characters in a string.
I used regex compile method as I saw online. But it did not detect all the special characters. As when I gave 165,56 instead for 165.56, it returned and error in console. Other characters like #$#!$ etc, all worked perfectly showing tkMessageBox as I programmed.
I've tried each character in string iterating through and finding if special characters are present and I even used regex compile as mentioned above but none satisfies my queries.
regex = re.compile('[#_!#$%^&*()<>?/\|}{~:]')
#assume have already got the value for h from user as 165,65
h = Entry.get(heightEntry)
if not h:
h = "0"
height = 0
elif h.isdigit() == True:
height = float(h)
elif h.isalnum() == True:
height = "None"
elif regex.search(h) == None:
for x in h:
if "." in x:
y += 1
if y >=2:
height = "None"
else:
height = float(h)
else:
height = "None"
#Check height lies between 0.5m and 3.0m or 50cm to 300cm
if not height:
print("There is no value for height to calculate")
tkMessageBox.showerror("Alert","No height value")
else:
if height == "None":
print("Invalid height value")
tkMessageBox.showerror("Alert","Invalid height value")
height = 0
elif not ((50.0<=height<=300.0) or (0.5<=height<=3.0)):
print("Invalid height value",height)
tkMessageBox.showerror("Alert","Invalid height value")
else:
if 50.0<=height<=300.0:
print("Height:",height,"cm")
else:
print("Height:",height,"m")
I expected the outcome to show the message box below height == "None"
But it showing traceback most recent call error.
You can use validatecommand to check whether the input string is a valid float. You can read this post for details.
import tkinter as tk
root = tk.Tk()
def onValidate(P):
try:
float(P)
except:
return False
return True
vcmd = (root.register(onValidate), '%P')
entry = tk.Entry(root, validate="key", validatecommand=vcmd)
entry.pack()
root.mainloop()
I cannot figure out why the if statement in the main() function is throwing error every time instead of checking the variable userChoice like it should. Unless it is and I am just missing something obvious.
import math
PI = 3.14159
def printGreeting():
print('This program will perform calculations based on your choices')
#display menu for user to choose from
def menuDisplay():
print ('Enter 1 to calculate the area of a circle')
print ('Enter 2 to calculate the surface area of a sphere')
print ('Enter 3 to calculate the volume of a sphere')
print ('Enter 4 to quit')
#check the user's choice to make sure it is an int
def choiceCheck(userChoice):
flag = True
while(flag == True):
if (userChoice.isdigit() == True):
int(userChoice)
flag = False
elif (userChoice.isalpha() == True):
print('Choice should be a number.')
flag = False
else: # because everything else has been checked, must be a float
print('Choice should be an int, not float.')
flag = False
return userChoice
#get the positive radius
def radiusF():
flag = True
radius = -1
try:
radius = int(input('Enter the radius: '))
if (radius > 0):
flag = False
else:
print ('The radius has to be positive')
except ValueError:
print ('Radius needs to be a number')
return radius
#calculate the area
def areaF(radius):
area = PI * (radius * radius)
print (area)
#calculate the surface area of a sphere
def surfaceAreaF(radius):
surfaceArea = 4 * PI * (radius * radius)
print (surfaceArea)
#calculate the volume of a sphere
def volumeF(radius):
volume = (4/3 * PI) * (radius ** 3)
print (volume)
def main():
userChoice = -1
printGreeting()
menuDisplay()
userChoice = input('Enter your choice: ')
choiceCheck(userChoice)
radius = radiusF()
This is where my issue arise, or at least shows itself by throwing an error even if userChoice is equal to 1,2, or 3. I know I am missing something but I cannot find it. Thank you for any help you may be able to offer.
if (userChoice == 1):
areaF(radius)
elif (userChoice == 2):
surfaceAreaF(radius)
elif (userChoice == 3):
volumeF(radius)
else:
print('Error')
main()
Cheers
In your choiceCheck() function, int(userChoice) returns an integer, it doesn't convert (not typecast, thanks to #Mad Physicist) userCast into integer. To typecast it:
userChoice = int(userChoice)
Or if you don't want to typecast it, change the numbers in if conditions of main() function into strings.
I'm in my 3rd week of a required college programming course. I was given an assignment to calculate BMI. I can write code that produces the desired output, but the instruction say I must use functions and that is giving me trouble. Here is the code I have come up with and I believe that maybe my issue is that on lines 12, 16, and 20, the input value is not being stored in the function name. Also something else seems to be wrong because when I run it, it asks for the student height twice. If someone could look at this and give me some direction I would really appreciate it.
Instructions...
You are the nutritional coach for a local high school football team. You realize that some of the players are not up to par having returned from summer break. Realizing nutrition plays a key in a productive team, you decide to implement a Body Mass Index Program.
Write a modularized Body Mass Index (BMI) Program which will calculate the BMI of a team player. The formula to calculate the BMI is as follows:
BMI = Weight *703 / Height^2
Note: Height^2 means, the value of Height raised to the power of 2.
Your program should utilize the following functions:
A method to obtain the weight of a player
A method to obtain the height of a player
A method to calculate the BMI of a player
A method to display the height, weight, and calculated BMI
import math
import sys
print("King's BMI Calculator")
while True:
name = input("Please enter student's name or press 0 to quit:")
if name == "0":
break
def h():
height = int(input("Please enter student's height in inches:"))
return height
def w():
weight = int(input("Please enter student's weight in pounds:"))
return weight
def bmi():
total = float((str(w() * 703)/str(h() * str(h()))))
return total
def printbmi():
print(name + "'s BMI Profile")
print("Height:", str(h(), "inches"))
print("Weight:", str(w(), "lbs"))
print("BMI Index:" + str(float(round(bmi(), 1))))
return
def main():
h()
w()
printbmi()
main()
Whenever you call a function (i.e. function_name()), the function is executed. Therefore, your script will ask for input whenever w() or h() is called. A simple solution would be to store the return value to a variable, maybe to weight = w() and height = h() so that you can use the variables when needed instead of calling the entire function every time.
def w():
# ...
return weight
def h():
# ...
return height
def bmi(w, h)
# ...
return total
def printbmi(w, h, total):
# print(w, h, total)
def main():
# prompt
weight = w()
height = h()
total = bmi(weight, height)
printbmi(weight, height, total)
while True:
main()
You can update your code by considering the followings.
Define the functions (h(),w(),bmi()) outside the while loop.
Don't call h() and w() inside main() because you are calling them inside printbmi(). So, your program will ask for input twice for each student.
You should move the main() function outside the loop as well.
You have problem in your printbmi() and bmi() functions as well. You are calling the h() and w() functions many times.
You can update your code as follows.
import math
import sys
def h():
height = int(input("Please enter student's height in inches: "))
return height
def w():
weight = int(input("Please enter student's weight in pounds: "))
return weight
def bmi(height, weight):
total = float((weight * 703)/(height * height))
return total
def printbmi(name):
print(name + "'s BMI Profile")
height = h()
print("Height:", str(height), "inches")
weight = w()
print("Weight:", str(weight), "lbs")
print("BMI Index:" + str(float(round(bmi(height, weight), 1))))
def main(name):
printbmi(name)
print("King's BMI Calculator")
while True:
name = input("Please enter student's name or press 0 to quit:")
if name == "0":
break
else:
main(name)
It outputs:
King's BMI Calculator
Please enter student's name or press 0 to quit:Jack
Jack's BMI Profile
Please enter student's height in inches: 12
Height: 12 inches
Please enter student's weight in pounds: 16
Weight: 16 lbs
BMI Index:78.1
Please enter student's name or press 0 to quit:0