How would while true work in this exact case? - python

I'm trying to get it when you type RecPyrSA it will play the def RecPyrSA and I'm not sure how that could be done. I'm also new to python and not sure what to do so I just wanted to make a fun script.
from math import e
def RecPyrSA():
recpyrl=float(input("Base Length "))
recpyrw=float(input("Base Width "))
recpyrthl=float(input("Triangle Height On The Legth Side "))
recpyrthw=float(input("Triangle Height On The Width Side "))
recpyrsa=(recpyrl*recpyrw+recpyrthl*recpyrl+recpyrthw*recpyrw)
print(recpyrsa)
def ConeSA():
print ("type r then l")
x=float(input("r "))
y=float(input("l "))
csa=(3.14*x*x)+(3.14*y*x)
print(csa)
start=input("Type Here --> ")
while True:
print ("For the surface area of a rectangular pyramid type RecPyrSA")
SAstart=input("Type here ---> ")
if SAstart == "RecPyrSA"
RecPyrSA
break
else:
print ("Incorrect Code")
print ("Try Again")

You didn't call the function.
RecPyrSA
is simply a variable with a function object in it. Once you've referenced a function object, it is called with parens
RecPyrSA()

You need to call the function, which you do with parenthesis, function_name(). Also, you don't appear to use e from math, so you don't need to import that. You were also missing a colon at the end of the line: if SAstart == "RecPyrSA". You should also add space on either side of operators, as according to PEP 8. Also according to PEP 8, function names should be in snake_case.
Code with changes:
def rec_pyr_SA():
recpyrl = float(input("Base Length "))
recpyrw = float(input("Base Width "))
recpyrthl = float(input("Triangle Height On The Legth Side "))
recpyrthw = float(input("Triangle Height On The Width Side "))
recpyrsa = recpyrl * recpyrw + recpyrthl * recpyrl + recpyrthw * recpyrw
print(recpyrsa)
def cone_sa():
print("type r then l")
x = float(input("r "))
y = float(input("l "))
csa = (3.14 * x * x) + (3.14 * y * x)
print(csa)
while True:
print ("For the surface area of a rectangular pyramid type RecPyrSA")
SA_start = input("Type here ---> ")
if SA_start == "RecPyrSA":
rec_pyr_SA()
break
else:
print("Incorrect Code")
print("Try Again")

Related

Trying to create a class which goes in a loop once the class and def is called

