Why is my user input not called when I run this function? - python

I'm super new to python and am working on a project for school. I am trying to open up a csv file to use in later functions. When I run my code, my terminal does not prompt me for an input at all. What am I missing? This works if I just remove the "def get_input_descriptor" but my project requires that I define this as a function.
def main():
def get_input_descriptor():
while True:
filename= input("Enter a file name: ")
try:
file = open(filename,newline = '')
break
except IOError:
print("Bad file name, try again")
continue
def get_data_list(filename):
filedata = csv.DictReader(file)
column = input("Which Column: ")
if column == 1:
columnread = "Open"
elif column == 2:
columnread = "High"
elif column == 3:
columnread = "Low"
elif column == 4:
columnread = "Close"
elif column == 5:
columnread = "Volume"
elif columnread == 6:
columnread = "Adj Close"
datalist = []
for row in filedata:
print(row["Date"],row[columnread])
main()

You should probably read this page first before asking homework related questions How do I ask and answer homework questions?
However... In Python defining a function with def will only run that code if the function gets called e.g. get_input_descriptor() When you remove the def get_input_descriptor(): bit the code is no longer "locked" in a function and is now part of the main method an so can run.
If you NEED to make this a separate function then you would move it above the main method code and then call the function get_input_descriptor() from within the main method

You are not actually making a call to the get_data_list function.
When you use the def keyword in python, that means you are defining a function that you later wish to call. So you're just setting it up so you can use it later.
You've already done this with the main function, you use def main(): at the start, which sets it up, then later you call main() to actually run the function.
So what you're doing here is setting up a function called main, then you call that function later. When you call it, it sets up two more functions get_input_descriptor and get_data_list, but neither of them actually get called. I'm guessing, but you probably want something that looks more like this
def get_input_descriptor():
while True:
filename= input("Enter a file name: ")
try:
file = open(filename,newline = '')
break
except IOError:
print("Bad file name, try again")
continue
def get_data_list(filename):
filedata = csv.DictReader(file)
column = input("Which Column: ")
if column == 1:
columnread = "Open"
elif column == 2:
columnread = "High"
elif column == 3:
columnread = "Low"
elif column == 4:
columnread = "Close"
elif column == 5:
columnread = "Volume"
elif columnread == 6:
columnread = "Adj Close"
datalist = []
for row in filedata:
print(row["Date"],row[columnread])
def main():
get_input_descriptor()
get_data_list(filename)
main()
There are a few other problems in your code, but I think you can work them out if you get passed this problem.

Related

How to open and read a file in python while it's an subfolder?

