How would I create lists for metric and imperial? - python

I've been trying to put the data input into the program and append it to the lists, but I'm not sure how. My original plan was to create "while" loops and if the length in imperial was 0, then metric would be used to calculate bmi. If not, imperial would be used. I'm just having some trouble figuring out how to do that and how to append the data to their respective lists. It's really important to use lists for that data in this assignment, I just can't figure it out. Thank you!!!
def inputM():
print("Enter weight in kg")
weightm = float(input())
print("Enter height in meters")
heightm = float(input())
return weightm, heightm
def inputI():
print("Enter weight in pounds")
weighti = float(input())
print("Enter height in inches")
heighti = float(input())
return weighti, heighti
def healthindex (preference, bmi):
if preference == "b":
print("BMI " + str(round(bmi,2)))
elif preference == "h":
index = 0
print("your BMI is " + str(round(bmi,2)))
while index < len(BMIList):
if bmi < BMIValues[index]:
print ("And, you are " + BMIList[index])
return
index = index + 1
print("You are Obese")
else:
print("Invalid choice")
return
BMIList = ["severly underweight", "underweight", "healthy", "overweight", "obese"]
BMIValues = [15.99, 18.49, 24.99, 29.99, 500]
print("Welcome to BMI Calculator!")
print("Enter I for Imperial or M for Metric")
request = input().upper()
if request == "M":
weightm, heightm = inputM()
bmi = weightm/(heightm**2)
elif request == "I":
weighti, heighti = inputI()
bmi = (703*weighti)/(heighti**2)
else:
print("Invalid input")
print("Enter b to only see your bmi or enter h if you would like to see your bmi and your corresponding health index!")
preference = input()
healthindex (preference, bmi)

I would suggest that there are better ways to learn about the use and functionality of lists than to use them for user input, however, you could pass a list to the inputM() and inputI() functions, add the user input to those lists, and then calculate the BMI from the items in the list. Here's an example for the metric BMI calculation:
def inputM(user_input):
print("Enter weight in kg")
user_input.append(float(input()))
print("Enter height in meters")
user_input.append(float(input()))
user_input = []
if request == "M":
inputM(user_input)
bmi = user_input[0]/(user_input[1]**2)
This shows how inconvenient and clumsy it is to use lists to capture user input in this scenario. Firstly, an empty list must be created and passed to the function. The function relies on the mutability of lists to return values to the calling code. And then the calling code needs access the result in a cumbersome way by accessing elements of the list by index, or by unpacking the list into variables, e.g.
inputM(user_input)
weightm, heightm = user_input[-2:] # unpack the last 2 items in the list

Related

Variables aren't passing from one function to another why?

I'm a Python beginner and trying to build upon my code below. I have the base working and want to collect the data from the calculator and store it in a dictionary. I created the last function to do this, but I can't pass the variables from bmi_metrics(). Why?
#Intro to BMI Calculator
print("Welcome to my BMI calculator!")
print("Give me your height and weight, I'll calculate your Body Mass Index")
# Gather BMI metrics from user and create two loops that only accept number inputs for height/weight
def bmi_metrics():
get_name = (input("\nWhat's your name? "))
while True:
try:
get_height = float(input(f"\nHi {get_name.title()}, please enter your height in inches: "))
break
except ValueError:
print("Oops, that doesn't look like a number, try again.")
while True:
try:
get_weight = float(input("Please enter your weight in pounds: "))
break
except ValueError:
print("Oops, that doesn't look like a number, try again.")
#Calculate BMI from height and weight input
BMI = (get_weight * 703) / (get_height ** 2)
#Display user BMI and weight category back to them
print(f"{get_name.title()}, your BMI is {BMI:.2f}")
if BMI <= 18.5:
print(f"A person with a BMI of {BMI:.2f} is underwieght ")
elif BMI <= 24.9:
print(f"A person with a BMI of {BMI:.2f} is normal weight ")
elif BMI <= 29.9:
print(f"A person with a BMI of {BMI:.2f} is overweight ")
else:
print(f"A person with a BMI of {BMI:.2f} is obese")
return get_name, get_height, get_weight, BMI
#Prompt user to run calculator again
def prompt_again():
while True:
run_again = input("\nWould you like to do another calculation (y/n)? ")
if run_again == 'y':
bmi_metrics()
elif run_again == 'Y':
bmi_metrics()
elif run_again == 'N':
break
elif run_again == 'n':
break
else:
print("Please enter 'y' or 'n' ")
print("Thanks for playing!")
#Collect Name/BMI data and place it in an empty dictionary
def calc_data():
calc_results = {"Name": " ", "BMI": " "}
get_name = name
bmi_metrics()
prompt_again()
Hello :) You are missing the storage of the returned values from the call at the end of the script:
get_name, get_height, get_weight, BMI = bmi_metrics()
Otherwise, the result is not stored. You have to keep in mind that all variables in python defined inside a method are local to the method unless you store them in an object, return them as result of the method or define them as global variables. If you want to use the resulting values in another function you need to pass them as arguments.