I'm creating a simple program to take in time and distance to then state the speed, but I want to do this with classes to learn about oop in python. I'm not figuring out how to set the loop to keep going until the user decides to not go again.
y=True
while y:
class Timer:
def __init__(self,speed):
self.speed=speed
def log(self):
print(mph)
again=input('Go again? y or n: ')
if again=='y':
y=True
else:
print('Thank you')
y=False
m=float(input('Enter the minutes: '))
s=float(input('Enter the seconds: '))
d=float(input('Enter distance: '))
x=(m*60)+s
x_tot=(x/3600)
mph=d/x_tot
t=Timer(mph)
t.log()
You need following code:
y=True
while y:
class Timer:
def __init__(self,speed):
self.speed=speed
def log(self):
print(mph)
global y
again=input('Go again? y or n: ')
if again=='y':
y=True
else:
print('Thank you')
y=False
if y:
m=float(input('Enter the minutes: '))
s=float(input('Enter the seconds: '))
d=float(input('Enter distance: '))
x=(m*60)+s
x_tot=(x/3600)
mph=d/x_tot
t=Timer(mph)
t.log()
else:
break
The y variabel inside log function should be global else it won't change global y referred inside if-else. We need if-else with y so that we can break out of loop if user chooses n. The t=Timer(mph) has to be inside while loop because class is not known outside the loop. Same applies for t.log function call.
Honestly to make your code easier to debug and track where changes are occuring, you should pull the class out of the loop and then reference it inside the loop when you need to use it.
In the init, I would pull out the assignment of the speed variable and just initialize it as none.
def __init__(self):
self.speed = None
Then you can add a separate private setter function to set the speed with user input and do error checking around it. Note, I have set the program to exit with a 0 code if the user inputs something wrong, but you can easily make another loop here that will wait until the user finally does input valid values for all the inputs. The __ double underscore in front of the function name makes it private to the class.
def __set_mph(self):
try:
m = float(input('Enter the minutes: '))
s = float(input('Enter the seconds: '))
d = float(input('Enter distance: '))
x = (m * 60) + s
x_tot = (x / 3600)
self.mph = d / x_tot
except (ValueError, ArithmeticError) as e:
print(f'Invalid user input: {e}')
exit(0)
except Exception as e:
print(f'Unexpected error: {e}')
exit(0)
Now you can update the log function to not even worry about the y variable by changing it to this:
def log(self):
self.__set_mph()
print(mph)
again = input('Go again? y or n: ')
if again == 'y':
return True
else:
print('Thank you')
return False
Now we just initialize the class before the loop and clean it up to be make it more manageable.
t = Timer()
while True:
if not t.log():
break
Final Code:
class Timer:
def __init__(self):
self.speed = None
self.mph = None
def __set_mph(self):
try:
m = float(input('Enter the minutes: '))
s = float(input('Enter the seconds: '))
d = float(input('Enter distance: '))
x = (m * 60) + s
x_tot = (x / 3600)
self.mph = d / x_tot
except (ValueError, ArithmeticError) as e:
print(f'Invalid user input: {e}')
exit(0)
except Exception as e:
print(f'Unexpected error: {e}')
exit(0)
def log(self):
self.__set_mph()
print(self.mph)
again = input('Go again? y or n: ')
if again == 'y':
return True
else:
print('Thank you')
return False
t = Timer()
while True:
if not t.log():
break
OOP is all about modeling your real world objects into programmatic objects that maintain the features and functionality of the real world object to its programatic counterpart's attributes and features, respectively.
Also, those objects should be separated on its own. Creating and calling a class from within a while loop is pretty bad practice. I would encourage you to separate the code based on its purpose. for example, I would have a file called timer.py to handle the Object that matches the timer like so:
# The timer class
class Timer:
def calculate_speed(self, minutes, seconds, distance):
hours = (minutes * 60) + seconds
tot_time = (hours / 3600)
return distance / tot_time
def get_speed(self):
minutes = float(input('Enter the minutes: '))
seconds = float(input('Enter the seconds: '))
distance = float(input('Enter distance: '))
return self.calculate_speed(minutes, seconds, distance)
Then in your main file:
from timer import Timer
timer = Timer()
while True:
user_response = input('Go again? y or n: ').lower()
if user_response == 'n':
break
elif user_response == 'y':
speed = timer.get_speed()
print(f'Your speed is {speed}')
else:
print('Not a valid response')
This makes it easier on the backend too. In other words, if you have an error that relates to the calculations, you know where to start looking.

List of objects only saving the last object in Python program

So I have an otherwise easy homework assignment that wants me to input my grades for subjects, etc. The amount of input varies with the number of subjects the user wants to enter. The input works fine, but when I print out the saved values only the ones most recently entered are saved. Here is my code for input:
def gpa_input(classList):
print("please enter how many classes you have")
while True:
try:
numOfClasses = int(input())
except ValueError:
print("please enter a valid number")
continue
else:
break
for i in range (numOfClasses):
classList.append(subject)
print("enter name of " + str(i+1) + "th subject:")
classList[i].name = input()
print("enter num of credits for " + str(i+1) + "th subject:")
while True:
try:
classList[i].credits = int(input())
except ValueError:
print("please enter a valid number")
continue
else:
break
print("enter grade for " + str(i+1) + "th subject:")
while True:
try:
classList[i].gradePercentage = int(input())
except ValueError:
print("please enter a valid number")
continue
else:
break
A subject is a class containing a string value and 2 int values, defined as following:
class subject:
def __init__(name, credits, gradePercentage):
self.name = name
self.credits = credits
self.gradePercentage = gradePercentage
And here is the code that prints out all of this:
def main():
gpa_input(classList)
for i in range (len(classList)):
print(classList[i].name)
print(classList[i].credits)
print(classList[i].gradePercentage)
What is the problem with my code? Am I iterating through something the wrong way, or is there something not getting properly assigned/saved?
You've got into the very common "trap".
The problem is in how you initialize your subject class.
Here you just append a class to the list:
classList.append(subject)
The situation here is the following:
Once you called subject without braces you will have a new object.
But when you call it on the second time - python will not initialize the new object for you and just return the object created on the first step.
So all you need is to properly initialize all subject objects.
Two ways:
1) Remove args from subject definition and make default values are none + add braces to the classList.append(subject)
2) Collect all values in your for loop into variables and at the end of the function initialize you subject class with proper args.