I have created a program where I have two text files: "places.txt" and "verbs.txt" and It asks the user to choose between these two files. After they've chosen it quizzes the user on the English translation from the Spanish word and returns the correct answer once the user has completed their "test". However the program runs smoothly if the text files are free in the folder for python I have created on my Mac but once I put these files and the .py file in a subfolder it says files can't be found. I want to share this .py file along with the text files but would there be a way I can fix this error?
def CreateQuiz(i):
# here i'm creating the keys and values of the "flashcards"
f = open(fileList[i],'r') # using the read function for both files
EngSpanVocab= {} # this converts the lists in the text files to dictionaries
for line in f:
#here this trims the empty lines in the text files
line = line.strip().split(':')
engWord = line[0]
spanWord = line[1].split(',')
EngSpanVocab[engWord] = spanWord
placeList = list(EngSpanVocab.keys())
while True:
num = input('How many words in your quiz? ==>')
try:
num = int(num)
if num <= 0 or num >= 10:
print('Number must be greater than zero and less than or equal to 10')
else:
correct = 0
#this takes the user input
for j in range(num):
val = random.choice(placeList)
spa = input('Enter a valid spanish phrase for '+val+'\n'+'==> ')
if spa in EngSpanVocab[val]:
correct = correct+1
if len(EngSpanVocab[val]) == 1:
#if answers are correct the program returns value
print('Correct. Good work\n')
else:
data = EngSpanVocab[val].copy()
data.remove(spa)
print('Correct. You could also have chosen',*data,'\n')
else:
print('Incorrect, right answer was',*EngSpanVocab[val])
#gives back the user answer as a percentage right out of a 100%
prob = round((correct/num)*100,2)
print('\nYou got '+str(correct)+' out of '+str(num)+', which is '+str(prob)+'%'+'\n')
break
except:
print('You must enter an integer')
def write(wrongDict, targetFile):
# Open
writeFile = open(targetFile, 'w')
# Write entry
for key in wrongDict.keys():
## Key
writeFile.write(key)
writeFile.write(':')
## Value(s)
for value in wrongDict[key]:
# If key has multiple values or user chooses more than 1 word to be quizzed on
if value == wrongDict[key][(len(wrongDict[key])) - 1]:
writeFile.write(value)
else:
writeFile.write('%s,'%value)
writeFile.write('\n')
# Close
writeFile.close()
print ('Incorrect answers written to',targetFile,'.')
def writewrong(wringDict):
#this is for the file that will be written in
string_1= input("Filename (defaults to \'wrong.txt\'):")
if string_1== ' ':
target_file='wrong.txt'
else:
target_file= string_1
# this checs if it already exists and if it does then it overwrites what was on it previously
if os.path.isfile(target)==True:
while True:
string_2=input("File already exists. Overwrite? (Yes or No):")
if string_2== ' ':
write(wrongDict, target_file)
break
else:
over_list=[]
for i in string_1:
if i.isalpha(): ovrList.append(i)
ovr = ''.join(ovrList)
ovr = ovr.lower()
if ovr.isalpha() == True:
#### Evaluate answer
if ovr[0] == 'y':
write(wrongDict, target)
break
elif ovr[0] == 'n':
break
else:
print ('Invalid input.\n')
### If not, create
else:
write(wrongDict, target)
def MainMenu():
## # this is just the standad menu when you first run the program
if len(fileList) == 0:
print('Error! No file found')
else:
print( "Vocabulary Program:\nChoose a file with the proper number or press Q to quit" )
print(str(1) ,"Places.txt")
print(str(2) ,"Verbs.txt")
while True:
#this takes the user input given and opens up the right text file depending on what the user wants
MainMenu()
userChoice = input('==> ')
if userChoice == '1':
data = open("places.txt",'r')
CreateQuiz(0)
elif userChoice == '2':
data = open("verbs.txt",'r')
CreateQuiz(1)
elif userChoice == 'Q':
break
else:
print('Choose a Valid Option!!\n')
break
You are probably not running the script from within the new folder, so it tries to load the files from the directory from where you run the script.
Try setting the directory:
import os
directory = os.path.dirname(os.path.abspath(__file__))
data = open(directory + "/places.txt",'r')

New function doesn't accept returned values from other function

I'm reading from a CSV file and created a function that separates the players from that file into 2 lists: experienced and fresh players.
Then, I tried to create another function that would print the length of each list. However, when I run my script and I call for the 2 functions, Python returns an error saying that the variables of the second function are not defined. Not sure what I'm doing wrong.
import csv
with open('soccer_players.csv', newline='') as csvfile:
players_reader = csv.DictReader(csvfile, delimiter=',')
players = list(players_reader)
def separate(players):
experienced = []
fresh = []
for player in players:
if player['Soccer Experience'] == 'YES':
experienced.append(player)
else:
fresh.append(player)
return experienced, fresh
def countexperience (experienced, fresh):
players_experience = len(experienced)
players_fresh = len(fresh)
print(players_experience)
print(players_fresh)
while True:
start = input("Want to start? (Y/n) ").lower()
if start == "y":
separate(players)
countexperience(experienced, fresh)
break
elif start == "n":
print("goodbye")
break
else:
print("letter not accepted! Please write 'Y' to start or 'N' to exit!\n")
Result:
countexperience(experienced, fresh)
NameError: name 'experienced' is not defined
The local variables in separate() are not added to the current scope, so you need to assign the return of separate() to variables in the current scope, e.g.:
experienced, fresh = separate(players)
Note: you can use any names you want, e.g.
e, f = separate(players)
countexperience(e, f)
You can also expand the tuple return from separate() directly in the function call to countexperience() using *, e.g.:
countexperience(*separate(players))

Difficulties with an unruly program

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)

completing a function fully