Why isnt the indexing in this python script working?

I'm writing this script for an assignment so I'd appriciate being talked through it rather than simply being handed an answer. Basically I'm trying to convert feet to meters, meters to feet, and provide a sum of the total converted distance in both at the end. Without the [] indexes, It was working perfectly. The new part I've only just added and am struggling with is the [] indexes, and to be honest I'm having a hell of a time groking how they work. Anyways heres the code:
MAX = 256
switch = ""
feet = [0.0] * MAX
meters = [0.0] * MAX
feetpermeter = 3.28084
metersperfoot = 0.3048
sum_meters = 0
sum_feet = 0
def main():
selector()
def selector():
while True:
print("Is your measurement in meters or feet?")
switch = input("Or would you like to quit?")
if (switch == "feet" or switch == "Feet"):
ftm()
elif (switch == "meters" or switch == "Meters"):
mtf()
elif (switch == "quit" or switch == "Quit"):
end()
else:
print("Sorry, that wasn't one of the options.")
print("Lets try that again")
def mtf():
try:
meters[sum_meters] = float(input("Enter the number of meters. "))
feet[sum_feet] = meters * feetpermeter
print("That is", feet, "feet.")
main()
except:
print("Sorry, I didn't quite get that, lets try again.")
mtf()
def ftm():
try:
feet[sum_feet] = float(input("Enter the number of feet. "))
meters[sum_meters] = feet * metersperfoot
print("That is", meters, "meters.")
main()
except:
print("Sorry, I didn't quite get that, lets try again.")
ftm()
def end():
while True:
switch2 = input("Are you sure you want to quit(y/n)?")
if (switch2 == "y" or switch2 == "Y"):
print("you converted a total of ", sum(feet), "feet")
print("And", sum(meters), "meters.")
print("Bye!")
exit()
elif (switch2 == "n" or switch2 == "N"):
print("Ok, let's try that again.")
main()
else:
print("Sorry, that wasn't one of the options.")
print("Lets try that again")
main()
I did try having sum_feet + 1 and sum_meters + 1 after each result but that hadnt worked either.
You are not using the indexing in a proper way. For instance , look at the comments on your existing code:
def mtf():
try:
# Error 1. You stored all the inputs to index 0, as sum_meters is 0 always and its not incremented
# So, all the inputs are not recorded, only last one gets in index 0
meters[sum_meters] = float(input("Enter the number of meters. "))
# Error 2: You multiplied the whole list against the conversion parameter.
# Instead, you should multiply the value at current index
feet[sum_feet] = meters * feetpermeter
# This will print the whole list. Again use the current index here
print("That is", feet, "feet.")
main()
except:
print("Sorry, I didn't quite get that, lets try again.")
mtf()
A fixed version of your function will be like:
def mtf():
try:
# For modifying global variables in a function scope
global sum_meters
global sum_feet
meters[sum_meters] = float(input("Enter the number of meters. "))
feet[sum_feet] = meters[sum_meters] * feetpermeter
print(f"That is {feet[sum_feet]} feet.")
sum_meters += 1
sum_feet += 1
main()
except:
print("Sorry, I didn't quite get that, lets try again.")
mtf()
This fixes stands true for your other functions as well.
I also thought to give you another piece of advice, that you can use a good object oriented approach for such problems, which makes it simpler to implement. You can learn a lot about that, then you will feel more confident.
As an example, see the below code - which does almost same, but in a more crisp way.
class Converter:
FEET_PER_METER = 3.28084
METERS_PER_FOOT = 0.3048
def __init__(self):
self.feet_store = []
self.meter_store = []
self.curr_index = 0
self.menu_handlers = {
"feet": self.feet_to_meter,
"meters": self.meter_to_feet,
"quit": self.summary
}
def run_selection(self, selected):
#
selected = str.lower(selected)
if selected in self.menu_handlers:
# call the relevant function
return self.menu_handlers.get(selected)()
return False
def meter_to_feet(self):
meters_in = float(input("Enter the number of meters."))
to_feet = meters_in * self.FEET_PER_METER
self.meter_store.append(meters_in)
self.feet_store.append(to_feet)
print(f"In Feet : {to_feet}")
return to_feet
def feet_to_meter(self):
feet_in = float(input("Enter the number of feet."))
to_meters = feet_in * self.METERS_PER_FOOT
self.feet_store.append(feet_in)
self.meter_store.append(to_meters)
print(f"In Meters : {to_meters}")
return to_meters
def summary(self):
confirm = input("Are you sure you want to quit(y/n)?")
if confirm in ["y", "Y"]:
print("you converted a total of ", sum(self.feet_store), "feet")
print("And", sum(self.meter_store), "meters.")
print("Bye!")
exit()
else:
return False
def main():
converter = Converter()
while True:
choice = input("Is your measurement in meters or feet (meters/feet/quit)?")
converter.run_selection(choice)
I hope this gives you better insights.
So theres two problems with what you've tried to do here, in the lines:
meters[sum_meters] = float(input("Enter the number of meters. "))
feet[sum_feet] = meters * feetpermeter
meters * feetpermeter is multiplying an array by a number, you need to do meters[sum_meters] to get the number you want. Secondly as you said, you need to increment sum_meters each time, but because you're inside a function you will need to declare the variable as a global before you change it. Also since sum_meters and sum_feet are always going to be equal, you can just use a single variable to keep track of this:
def mtf():
try:
global index
meters[index] = float(input("Enter the number of meters. "))
feet[index] = meters[index] * feetpermeter
index += 1
print("That is", feet, "feet.")
main()
except:
print("Sorry, I didn't quite get that, lets try again.")
mtf()
def ftm():
try:
global index
feet[index] = float(input("Enter the number of feet. "))
meters[index] = feet * metersperfoot
index += 1
print("That is", meters, "meters.")
main()
except:
print("Sorry, I didn't quite get that, lets try again.")
ftm()
I would also go a little further and say that the use of lists is unnecessary for this problem, you could simply have two numbers, total_meters and total_feet and add the values as you go. This would take less memory and also remove the arbitrary limit of 256 goes that has been imposed. So I would do:
import sys
MAX = 256
switch = ""
total_feet = 0
total_meters = 0
feetpermeter = 3.28084
metersperfoot = 0.3048
sum_meters = 0
sum_feet = 0
index = 0
def main():
selector()
def selector():
while True:
print("Is your measurement in meters or feet?")
switch = input("Or would you like to quit?")
if switch == "feet" or switch == "Feet":
ftm()
elif switch == "meters" or switch == "Meters":
mtf()
elif switch == "quit" or switch == "Quit":
end()
sys.exit(0)
else:
print("Sorry, that wasn't one of the options.")
print("Lets try that again")
def mtf():
try:
global total_feet
global total_meters
meters = float(input("Enter the number of meters. "))
feet = meters * feetpermeter
total_meters += meters
total_feet += feet
print("That is", feet, "feet.")
main()
except Exception as e:
print(e)
print("Sorry, I didn't quite get that, lets try again.")
mtf()
def ftm():
try:
global total_feet
global total_meters
feet = float(input("Enter the number of feet. "))
meters = feet * metersperfoot
total_meters += meters
total_feet += feet
print("That is", meters, "meters.")
main()
except Exception as e:
print(e)
print("Sorry, I didn't quite get that, lets try again.")
ftm()
def end():
while True:
switch2 = input("Are you sure you want to quit(y/n)?")
if switch2 == "y" or switch2 == "Y":
print("you converted a total of ", total_feet, "feet")
print("And", total_meters, "meters.")
print("Bye!")
exit()
elif switch2 == "n" or switch2 == "N":
print("Ok, let's try that again.")
main()
else:
print("Sorry, that wasn't one of the options.")
print("Lets try that again")
main()

