Trying to print, but says my function name is not defined? - python

name = str(input("What is your name? "))
age = int(input("What is your age? "))
weight_float = float(input("What is your weight in pounds? "))
height_float = float(input("What is your height in inches? "))
Pounds2Kilogram = weight_float * 0.453592
Inches2Meter = height_float * 0.0254
weight = Pounds2Kilogram
height = Inches2Meter
class calcBMI:
def __init__(self, name, age, weight, height):
self.__name = name
self.__age = age
self.__weight = weight
self.__height = height
def getBMI(self):
return self.__weight / (self.__height **2)
def getStatus(self):
if getBMI() < 18.5:
self.__getStatus = "Underweight"
elif 18.5 < getBMI() < 24.9:
self.__getStatus = "Normal"
elif 25.0 < getBMI() < 29.9:
self.__getStatus = "Overweight"
elif getBMI() > 30:
self.__getStatus = "Obese"
def getName(self):
return self.__name
def getAge(self):
return self.__age
def getWeight(self):
return self.__weight
def getHeight(self):
return self.__height
a = calcBMI(name, age, weight, height)
print("The BMI for ", a.getName(), " is ", a.getBMI(), "which is ", a.getStatus())
I have a bit of an issue when trying to print for this BMI calculator, at the very end it should look like,
"The BMI for (name) is (BMI number), which is (status, basically if they're underweight, overweight etc.)"
In the getStatus() i am trying to take the numeric value from getBMI() and use it in the if statement. (I don't know why this is big and bold lettered)
The problem arises when I try to print, it's prompts me to input my name, age, weight, and height like normal.
This is what it outputs: NameError: name 'getBMI' is not defined

The reason is in the getStatus function, you are calling getBmi but you should be calling self.getBmi()
The getStatus function should look like this:
def getStatus(self):
if self.getBMI() < 18.5:
self.__getStatus = "Underweight"
elif 18.5 < self.getBMI() < 24.9:
self.__getStatus = "Normal"
elif 25.0 < self.getBMI() < 29.9:
self.__getStatus = "Overweight"
elif self.getBMI() > 30:
self.__getStatus = "Obese"
return self.__getStatus
Also, as input automatically returns a string, you can just say
name = input("What is your name? ")

getBMI is not defined as a global function, and so a NameError is thrown when you try to refer to it as just getBMI. The method of this name cannot be referenced nakedly like this in the way that C++ methods can. Instead, an instance must refer to its methods as attributes of self, i.e. as self.getBMI() in this case.

Related

i would like to assign subclasses to the charecter? how do i do this?

the problem i has is that the errors that occur are found in the code that works. it doesnt make sence.
my code is:
import random
import pickle
class person():
def __init__(self, name, hp, luck, xp, level, gold, age, location, strength, intellegence):
self.name = name
self.hp = hp
self.luck = luck
self.xp = xp
self.level = level
self.strength = strength
self.gold = gold
self.location = location
self.age = age
self.intellegence = intellegence
#self.x = 0
#self.y = 0
def talk(self):
return "hello my name is %s. i have %d strength. i am %d years old. i am from %s. I have %d intellence" %(self.name,self.strength,self.age,self.location, self.intellegence)
#def walk(self,newlocation):
# self.x += movex
# self.y += movey
# self.location = newlocation
def takedmg(self, amount):
self.hp = self.hp - amount
def heal(self, amount):
self.hp = self.hp + amount
def attack(self):
pass
allpeople = []
def createperson():
global allpeople
name = input("enter name: ")
hp = 100
luck = random.randint(1,15)
xp = 0
level = 1
gold = 0
age = int(input("enter age: "))
location = input("enter location: ")
strength = random.randint(1,25)
intellegence = 50
aperson = person(name, hp, luck, xp, level, gold, age, location, strength, intellegence)
allpeople.append(aperson)
savedata()
def findchara():
charaname = input("enter the name of the charecter: ")
for foundchara in allpeople:
if foundchara.name == charaname:
print("found \n")
return(foundchara)
return""
def savedata():
savedata = open("mypeople.pickle","wb")
pickle.dump(allpeople,savedata)
savedata.close()
def loaddata():
global allpeople
loaddata = open("mypeople.pickle","rb")
allpeople = pickle.load(loaddata)
loaddata.close()
class warrior(person):
def __init__(self, name, hp, luck, xp, level, gold, age, location, strength, intellegence):
person.__init__(self)
class1 = warrior
class mage(person):
def __init__(self, name, hp, luck, xp, level, gold, age, location, strength, intellegence):
person.__init__(self)
class1 = mage
class trader(person):
def __init__(self, name, hp, luck, xp, level, gold, age, location, strength, intellegence):
person.__init__(self)
class1 = trader
def talk_warrior(person, warrior):
self.strength = self.strength + 15
self.intellegence = self.intellegence - self.intellegence + random.randint(0,5)
return "Hi, name is %s. %d strength. I am %d. from %s. intellegence? %d" %(self.name,self.strength,self.age,self.location,self.intellegence)
def talk_mage(person, mage):
self.strength = self.strength - self.strength + random.randint(0,5)
self.intellegence = self.intellegence + 50
return "Hello my name is The Great MAGE %s. I have %d strength DONT QUESTION MY STRENGTH. I am %d years old. I happened to be from %s. my intellegence also happens to be %d which is superior to everyone else." %(self.name,self.strength,self.age,self.location,self.intellegence)
def talk_trader(person, trader):
return "Hello my name is %s. I have %d strength. I am %d years old. I am from %s. I am very average and my intellegence is %d " %(self.name,self.strength,self.age,self.location,self.intellegence)
loaddata()
def classmenu():
charaloop = True
while charaloop == True:
option = int(input("1. warrior \n2. mage \n3. trader \n9. change class \n0. exit \n"))
if option == 1:
classchara = findchara()
class1 = warrior
print("Class has been set to warrior.")
talk_warrior()
elif option == 2:
classchara = findchara()
class1 = mage
print("Class has been set set to mage.")
talk_mage()
elif option == 3:
classchara = findchara()
class1 = trader
print("Class has been set to trader.")
talk_trader()
elif option == 9:
pass
elif option == 0:
print("returning to main menu. :) \n")
charaloop = False
savedata()
else:
print("invalid choice")
def menu():
mainloop = True
while mainloop == True:
option = int(input("1. create character. \n2. character list. \n3. look for a charecter. \n4. select charecter class. \n8. continue... \n9. delete character from list. \n0. exit \n choice: "))
if option == 1:
print("you will now create your character!!!")
createperson()
elif option == 2:
for aPerson in allpeople:
print(aPerson.talk())
elif option == 3:
findchara()
elif option == 4:
classmenu()
elif option == 8:
if class1 == warrior:
talk_warrior()
elif class1 == mage:
talk_mage()
elif class1 == trader:
talk_trader()
else:
print("ERROR!")
elif option == 9:
chara = findchara()
allpeople.remove(chara)
print("charecter removed")
savedata()
elif option == 0:
print("bye!!! :)")
mainloop = False
savedata()
else:
print("invalid choice")
menu()
the errors are:
Traceback (most recent call last):
File "D:\python stuff\python chara game ulsfdgklfsgnklfs.py", line 173, in <module>
menu()
File "D:\python stuff\python chara game ulsfdgklfsgnklfs.py", line 151, in menu
classmenu()
File "D:\python stuff\python chara game ulsfdgklfsgnklfs.py", line 118, in classmenu
talk_warrior()
TypeError: talk_warrior() missing 2 required positional arguments: 'person' and 'warrior'
the code is meant to run in the shell and is a simple class and subclass game that the player creates a character and then assigns it a subclass which changes the attributes of the character. this is where my problems started. in the future I want the character to be able to travel and then will encounter monsters attack and receive damage.
id like to hear some advice on what I could do to improve and make the code better smoother and also fix these problems that have occurred. I've only been coding for a while so there is allot of things wrong with this code.

calculating bmi using sentinel loop where user inputs values until user enters values

I have a frame for the python code that calculates bmi.
i have done most of the part but I cannot seem to get around the sentinel loop. The goals are:
user enters a patient identification number (an int), patient name (a string), patient height in inches (a positive float), and patient weight in pounds (a positive float) until the user enters a negative number for the patient ID .
I have done the BMI calculation.
For each patient’s information entered, output a well-formatted result listing the patient’s ID, name, calculated BMI (output with 1 digit of precision) and associated category (Underweight, Obese, etc.). The use of f-strings to produce the formatted output is recommended.
After trying and some googling, here is what I have. I would like help with the sentinel loop.
class BodyMassIndex:
def __init__(self, pid, name, weight, height):
self.patient_id = pid
self.name = name
self.weight = weight
self.height = height
#property
def body_mass_index(self):
return round((self.weight * 703) / self.height ** 2, 1)
#property
def score(self):
if self.body_mass_index < 18.5:
return 'Underweight'
elif self.body_mass_index < 25:
return 'Healthy Weight'
elif self.body_mass_index < 30:
return 'Overweight'
else:
return 'Obese'
def print_score(self):
print('Patient id {}: {} has a bmi score of {}. Patient is {}.'.format(self.patient_id, self.name, self.body_mass_index, self.score))
def _get_user_info():
while True:
try:
pid = int(input("Please enter your 5-digit patient id: "))
p_name = input("Please enter patient first name and last name: ")
weight = float(input('Enter weight in pounds: '))
height = float(input('Enter height in inches: '))
if 0 < weight and 0 < height < 107:
return pid, p_name, weight, height
else:
raise ValueError('Invalid height or weight. Let us start over.')
except ValueError:
print('Invalid height or weight input')
continue
def calculate_bmi():
pid, name, weight, height = _get_user_info()
return BodyMassIndex(pid, name, weight, height)
if __name__ == '__main__':
bmi = calculate_bmi()
bmi.print_score()
I was told I would need to delete the print_score function and instead I should have a table of values entered and bmi result when user entered a wrong/negative patient id. It does not need to be 5-digit patient id.

List returns None value instead of class object

In my role-playing party creator program, I am trying to have the user create a class object, adding the attributes, and storing it into a party-list index. However, by the time the player goes back to the main menu (the main() function that displays the party list), the slot still shows a None value. Here is my code:
class Creature:
def __init__(self):
self.name = None
self.feet = None
self.inches = None
self.weight = None
self.gender = None
def getName(self):
return "Name: {}".format(self.name)
def setName(self, name):
self.name = name
def getHeight(self):
return "Height: {} ft. {} in.".format(self.feet, self.inches)
def setFeet(self, feet):
self.feet = feet
def setInches(self, inches):
self.inches = inches
def getWeight(self):
return "Weight: {} lbs.".format(self.weight)
def setWeight(self, weight):
self.weight = weight
def getGender(self):
return "Gender: {}".format(self.gender)
def setGender(self, index):
genders = ['Male', 'Female', 'Others']
if int(index) == 1:
self.gender = genders[0]
elif int(index) == 2:
self.gender = genders[1]
elif int(index) == 3:
self.gender = genders[2]
class Dragon(Creature):
pass
class Mermaid(Creature):
pass
class Fairy(Creature):
pass
class Vampire(Creature):
pass
#allows the user to change attributes of creature
def changeAttributes(creature):
value = input("Pick an attribute to change: 1) name 2) height 3) weight 4) gender 5) save")
if int(value) == 1:
creature.setName(input("Enter a name: "))
return changeAttributes(creature)
elif int(value) == 2:
creature.setFeet(input("Enter a foot value: "))
creature.setInches(input("Enter an inch value: "))
return changeAttributes(creature)
elif int(value) == 3:
creature.setWeight(input("Enter a value in pounds: "))
return changeAttributes(creature)
elif int(value) == 4:
creature.setGender(input("Enter a value to set gender; 1 = male, 2 = female, 3 = others: "))
return changeAttributes(creature)
elif int(value) == 5:
confirm = input("Save? 1) yes 2) no")
if int(confirm) == 1:
print('Saving...')
return menu(creature)
else:
return changeAttributes(creature)
else:
print("Not a valid input, please try again.")
return changeAttributes(creature)
#prints the attributes of the creature
def showAttributes(creature):
print(creature.getName())
print(creature.getHeight())
print(creature.getWeight())
print(creature.getGender())
menu(creature)
def Delete(creature):
a = input("Are you sure? 1) yes 2) no ")
if int(a) == 1:
print("Deleting...")
creature = None
return main()
elif int(a) == 2:
print("Cancelled")
return menu(creature)
#checks to see if slot is empty or has a creature object; if empty, create a creature, otherwise go to creature menu
def menu(creature):
value = input("Select an option 1) Show Attributes 2) Change Attributes 3) Delete 4) Back")
if int(value) == 1:
return showAttributes(creature)
return menu(creature)
elif int(value) == 2:
return changeAttributes(creature)
return menu(creature)
elif int(value) == 3:
return Delete(creature)
elif int(value) == 4:
return main()
#checks if slot is empty, if empty, choose a creature subclass and change attributes, else takes user directly to change attribute menu
def check(slot):
if slot == None:
a = input('Choose a creature: 1) Dragon 2) Fairy 3) Mermaid 4) Vampire')
if int(a) == 1:
slot = Dragon()
elif int(a) == 2:
slot = Fairy()
elif int(a) == 3:
slot = Mermaid()
elif int(a) == 4:
slot = Vampire()
return changeAttributes(slot)
else:
return menu(slot)
#user select a slot; note that since development has not finished, you can only change slot 1
def main():
global party
print(party)
inp = input("Select a slot: ")
inp_1 = int(inp) - 1
if int(inp) > 0 and int(inp) < 6:
print("Slot {} selected!".format(int(inp)))
return check(party[inp_1])
party = [None, None, None, None, None]
main()
This is how the program runs so far:
[None, None, None, None, None]
Select a slot:
#User inputs 1
Slot 1 selected!
Choose a creature: 1) Dragon 2) Fairy 3) Mermaid 4) Vampire
#User inputs 1
Pick an attribute to change: 1) name 2) height 3) weight 4) gender 5) save
#User inputs 1
Enter a name: *Name*
Pick an attribute to change: 1) name 2) height 3) weight 4) gender 5) save
#User inputs 5
Save? 1) yes 2) no
#User inputs 1
Saving...
Select an option 1) Show Attributes 2) Change Attributes 3) Delete 4) Back
#User inputs 4
However, after you go back to main(), the list still displays as such:
[None, None, None, None, None]
Select a slot:
What doesn't make sense is that the parameters in the functions should have followed a chain rule that will eventually lead to the party slot. I want it so that a slot index will have a class object stored in it rather than None. As far as I know, I might need to use global variables, but I haven't found out much after that. Any ways to fix this?
Edit: So I managed to fix the problem. I just put the check() function in the main(). It goes like this:
def main():
print(party)
inp = input("Select a slot: ")
inp_1 = int(inp) - 1
if int(inp) > 0 and int(inp) < 6:
print("Slot {} selected!".format(int(inp)))
if party[inp_1] == None:
a = input('Choose a creature: 1) Dragon 2) Fairy 3) Mermaid 4) Vampire')
if int(a) == 1:
slot = Dragon()
elif int(a) == 2:
slot = Fairy()
elif int(a) == 3:
slot = Mermaid()
elif int(a) == 4:
slot = Vampire()
party[inp_1] = slot
return changeAttributes(party[inp_1])
else:
return menu(party[inp_1])
There is no sens of "return" at the end of main. What you should want to do I think is editing the party list. Therefor instead of
return check(party[inp_1])
you should try
party[inp_1] = check(party[inp_1])
Make sure the check function returns a creature type, I'm not sure of that.
there is some really weird interaction you really should try to make class and methods for all of that. In your 4th elseif in the menu function, you shouldn't have to call main again.