Unbound Local Error which i dont know how to fix

def perd():
Personaldetails_file = open("Personaldetails_file.txt", "w")
Personaldetails_file = open("Personaldetails_file.txt", "a")
pd = input("Are you a new user?")
if pd == "yes":
print ("Add your details")
####################################
age = int(input("how old are you?"))
DOB = input("Date of birth:")
gender = input("Gender:")
weight = int(input("weight in kg:"))
height = int(input("height in cm:"))
Personaldetails = (age, DOB, gender, weight, height)
Personaldetails_file.write(str(Personaldetails))
Personaldetails_file.close()
#######################################
def td():
choice = input("which trainning event would you like to access?\n1.swimming\n2.cycling\n3.running\nplease type in the number before the event of which you want to choose\n")
if choice == "1":
Swimming_file= open("Swimming_file.txt", "w")
totaldistance = input("what was the total distance you swam in meters?")
totaltime = input("how long did you swim for in minutes?")
speed = totaldistance/totaltime
print ("on average you where running at a speed of", speed, "mps\nyou can look at the tables to see how many calouries you have burnt")
total = (totaldistance, totaltime, speed)
Swimming_file.write(str(total))
Swimming_file.close()
elif choice == "3":
Running_file= open("Running_file.txt", "w")
totaldistanceR = int(input("what was the total distance you ran in KM?"))
totaltimeR = int(input("how long did you run for in minutes?"))
totaltimeR1 = 60/totaltimeR
speedR1 = totaldistanceR/totaltimeR1
calburn = (speedR1 * 95)/(60/totaltimeR1)
print ("\nThe records have been saved")
print ("\non average you where running at a speed of", speedR1, "KMph\nyou burnt",calburn," calouries\n")
totalR = (totaldistanceR, totaltimeR, speedR1, calburn)
Running_file.write(str(totalR))
Running_file.close()
##############################################################
elif choice == "2":
Cycling_file= open("Cycling_file.txt", "w")
with open("Personaldetails_file.txt", "r") as f:
content = [x.strip('\n') for x in f.readlines()]
lines = f.readlines()
for line in lines:
words = line.split(",")
age = (line.split)(0)
weight = (line.split)(3)
height = (line.split)(4)
################################################################
totaldistancec = int(input("what was the total distance you cycled in KM?"))
totaltimec = int(input("how long did you cycle for in minutes?"))
calburn1 = (13.75 * weight) + (5 * height) - (6.67 * age)
speedc = totaldistancec/totaltimec
print ("on average you where running at a speed of", speedc, "KMph\nyou burnt", calburn1, " calouries")
totalc = (totaldistancec, totaltimec, speedc)
Cycling_file.write(str(totalc))
Cycling_file.close()
Personaldetails_file.close()
when I un the program an error appears.
line 84, in td
calburn1 = (13.75 * weight) + (5 * height) - (6.67 * age)
UnboundLocalError: local variable 'weight' referenced before assignment
does anyone know how I can fix this error?
the code which is relevant to the question surrounded by '#'
You declare weight here
def perd():
...
gender = input("Gender:")
weight = int(input("weight in kg:"))
height = int(input("height in cm:"))
...
but you try to use it here in this other function:
def tr():
....
calburn1 = (13.75 * weight) + (5 * height) - (6.67 * age)
....
this is a separate function that does not know about the variables within the perd() function, and why should it? It does not need any of them to operate as functions should isolate pieces of code and be able to be used by themselves. In other words once perd() runs its local variables go out of scope. Take a look at this question, Short Description of the Scoping Rules?. To solve this you either need to make the input taken in perd() global, not advisable because it is not very pythonic. Or you can pass the value in as a function parameter like this:
td(weight, height, age):
#code here
Now you have access to the value passed in as weight within the td function. But you need to realize that these are not the same variables, they may share the same name but they are NOT the same. You will need to pass in all values that you want to use from the perd function. This is preferable because you are designing your functions in a way that they can be used modularity, so one can handle getting input from the user while the other can perform calculations on data that it already knows are valid, this allows for easier to read code, which is what python is all about

