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
Related
I would like to be able to take the test scores the user inputs and write to an external text file. Then have the application read off the values from the and calculate the average. However, I am unsure as to how to implement the python syntax within the loop and the functions. I've attempted to utilize my resources to get a better idea of how to do this, but I've been having some trouble understanding how python handles external files. In addition, would using append be better than write in this scenario?
Current Syntax:
def testAvgCalculation():
#Variables
total = 0
total_quiz = 0
while True:
#User Input and Variable to stop loop
inpt = input("Enter score: ")
if inpt.lower()== 'stop':
break
#Data Validation
try:
if int(inpt) in range(1,101):
total += int(inpt)
total_quiz += 1
else:
print("Score too small or Big")
except ValueError:
print("Not a Number")
return total, total_quiz
def displayAverage(total, total_quiz):
average = total / total_quiz
print('The Average score is: ', format(average, '.2f'))
print('You have entered', total_quiz, 'scores')
#Main Function
def main():
total, total_quiz = testAvgCalculation()
displayAverage(total, total_quiz)
#Run Main Function
main()
This is hacky as heck, but I tried to work with what was already there. I split the data validation section of the original function off into a separate function. In main() it returns its value counter, which keeps track of how many values were entered, to calculate_average(), which then reads the file line by line until counter becomes 0, which means it's about to read the word "stop" (which allows EOF recognition via the 'and' in the if statement), performs the calculation and returns its values.
def write_file():
#Variables
counter = 0
file = open("Scores.txt", "w")
while True:
#User Input and Variable to stop loop
inpt = input("Enter score: ")
file.write(inpt + "\n")
if inpt.lower()== 'stop':
file.close()
break
counter += 1
return counter
def calculate_average(counter):
total = 0
total_quiz = counter
scores = open("Scores.txt", "r")
s = ""
try:
while counter > 0 and s != 'stop':
s = int(scores.readline())
if int(s) in range(1,101):
total += int(s)
counter -= 1
else:
print("Invalid data in file.")
except ValueError:
print("Invalid data found")
return total, total_quiz
def displayAverage(total, total_quiz):
average = total / total_quiz
print('The Average score is: ', format(average, '.2f'))
print('You have entered', total_quiz, 'scores')
#Main Function
def main():
total, total_quiz = calculate_average(write_file())
displayAverage(total, total_quiz)
#Run Main Function
main()
NOTE: the file is created initially in write mode which overwrites the file each time so you never need a new one. if you want to keep a record you might like to change it to append, though you'll need to manage extracting the proper lines from among old input.
Not pretty at all, but should give you an idea of how to accomplish what you were going for.
In Python, This can not loop many times and cannot find ID number in def.
Every time I try to run the program I get the error
"NameError: name 'askname' is not defined"
and in textfile Keep only the latest data
I expect the output of #def new_booking to be Keep data in files continuously but the actual output is kept data in files just one sentence
I expect the output of #def pre_booked to be Extract data from a file but the actual output is
"NameError: name 'askname' is not defined"
import random
# total=0
# people=0
total1 = 0
total2 = 0
# mini bar
def mini_bar():
mini_bar_total = 0
print("£50 for the Bar")
askbar = input("Would you like a mini bar? Y/N")
if askbar.upper() == "Y":
mini_bar_total = mini_bar_total + 50
return mini_bar_total
# breakfast
def breakfast(people, asknights):
breakfast_total = 0
print("£25 for breakfast")
askdinner = input("Would you like dinner? Y/N")
if askdinner.upper() == "Y":
breakfast_total = (people * 25) * asknights
print("total: £", breakfast_total)
return breakfast_total
# dinner
def dinner(people, asknights):
dinner_total = 0
print("£25 for Dinner")
askdinner = input("Would you like dinner? Y/N")
if askdinner.upper() == "Y":
dinner_total = (people * 25) * asknights
return dinner_total
# number customers
def num_customers():
customer_total = 0
print("£50 an Adult")
askadult = int(input("How many adults? "))
customer_total = askadult * 50
print("total: £", customer_total)
print("£25 a Child")
askchild = int(input("How many children? "))
customer_total = (askchild * 25) + customer_total
print("total: £", customer_total)
return customer_total, askadult, askchild
# number of nights (multiplier)
def num_nights(customer_total):
nights_total = 0
waiting = True
while waiting == True:
try:
asknights = int(input("How many nights are you staying for? "))
nights_total = customer_total * asknights
print("total: £", nights_total)
break
except ValueError:
print("invalid input!")
return nights_total, asknights
# New Booking *********
def new_booking():
askname = str(input("Please enter your name? "))
idnumber = random.randint(100, 999)
customer_total, numAdults, numChild = num_customers()
Num_people = numAdults + numChild
nights_total, asknights = num_nights(customer_total)
askbar = mini_bar()
askbreakfast = breakfast(Num_people, asknights)
askdinner = dinner(Num_people, asknights)
total = askdinner + askbreakfast + askbar + asknights
detailslist = (idnumber, askname, numAdults, numChild, asknights, askbar, askbreakfast, askdinner)
for i in detailslist:
f = open('newbooking.txt', 'w')
f.write(str(detailslist) + '\n')
print(i)
print("your total amount is: £", total)
print("your Name & ID number is: ", askname, idnumber)
# Pre booking ***** is not defind
def pre_booked():
name = input("enter your name or ID number: ")
if name == (askname) or (idnumber):
detailslist = [idnumber, askname, askadult, askchild, asknights, askbar, askbreakfast, askdinner]
for i in detailslist:
print(i)
print("total: £", total)
# main menu, start of program.
def main_menu():
print("##################### WELCOME TO BAY HOTEL ###########################")
print('''Please see what is available at the Hotel,\nAdult Prices per night: £50pp,\nChild price: £25pp,\nMiniBar price: £50 per room,\nBreakfast: £20pp,\nDinner: £25pp''')
while True:
prebook = input("Have you booked? Y/N")
if prebook.upper() == "N":
new_booking()
elif prebook.upper() == "Y":
pre_booked()
main_menu()
- I expect the output of #def new_booking to be Keep data in files continuously but the actual output is keep data in files just one sentence
- I expect the output of #def pre_booked to be Extract data from file but the actual output is "NameError: name 'askname' is not defined"
I think it's because your way to writing data in files.
Working with files has 3 step:
1) Opening file
2) Read [from] / Write [to] file
3) Closing file
third step is what you don't handled it.
You want to write a list in file and you are opening that file in each iteration. It's not a good idea (opening and closing files have their overhead) when you can do it once.
I changed some of your new_booking function and wrote it here:
# New Booking *********
def new_booking():
askname = str(input("Please enter your name? "))
idnumber = random.randint(100, 999)
customer_total, numAdults, numChild = num_customers()
Num_people = numAdults + numChild
nights_total, asknights = num_nights(customer_total)
askbar = mini_bar()
askbreakfast = breakfast(Num_people, asknights)
askdinner = dinner(Num_people, asknights)
total = askdinner + askbreakfast + askbar + asknights
detailslist = (idnumber, askname, numAdults, numChild, asknights, askbar, askbreakfast, askdinner)
# I handled opening and closing file with [python with statement]
# It close files automatically at the end
with open('newbooking.txt', 'w') as f:
for i in detailslist:
f.write(str(detailslist) + '\n')
print(i)
print("your total amount is: £", total)
print("your Name & ID number is: ", askname, idnumber)
The problem here is that you havent actually defined askname in your pre_booked() function so you cant compare against it. In new_booking() you are asking for the username with askname = str(input("Please enter your name? ")) however in the pre_booked() case you dont so you cant use it there without first getting the values from somewhere.
Seeing that you save the new_booking() to a file you probably want to load the data from your file like this:
accounts = []
with open(r"<FILEPATH", "r") as booking_file:
for line in booking_file:
accounts.append(line)
In your new_booking function it might be better to put all the related data in line by line or maybe even use dicts so you can later be sure which values belong together instead of writing all the values into their own line. So you might want to do this instead:
with open('newbooking.txt', 'w') as booking_file:
f.write(detailslist)
Then you can read line by line and possibly use ´eval()´ to get a list or dictionary right from your string or atleast you know the values in one line belong together later on.
You might also want to consider using "a" for append instead of w for write in your bookings file depending if you want to have multiple booking values in your file or just the one.
I have been working on this code for a couple of hours now, and I am rather unsure what the problem is.
import random#imports random
import os#Imports os
print("Welcome to the maths quiz") # Welcomes user to quiz
score = (0)
def details():
plr_name = input ("Please Input Name:") # Asks user for name
plr_class = input("Input class number: ") # Asks the user for class numer
return (plr_name, plr_class)
def Q():
while qno < 10: # loops while qno is under 10
ran_num1 = random.randint(1,99) # Generates the first random number
ran_num2 = random.randint(1,99) # Generates the second random number
ran_fun = random.choice("X-+") # Picks a random function
print(ran_num1,ran_fun,ran_num2,"=") # Prints the Sum for the user
if ran_fun == "X":
sum_ans = ran_num1 * ran_num2 # Does the sum if it is a multiplication
if ran_fun == "+":
sum_ans = ran_num1 + ran_num2 # Does the sum if it is a addition
if ran_fun == "-":
sum_ans = ran_num1 - ran_num2 # Does the sum if it is a subtraction
plr_ans = int(input()) # Gets the user's answer
if plr_ans == sum_ans:
print("Correct!") # Prints correct
score = score + 1 # Adds 1 to score
else:
print("Incorrect!")
qno = qno + 1 # Adds 1 to qno
def plr_list_make(lines, listoreder):
index = 0
plr_names =[]
plr_scores =[]
for line in lines:
if listorder == 1:
column =0
rev = False
else:
column = 1
rev = True
return sorted(zip(plr_names, plr_scores),key = lambda x:(x[column]),reverse = rev)
def fileUP(plr_name, score, line ):
found = False
index = 0
for line in lines:
if line.startswith(plr_name):
line = line.strip("\n") + ","+str(score+"\n")
lines[index] = line
found = True
index = index + 1
if not found:
lines.append(plr_name+"|" +str(score)+"\n")
return lines
def save (plr_name, plr_class, score):
filename = "QuizScore_"+plr_class+".txt"
try:
fileI = open(filename)
except IOError:
fileI = open(filename, "w+")
fileI = open(filename)
lines = fileI.readlines()
fileI.close
lines = FileUP(plr_name, score, lines)
fileO = open(filename, "w")
fileO.writelines(lines)
fileO.close
def disp_list(): ## intialise_list
student_list=[]
filename = "QuizScore_"+plr_class+".txt"
try:
## open file read into list "lines"
input_file = open(filename)
lines = input_file.readlines() ## read file into list "lines"
input_file.close
student_list = create_student_list(lines, listorder) ### update "lines" with student list as requested by user
## output sorted list
for counter in range(len(student_list)):
print ("Name and Score: ", student_list[counter][0], student_list[counter][1])
except IOError:
print ("no class file!!!")
def menu():
print ("1 Test")
print ("2 Alphabetical")
print ("3 Highscore")
print ("4 Avg Score")
def Run():
selection = 0
while selection != 5:
menu()
option = int(input("Please select option: "))
if option == 1:
name, plr_class = details()
save(name, plr_class, Q())
else:
plr_class = input("input class ")
disp_list(plr_class, option-1)
Run()
Errors:
Traceback (most recent call last):
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 117, in
Run()
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 113, in Run
save(name, plr_class, Q())
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 74, in save
lines = FileUP(plr_name, score, lines)
NameError: global name 'FileUP' is not defined
Line 110:
name, plr_class = details()
But the details function does not return anything - so Python tries to assign the default return value None to the tuple name, plr_class. It can't do this, because None is not an iterable (you can't assign two things to it). To fix it, add the following line to your details function:
return (plr_name, plr_class)
(I haven't tested this.)
I like your game but it's buggy as a mofo :P
score and qno aren't properly defined. Define them in the functions that need them, define them globally or pass them to the relevant functions as arguments.
details() doesn't return anything but you still attempt to use its output to define two other variables. Add return (plr_name, plr_class) to details()
Every time you cast user input to int without checking its value, your program will crash if an int can't be cast. This applies here:
option = int(input("Please select option: "))
here
plr_ans = int(input())#Gets the user's answer
and elsewhere.
Since your program is input-heavy you could make a a function to which you pass the expected datatype and an optional string to display to the user. This way you wouldn't have to write try/except 10 times and your program wouldn't crash on unexpected input.
In def fileUP(plr_name, score, line ): you have for line in lines: but lines isn't defined. Thus, the save() function that calls FileUP() also fails. Also, FileUP and fileUP are not the same thing. You call the function with a capital "f" but the defintion of the function calls it fileUP with a lower case "f".
While we're at it, the file handling in def save (plr_name, plr_class, score):looks weird. The standard way of opening files for simple reading and writing in Python is via with open().
disp_list() should take one or two arguments but it doesn't at the moment so this error is raised:
TypeError: disp_list() takes 0 positional arguments but 2 were given
These 2 positional arguments were given here:
disp_list(plr_class, option-1)
def file_contents():
global file_encrypt
encryption_file = input("What is the name of the file?")
file_encrypt = open(encryption_file, 'r')
contents = file_encrypt.read()
print (contents)
ask_sure = input("Is this the file you would like to encrypt?")
if ask_sure == "no":
the_menu()
This part of the code opens the file the user enters, right? There are no real problems here.
def key_offset():
key_word = ''
count = 0
total = 0
while count < 8:
num = random.randint (33, 126)
letter = chr(num)
key_word = key_word + letter
count = count + 1
offset = ord(letter)
total = total + offset
print("Make sure you copy the key for decryption.")
if count == 8:
total = total/8
total = math.floor(total)
total = total - 32
print(key_word)
return total
This is the part where it calculates the offset and etc etc. Once again no problems here.
def encrypting():
file = file_contents()
total = key_offset()
encrypted = ''
character_number = 0
length = len(file_encrypt)
And then this is where the problem appears, I have made the variable file_encrypt global in the first block of code, so therefore it should work. I have tried calling it under another variable like file_en = file_encrypt and used file_en in the length calculating, but it keeps saying it has no length... I have tried asking friends and my teacher, but they seem clueless. The problem is that every time i get to this part it says that file_encrypt has no length or the other way I tried it, file_en has no length, something to do with TextWrapper.io.
file_encrypt is a file pointer, which does indeed not have a length. The contents of your file are in contents, but that is a variable local to the file_contents function.
Really you should not be using global variables; there isn't any reason to here. Instead, return the actual data - contents - from file_contents, then you can use it in the calling function.
There are a few issues with your code, but ignoring those for now, I think your main problems are:
1) The function "file_contents" doesn't return anything, I suspect you want to return "contents". Hard to say without knowing what you want to do with the "file" variable.
def encrypting():
file = file_contents() # <--
2) As others have said, "file_encrypt" is a pointer to a file, although in this function you didn't declare it as global, so it's probably None.
def encrypting():
file = file_contents()
total = key_offset()
encrypted = ''
character_number = 0
length = len(file_encrypt) # <--
So, these modifications should give you what you need:
def file_contents():
global file_encrypt
encryption_file = input("What is the name of the file?")
file_encrypt = open(encryption_file, 'r')
contents = file_encrypt.read()
print (contents)
ask_sure = input("Is this the file you would like to encrypt?")
if ask_sure == "no":
the_menu()
return contents # <-- ADDED
def encrypting():
contents = file_contents() # <-- MODIFIED
total = key_offset()
encrypted = ''
character_number = 0
length = len(contents) # <-- MODIFIED
def main():
name = input("What is your first name?: ")
name2 = input("What is your last name?: ")
kg = float(input("What is your weight in kilograms?: "))
meters = float(input("What is your height in meters?: "))
mass = float(kg)
height = float(meters)
Health(BMI, Ponderal, Rohrer)
print(name2+",",name,"(BMI:",BMI,",",\
"Ponderal Index:",Ponderal,",","Rohrer's Index:",Rohrer,",",")")
***It should return something along the lines of
Last, First(BMI: 35.234, Ponderal Index: 16.5, Rohrer's Index: 114)
Im in a intro to python class and its really late to contact anyone else for help. The whole purpose of this exercise is to create functions and call back to them.
Edit: Thanks a lot for the help guys, I know a lot of the questions on here are normally far more advanced, but the quick replies and the amount of helpful tips is greatly appreciated.
If a function returns something, then you should put it somewhere. For example, in a variable!
Here, change your functions:
def main():
name = input("What is your first name?: ")
name2 = input("What is your last name?: ")
mass = float(input("What is your weight in kilograms?: "))
height = float(input("What is your height in meters?: "))
#mass = float(kg) #not needed
#height = float(meters) #not needed
result = health(mass, height)
#printing based on the return value. result[0] is bmi, and so on.
print("%s, %s (BMI: %d, Ponderal Index: %d, Rohrer's Index: %d"%(name2,name,health[0],health[1],health[2]))
def bmi (mass, height):
result = mass / (height ** 2)
return result
def ponderal (mass, height):
result = mass / height ** 3
return result
def rohrer(mass, height):
result = (mass * 10000) / ((height * 100) ** 3)
return result
def health (mass, height):
#calling the functions
bmi = bmi(mass, height) #store the returned value to a variable
ponderal = ponderal(mass, height)
rohrer = rohrer(mass, height)
return [bmi,ponderal,rohrer] #return it as a list.
Result:
>>> ================================ RESTART ================================
>>>
What is your first name?: Akhyar
What is your last name?: Kamili
What is your weight in kilograms?: 50
What is your height in meters?: 1.7
Kamili, Akhyar (BMI: 17.301038062283737 , Ponderal Index: 10.177081213108082 , Rohrer's Index: 0.1017708121310808 , )
>>>
Some advice:
Do NOT capitalize function names!
Don't name variables like the functions!
Your code will do better.
There are a lot of problems with your code; first off format it better make sure you have comments on your code (lines that start with #)
Also don't directly convert units from string to float. What if they enter something invalid handle exceptions.
Thirdly the way you format you output text is god awful it is extremely hard to read all the commas and paratheses.
Also the way you get the values you never set them to a variable you also use this health function which you do not need just call the values directly!
Also use sensical names for variables instead of name2 use first name etc
Your code should better look like this (note if this is for homework and you turn this in your professor will easily find it on stackoverflow; so don't)
# calculates the BMI of a person
def BMI (mass, height):
BMI = mass / (height ** 2)
return BMI
# calculates the Ponderal index of a person
def Ponderal (mass, height):
Ponderal = mass / height ** 3
return Ponderal
# calculates the Rohrer index of a person
def Rohrer (mass, height):
Rohrer = (mass * 10000) / ((height * 100) ** 3)
return Rohrer
# this isn't needed
def Health (BMI, Ponderal, Rohrer):
BMI (mass, height)
Ponderal (mass, height)
Rohrer (mass, height)
return Health
def main():
# get the names of people
first_name = input("What is your first name?: ")
last_name = input("What is your last name?: ")
# get their height and weight
kg = input("What is your weight in kilograms?: ")
meters = input("What is your height in meters?: ")
# convert mass and height to numbers
try:
mass = float(kg)
except ValueError:
print "Please enter a valid mass."
return
try:
height = float(meters)
except ValueError:
print "Please enter a valid height."
return
# call the BMI, Ponderal and Rohrer functions
# don't make the variable BMI as your function is also that name!
bmi_value = BMI(mass, height)
ponderal_value = Ponderal(mass, height)
rohrer_value = Rohrer(mass, height)
print( "%s, %s (BMI: %s, Ponderal Index: %s, Rohrer Index: %s)" % (last_name, first_name, bmi_value, ponderal_value, rohrer_value) )
# this print string is EXTREEMLY hard to read
# print(name2+",",name,"(BMI:",BMI,",", "Ponderal Index:",Ponderal,",","Rohrer's Index:",Rohrer,",",")")
# if we are running this script directly call main
if __name__ == "__main__":
main()
You're not calling the functions, you're only referencing them. For example:
Ponderal
# <function Ponderal at blah>
Compared to:
Ponderal()
# A number