Why am I getting a name error when I defined the variable?

def calculate_letter_grades(test_score):
if test_score >= 90:
return "A"
elif test_score >= 80 and test_score < 90:
return "B"
elif test_score >= 70 and test_score < 80:
return "C"
elif test_score >= 60 and test_score < 70:
return "D"
else:
return "F"
def caluculate_avg(scores):
all_grades = 0
for i in range(len(scores)):
all_grades = all_grades + scores[i]
return all_grades / float(len(scores))
for c in range(6):
scores = []
student_name = input("Please enter the student\'s name: ")
for x in range(6):
test_score = int(input("Please enter test scores: "))
scores.append(test_score)
scores_averaged = calculate_avg(scores)
print("Student: ", students_name)
for z in range(len(scores)):
print("Test Score: ", scores[z], "Test Letter Grade: ", calcualte_letter_grades(scores[z]))
print("Average test score: ", scores_averaged)
The error I am getting is:
"NameError: name 'calculate_avg' is not defined"
I don't understand why though, I thought I had it defined.
I think you miss spelled the word "calculate" on
def caluculate_avg(scores):
change to
def calculate_avg(scores):
The function name is spelled incorrectly 'caluculate'.
Your function name is caluculate_avg but you call calculate_avg
So that is just a typo problem and change this line
def caluculate_avg(scores):
To this
def calculate_avg(scores):
Because there is a typo in function name and calling.
You are defining
def caluculate_avg(scores):
but you are using
scores_averaged = calculate_avg(scores)
Change the function definition to
def calculate_avg(scores):
You called your function with a different name, 'calculate_avg' instead of 'caluculate_avg', make sure you have the same function name when calling it