I AM NEW TO PYTHON AND CODING IN GENERAL.
So I have a program with a menu that has multiple functions in it. individually each function works fine on its own, however when i put them together they would usually not fully execute and instead stop half way or wont work at all.
EXAMPLE- the function remove wont remove what i tell it to.
def show_coffee will only show the first description and weight only and nothing else.
What can i do to make the functions fully execute?
import os
def main():
choice =''
fun=[]
while choice != 4:
menu()
choice=getUserChoice()
if choice !=4:
fun=process_choice(choice,fun)
print(fun)
print("Goodby!")
def process_choice(choice,fun):
#fun=fun1
if choice == 0:
fun=add_coffee(fun)
elif choice == 1:
fun=show_coffee(fun)
elif choice == 2:
fun=search_coffee(fun)
elif choice == 3:
fun=modify_coffee(fun)
else:
print(choice,"is not a valid choice.")
return fun
def add_coffee(fun):
another= 'y'
coffee_file=open('coffee.txt', 'a')
Description={}
while another == 'y' or another == 'Y':
print('Enter the following coffee data:')
descr=input('Description: ')
qty= int(input('Quantity (in pounds): '))
coffee_file.write(descr + '\n')
coffee_file.write(str(qty) + '\n')
print("Do you want to add another record?")
another = input("Y=yes, anything else =no: ")
return fun
coffee_file.close()
print('Data append to coffee.txt.')
def show_coffee(fun2):
coffee_file=open ('coffee.txt', 'r')
descr=coffee_file.readline()
while descr != "":
qty= str(coffee_file.readline())
descr=descr.rstrip('\n')
print('Description:', descr)
print('Quantity:', qty)
descr= coffee_file.readline()
fun=fun2
return fun
coffee_file.close()
def search_coffee(fun3):
found=False
search =input('Enter a description to search for: ')
coffee_file=open('coffee.txt', 'r')
descr=coffee_file.readline()
while descr != '':
qty= float(coffee_file.readline())
descr = descr.rstrip('\n')
if descr== search:
print('Description:', descr)
print('Quantity:', qty)
found=True
descr=coffee_file.readline()
fun=fun3
return fun
coffee_file.close()
if not found:
print('That item was not found in the file.')
def modify_coffee(fun4):
found=False
search=input('Which coffee do you want to delete? ')
coffee_file=open('coffee.txt', 'r')
temp_file=open('temp.txt', 'w')
descr=coffee_file.readline()
while descr != '':
qty=float(coffee_file.readline())
descr=descr.rstrip('\n')
if descr !=search:
temp_file.write(descr + '\n')
temp_file.write(str(qty) + '\n')
else:
found=True
descr=coffee_file.readline()
fun=fun4
return fun
coffee_file.close()
temp_file.close()
os.remove('coffee.txt')
os.rename('temp.txt', 'coffee.txt')
if found:
print('The file has been update.')
else:
print('The item was not found in the file.')
def menu():
print('''
0. Add or Update an entry
1. Show an entry
2. Search
3. remove
4. Remove number
''')
def getUserChoice():
choice=-1
while choice <0 or choice > 3:
print("Please select 0-3: ",end='')
choice=int(input())
return choice
You are defining functions but this does not call a function. The standard way to do this in Python is use the if __name__=="__main__": statement at the bottom of a file. When the file is executed (instead of functions/classes being imported by another script) the code block within the scope of if __name__=="__main__": is executed.
Get comfortable with this, it's useful and clean :) Good read - What does if __name__ == "__main__": do?
So, for example...
At the bottom of your file...
if __name__=="__main__":
main()

Python file scanning

I have a some code in a game I'm making where it stores user data on a text file called data.txt. The following code is when a person continues, then it will read the part where the level is stored and see where it will begin the game:
elif choice==("2"):
contusername = input("Enter the name you registered with")
with open("data.txt") as f:
f.readline()
for lines in f:
name, level = lines.split()
if name == contusername:
userdata = level
break
while True:
if level == 1:
level1()
elif level == 2:
level2()
#and so on
But it won't work. Python can't read the text file. How do I fix this?
You probably forgot to cast to int:
userdata = int(level)
Other way your userdata are strings of form '1\n'
Also, you want to use this userdata in comparison, not level
while True:
if userdata == 1:
level1()
p.s. I don't know whether this while True: statement is correct, as only a code excerpt is presented, but it also looks suspitious for me.
It appears you have a Type problem. Reading from a file will give you a string, but you are checking for integers.
Try forcing the level numbers to an int.
elif choice==("2"):
contusername = input("Enter the name you registered with")
with open("data.txt") as f:
f.readline()
for lines in f:
name, level = lines.split()
if name == contusername:
userdata = level
break
level = int(level) # <-- force the level to an integer
while True:
if level == 1:
level1()
elif level == 2:
level2()
This should work :
elif choice == "2":
contusername = raw_input("Enter the name you registered with")
with open("data.txt") as f:
for lines in f.readlines():
name, level = lines.split()
if name == contusername:
userdata = int(level)
break
while True:
if userdata == 1:
level1()
elif userdata == 2:
level2()

Categories