How do I get a return value for BMI in this loop?

I'm working on an assignment to create a code that receives input from the user on a name, weight, and height and then returns a BMI value and then loops back to ask for another name. I cannot seem to get my BMI function to return an output though.
def BMI(BMI):
num1, num2 = weight, height
BMI = (num1 * 706)/(num2^2)
return BMI
user = str
end = "x"
while user != end:
print()
user = input("Please enter player name or type 'X' to quit: ")
if user == end:
print("Report Complete")
break
else:
num1 = (float(input("Please enter weight: ")))
num2 = (float(input("Please enter height: ")))
if num1 >= 1:
print("BMI: "(BMI))
i receive this error: "" when I run the function.
I'm looking for an input that is along the lines of
Please enter player name or press 'X' to quit: xxx
Please enter weight: xxx
Please enter height: xxx
BMI: xxx
Please enter player name or press 'X' to quit:
Okay, so there are a few things that you'll want to fix for this to work.
When you are printing, you are not calling the function correctly and python thinks you're trying to use "BMI: " as a function. How you want to call BMI is like BMI(weight, height) where you pass in the values for weight and height as parameters. BMI returns a float, so you'll need to turn it into a string before appending it. The result of those changes are "BMI: "+ str(BMI(num1, num2))
In the definition of your BMI function, you'll want to pass in the weight and height as parameters like so: def BMI(weight, height):. This will allow you to use both weight and height in the function body.
The ^ in python does not mean power, it means bitwise xor. You want to use the ** operator like so: BMI = (num1 * 706)/(num2**2)
After making those changes, you should end up with something like this:
def BMI(weight, height):
num1, num2 = weight, height
BMI = (num1 * 706.0)/(num2**2)
return BMI
user = str
end = "x"
while user != end:
print()
user = input("Please enter player name or type 'X' to quit: ")
if user == end:
print("Report Complete")
break
else:
num1 = (float(input("Please enter weight: ")))
num2 = (float(input("Please enter height: ")))
if num1 >= 1:
print("BMI: " + str(BMI(num1, num2)))