call function from function python

I am doing a simple calculation for burning calories.
I am getting data and variables from users and I have two formulas.
The BMR function works. The tee keeps throwing errors (mostly on cannot call a float) and when it does not I get something like <function a0…>.
def bmr(gender, age, height, weight):
if gender == "f":
bmr = 655 + weight*9.6 + height*1.6 + age*4.7
else:
bmr = 66 + weight*13.8 + height*5 + age*6.8
return bmr
def tee (bmr, amount_of_exersice):
#x = 0
y = bmr(gender, age, height, weight)
if amount_of_exersice == 0:
x = 1.2
elif 1<= amount_of_exersice <= 2:
x = 1.375
elif 3 <= amount_of_exersice <= 5:
x = 1.55
else:
x = 1.725
z = x * y
return z
A couple of problems, you're redefining "bmr" and you're not passing the right arguments to second bmr call. Try, as example:
def tee (gender, age, height, weight, amount_of_exersice):
y = bmr(gender, age, height, weight)
if amount_of_exersice == 0:
x = 1.2
elif 1<= amount_of_exersice <= 2:
x = 1.375
elif 3 <= amount_of_exersice <= 5:
x = 1.55
else:
x = 1.725
z = x * y
return z
or if you want to define bmr before:
def tee (y, amount_of_exersice):
if amount_of_exersice == 0:
x = 1.2
elif 1<= amount_of_exersice <= 2:
x = 1.375
elif 3 <= amount_of_exersice <= 5:
x = 1.55
else:
x = 1.725
z = x * y
return z
y_bmr = bmr(gender, age, height, weight)
tee(y_bmr, amount_of_exersice)
When you do
def tee(bmr, amount_of_exersize):
You're redefining the name bmr to point to whatever variable you're passing in - whereas, if you hadn't done that, it would have referred to the function above. This replacement applies so long as you're within the method, and the only real solution is to rename the parameter so that it doesn't conflict:
def tee(something_else, amount_of_exersize):
y = bmr(gender, age, height, weight)
def validate_user_input(prompt, type_=None, min_=None, max_=None, range_=None):
if min_ is not None and max_ is not None and max_ < min_:
raise ValueError("min_ must be less than or equal to max_.")
while True:
ui = input(prompt)
if type_ is not None:
try:
ui = type_(ui)
except ValueError:
print("Input type must be {0}.".format(type_.__name__))
continue
if max_ is not None and ui > max_:
print("Input must be less than or equal to {0}.".format(max_))
elif min_ is not None and ui < min_:
print("Input must be greater than or equal to {0}.".format(min_))
elif range_ is not None and ui not in range_:
if isinstance(range_, range):
template = "Input must be between {0.start} and {0.stop}."
print(template.format(range_))
else:
template = "Input must be {0}."
if len(range_) == 1:
print(template.format(*range_))
else:
print(template.format(" or ".join((", ".join(map(str,
range_[:-1])),
str(range_[-1])))))
else:
return ui
def bmr(gender, age, height, weight):
if gender == "f":
bmr = 655 + weight*9.6 + height*1.6 + age*4.7
else:
bmr = 66 + weight*13.8 + height*5 + age*6.8
return bmr
def tee (gender, age, height, weight, amount_of_exersice):
y = bmr(gender, age, height, weight)
if amount_of_exersice == 0:
x = 1.2
elif 1<= amount_of_exersice <= 2:
x = 1.375
elif 3 <= amount_of_exersice <= 5:
x = 1.55
else:
x = 1.725
z = x * y
return z
## user info ##
gender = validate_user_input("Please enter your gender (F -Female / M- Male): ", str.lower, range_=("f","m"))
age = validate_user_input("Please enter your age: ", int, 1, 110)
height = validate_user_input("Please enter your height in cm: ", int, 130, 230)
weight = validate_user_input("Please enter your weight in kg: ", float, 20, 400)
amount_of_exersice = validate_user_input("Please enter the amount of days you engage in physical activity per week: ", int, 0, 7)
calc_bmr = bmr(gender, age, height, weight)
calc_tee = tee(gender, age, height, weight, amount_of_exersice)
print("Your Basal Metabolic Rate is ", calc_bmr)
print("Your daily calories burn is ", calc_tee)

Categories