python: global name 'user_input' is not defined

I keep getting the error message "global name 'user_input' not defined. new to python and to SO, hope you can help. Here's my code. Sorry if it's a mess. just starting out and teaching myself...
def menu():
'''list of options of unit types to have converted for the user
ex:
>>> _1)Length
_2)Tempurature
_3)Volume
'''
print('_1)Length\n' '_2)Temperature\n' '_3)Volume\n' '_4)Mass\n' '_5)Area\n'
'_6)Time\n' '_7)Speed\n' '_8)Digital Storage\n')
ask_user()
sub_menu(user_input)
def ask_user():
''' asks the user what units they would like converted
ex:
>>> what units do you need to convert? meter, feet
>>> 3.281
'''
user_input = input("Make a selection: ")
print ("you entered", user_input)
#conversion(user_input)
return user_input
def convert_meters_to_feet(num):
'''converts a user determined ammount of meters into feet
ex:
>>> convert_meters_to_feet(50)
>>> 164.042
'''
num_feet = num * 3.28084
print(num_feet)
def convert_fahrenheit_to_celsius(num):
'''converts a user determined temperature in fahrenheit to celsius
ex:
>>> convert_fahrenheit_to_celsius(60)
>>> 15.6
>>> convert_fahrenheit_to_celsius(32)
>>> 0
'''
degree_celsius = (num - 32) * (5/9)
print(round(degree_celsius, 2))
def sub_menu(num):
'''routes the user from the main menu to a sub menu based on
their first selection'''
if user_input == '1':
print('_1)Kilometers\n' '_2)Meters\n' '_3)Centimeters\n' '_4)Millimeters\n'
'_5)Mile\n' '_6)Yard\n' '_7)Foot\n' '_8)Inch\n' '_9)Nautical Mile\n')
ask = input('Make a selection (starting unit)')
return
if user_input == '2':
print('_1)Fahrenheit\n' '_2)Celsius\n' '_3)Kelvin\n')
ask = input('Make a selection (starting unit)')
return
When you do:
user_input = input("Make a selection: ")
Inside the ask_user() function, you can only access user_input inside that function. It is a local variable, contained only in that scope.
If you want to access it elsewhere, you can globalise it:
global user_input
user_input = input("Make a selection: ")
I think what you were trying was to return the output and then use it. You kind of got it, but instead of ask_user(), you have to put the returned data into a variable. So:
user_input = ask_user()
THere's no need to globalise the variable (as I showed above) if you use this method.
In your menu function, change the line that says ask_user() to user_input = ask_user().

Text will not print in the Python interpreter from these two methods I made

I want to call either method (getPerimeter | getArea) and return the answer depending on the input provided.
#!usr/bin/python
def getPerimeter(x, y):
answer = (2 * x) + (2 * y)
return string(answer) **This will not return anything in my terminal**
def getArea(x, y):
answer = x * y
return string(answer) **This also will not return anything in my terminal**
reply = raw_input("Do you want to find the area or the perimeter? ")
if reply == "area":
response1 = raw_input("What is the length ?: ")
response2 = raw_input("What is the width ?: ")
response1Int = int(response1)
response2Int = int(response2)
getArea(response1Int, response2Int)
else:
response3 = raw_input("What is the length ?: ")
response4 = raw_input("What is the width ?: ")
response3Int = int(response3)
response4Int = int(response4)
getPerimeter(response3Int, response4Int)
return returns, it doesn't print.
Returning something from a function doesn't print it to the screen. Try print(getArea(response1Int, response2Int)) and print(getPerimeter(response1Int, response2Int))
Also, string is not a function.

Categories