Storing items within a dictionary to be then used to calculate area

I'm pretty new to Python (2 days) and I'm struggling to find a solution to add a variable to a dictionary with a defined value as well as
choice = input("")
if choice == "1":
print ("1.Basic - £8")
print ("2.Standard- £13")
print ("3.Premium- £25")
Premium = dict(name ="Premium",
Cost = 25.0)
Standard = dict(name ="Standard",
Cost = 13.0)
Basic = dict(name ="Basic",
Cost = 8.0)
Grass_Dict = {}
Premium = input("Type Premium")
Basic = print(input("Type '3' for Basic")
Grass_Dict['1'] = Premium
Grass_Dict['2'] = Standard
Grass_Dict['3'] = Basic
I have then tried to add the variables to the second part of the code so that when I reference the cost calculation I will be able to use the stored variable and it's value (25.0) to be used.
elif (choice =="2"):
time.sleep(0.2)
print("-")
time.sleep(0.2)
print("-")
print("2.Select Area of Grass")
print("1.Select Shape Required")
if (choice =="1"):
print("Grass Calculation Program")
print("Select Shape Required")
print("1.Square")
print("2.Triangle")
print("3.Circle")
shape = input ("Please Select (1/2/3)")
if choice =="1":
length = input ("Please Enter Length")
width = input ("Please Enter Width")
area = (length*width)
print ("Calculating Cost")
elif choice =="2":
length = input ("Please Enter Length")
width = input ("Please Enter Width")
Thanks for everyone's help!

Adding floating numbers in python

Trying to add all the BMI results together and then display it, keep getting a error :
TypeError: 'float' object is not iterable
Also keep getting None printed when i run my program after a bmi is calculated>?
def bmirange():
if bmi >= 25.0:
print('Your BMI measurement shows that you are overweight')
elif bmi <18.0:
print('Your BMI measurement shows that you are underweight')
else:
print('Your BMI measurement shows that you are in the healty weight band')
weight = float(input('What is your weight in Kg? '))
height = float(input('What is your height in Meters? '))
bmi = weight / (height * height)
print(bmi)
print(bmirange())
bmiredo = input('Do you want to do another BMI measurement?, y / n ')
while bmiredo == 'y':
weight = float(input('What is your weight in Kg? '))
height = float(input('What is your height in Meters? '))
print(bmi)
print(bmirange())
bmiredo = input('Do you want to do anoher BMI measurement?, y / n ')
else:
print('ok, the total of your BMI results are')
print(sum(bmi))
input('press the enter key to exit')
The problem is here:
print(sum(bmi))
The bmi variable is a number, but if you want to use sum() you need a list of numbers. Here is how you can collect a list of numbers. The .append() method adds an element to the end of a list.
bmi_list = []
...
bmi = weight / height**2
bmi_list.append(bmi)
...
while ...:
....
bmi = weight / height**2
bmi_list.append(bmi)
...
...
print(sum(bmi_list))
Note
There is also an error with bmirange(): print() is called twice. You can either put the print() inside bmirange(), or you can print() the results of bmirange(), but doing both will result in None being printed out, which I assume is not what you want.
Solution 1
def bmirange():
if bmi >= 25.0:
print('Your BMI measurement shows that you are overweight')
elif bmi <18.0:
print('Your BMI measurement shows that you are underweight')
else:
print('Your BMI measurement shows that you are in the healty weight band')
...
bmirange() # will print itself
Solution 2
def bmirange():
if bmi >= 25.0:
return 'Your BMI measurement shows that you are overweight'
elif bmi <18.0:
return 'Your BMI measurement shows that you are underweight'
else:
return 'Your BMI measurement shows that you are in the healty weight band'
...
print(bmirange()) # will not print itself

Categories