Using .readlines() and struggling to access the list - python

I am struggling to access the list created by using .readlines() when opening the text file. The file opens correctly, but I am not sure how I can access the list in the function 'display_clues()'.
def clues_open():
try:
cluesfile = open("clues.txt","r")
clue_list = cluesfile.readlines()
except:
print("Oops! Something went wrong (Error Code 3)")
exit()
def display_clues():
clues_yes_or_no = input("Would you like to see the clues? Enter Y/N: ")
clues_yes_or_no = clues_yes_or_no.lower()
if clues_yes_or_no == "y":
clues_open()
print(clue_list)
Error:
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
display_clues()
File "N:\Personal Projecs\game\game.py", line 35, in display_clues
print(clue_list)
NameError: name 'clue_list' is not defined
Thanks!

def clues_open():
try:
cluesfile = open("clues.txt","r")
clue_list = cluesfile.readlines()
#print clue_list #either print the list here
return clue_list # or return the list
except:
print("Oops! Something went wrong (Error Code 3)")
exit()
def display_clues():
clues_yes_or_no = raw_input("Would you like to see the clues? Enter Y/N: ")
clues_yes_or_no = clues_yes_or_no.lower()
if clues_yes_or_no == "y":
clue_list = clues_open() # catch list here
print clue_list
display_clues()

You have to return the list from clues_open() to display_clues():
def clues_open():
with open("clues.txt","r") as cluesfile:
return cluesfile.readlines()
def display_clues():
clues_yes_or_no = input("Would you like to see the clues? Enter Y/N: ")
if clues_yes_or_no.lower() == "y":
clues_list = clues_open()
print(clue_list)
As a side note: I removed your worse than useless except block. Never use a bare except clause, never assume what actually went wrong, and only catch exception you can really handle.

Related

Adding and saving to list in external json file

I'm very new to Python and I'm struggling when it comes to saving the data that the user has entered to a json file when quitting the application. Also every time I run my code all the data inside the json file is wiped. When I enter the input to save and exit I get this error code:
Traceback (most recent call last):
File "C:\Users\User\Downloads\sit_resources\sit_resources\sit_admin_application.py", line 86, in <module>
main_menu()
File "C:\Users\User\Downloads\sit_resources\sit_resources\sit_admin_application.py", line 23, in main_menu
save()
File "C:\Users\User\Downloads\sit_resources\sit_resources\sit_admin_application.py", line 82, in save
patients_file.write(finallist)
io.UnsupportedOperation: not writable
Here is my code below:
import json
patients_file = open("patients.json", "r")
loaded_patients = json.load(patients_file)
def main_menu():
'''Function docstring documentation here'''
print("\nSIT Data Entry Menu")
print("==========================")
print("1: Print Patients' List\n2: Add Patient\n3: Delete Patient\n4: Exit")
print("==========================")
input1 = input("Enter your menu selection:")
if input1 == "1":
patients_list()
elif input1 == "2":
add_patient()
elif input1 == "3":
remove_patient()
elif input1 == "4":
save()
else:
print ("Please enter a valid input")
main_menu()
def patients_list():
print("\nSIT current patients:\n")
loaded_patients.sort(key=str.casefold)
for number, item in enumerate(loaded_patients, start=1):
print(number, item)
print("\nTotal number of registered patients is", len(loaded_patients))
main_menu()
def add_patient():
newpatient = input("\nEnter new Patient -> Lastname Firstname:")
print ("Do the details you have entered look correct? y/n")
confirm = input()
if confirm == "y":
loaded_patients.append(newpatient)
print ("Patient successfully added to list")
main_menu()
elif confirm == "n":
print ("Patient import cancelled")
add_patient()
else:
print ("Please enter a valid input")
add_patient()
def remove_patient():
print ("Which of the following patients would you like to remove?")
loaded_patients.sort(key=str.casefold)
for number, item in enumerate(loaded_patients, start=1):
print(number, item)
try:
removepatient = int(input("\nEnter the number of the patient you would like to remove"))
print ("Does the patient number you have entered look correct? y/n")
delconfirm = input()
if delconfirm == "y":
try:
removepatient = (removepatient - 1)
loaded_patients.pop(removepatient)
print ("Patient was successfully removed from the list")
main_menu()
except IndexError:
print("Please enter a valid input")
remove_patient()
elif delconfirm == "n":
print ("Deletion cancelled")
remove_patient()
else:
print ("Please enter a valid input")
remove_patient()
except ValueError:
print ("Please enter a valid input")
remove_patient()
def save():
open("patients.json", "w")
finallist = json.dumps(loaded_patients)
patients_file.write(finallist)
print("Patient List successfully saved")
quit()
main_menu()
I store the json file in the same directory and all it contains is a list:
["Soreback Leigh", "Neckache Annette", "Sorefoot Jo", "Kaputknee Matt", "Brokentoe Susan", "Tornligament Alex"]
If anyone could help me out and let me know what I'm doing wrong or any simpler method I could use, it would be greatly appreciated.
Thanks
Your code has several issues, including the one you're asking about.
The main thing is the overall structure: your code keeps calling functions from functions, never really returning - that can work for a very long time, but in the end it will fail, and it's not the correct way to go about this.
Take for example your main_menu() - once an option is selected, you call the function matching it, and when the work there is done, you call main_menu() again. However, a better way to do the same:
def main_menu():
choice = ''
while choice != '4':
print('some options, 4 being "save and quit"')
if choice == 1:
patients_list()
...
# no if choice == 4: save() here, we'll save at the end
save()
This way, the menu will keep getting printed when you return to it, but every function that is executed, is allowed to return and then the loop restarts, unless option 4 was entered. And since you can allow the functions to return, no need to call main_menu() at the end of them.
Your save() function has some issues: it doesn't need quit() any more, but you also didn't do anything with the file you opened. A nice way to do this in Python is to use a 'context manager', which boils down to using with, like this:
def save():
with open("patients.json", "w") as patients_file:
finallist = json.dumps(loaded_patients)
patients_file.write(finallist)
That's assuming your loaded_patients always contains all the current patients of course. Given that's what it is for, you should consider just calling it patients.
Your file only contains a list, because a list is what you are creating in those functions and a list is a valid content for a json file. If you expected a dictionary, you should construct one in the rest of the code, but from your example it's unclear what exactly you would expect that dictionary to look like.
The conventional way to load and save json:
with open('patients.json', 'r') as f:
loaded_patients = json.load(f)
with open('patients.json', 'w') as f:
json.dump(loaded_patients, f)
You are trying to write to patients_file, which you opened in read-only mode.

How to solve python's NameError: name 'xx' is not defined?

I am learning python, according to the logic written in the code in the book, I want to see the running result, the code is as follows, but the output error NameError: name 'pr' is not defined
code show as below:
stack=[]
def pushit():
stack:append(input(' Enter New String: ').strip())
def popit():
if len(stack)==0:
print('Cannot pop from an empty stack!')
else:
print ('Removes [','stack.pop()',']')
def viewstack():
print(stack)
CMDs={'u':pushit,'o':popit,'v':viewstack}
def showmenu():
pr='''
p(U)sh
p(O)p
(V)iew
(Q)uit
Enter choice:'''
while True:
while True:
try:
choice=input(pr).strip()[0].lower()
except (EOFError,KeyboardInterrupt,IndexError):
choice='q'
print('\nYou picked:[%s]'%choice)
if choice not in 'uovq':
print('Invalid option,try again')
else:
break
if choice=='q':
break
CMDs[choice]()
if _name_=='_main_':
showmenu()
The error message is as follows:
Traceback (most recent call last):
File "/Users/zego/Desktop/test.py", line 22, in <module>
choice=input(pr).strip()[0].lower()
NameError: name 'pr' is not defined
You have not inserted the showmenu function code at right index. The while loop should be started from one tab space ahead.
Look at the below code.
stack=[]
def pushit():
stack:append(input(' Enter New String: ').strip())
def popit():
if len(stack)==0:
print('Cannot pop from an empty stack!')
else:
print ('Removes [','stack.pop()',']')
def viewstack():
print(stack)
CMDs={'u':pushit,'o':popit,'v':viewstack}
def showmenu():
pr='''
p(U)sh
p(O)p
(V)iew
(Q)uit
Enter choice:'''
while True:
while True:
try:
choice=input(pr).strip()[0].lower()
except (EOFError,KeyboardInterrupt,IndexError):
choice='q'
print('\nYou picked:[%s]'%choice)
if choice not in 'uovq':
print('Invalid option,try again')
else:
break
if choice=='q':
break
CMDs[choice]()

Python cause of "AttributeError: 'NoneType' object has no attribute 'readline'"

I'm trying to print integers from a file where each line has 1 integer, as well as print their sum. Everything seems to work fine, except when I enter the incorrect file name, loop back, and then enter the correct one. The program still outputs the correct information but then the error:
"AttributeError: 'NoneType' object has no attribute 'readline'". Why is this happening?
def main():
listnums = filetolist()
print(f'numbers in file: {listnums}')
print(f' sum of before mentioned numbers is: {sum(listnums)}')
# opens file
def openfile():
try:
file = open(input("what is the file named including the file extension?"), "r")
return file
except IOError:
tryagain = input("File could not be found \n" + "if you would like try again type 1 and press enter, to exit press enter")
if tryagain == "1":
main()
else:
exit()
# converts file to list
def filetolist():
file = openfile()
line = file.readline()
nums = []
linenumber = 1
while line != "":
nums += [verifyint(line, linenumber)]
line = file.readline()
linenumber += 1
file.close()
return nums
# verifies number is an int
def verifyint(num, linenumber):
try:
numint = int(num)
return numint
except ValueError:
print(f'Invalid value on line #{linenumber}')
exit()
main()
When you hit the except block, there is no return statement, so this function returns None after running main() again
Rather than effectively recurse, you should properly raise the errors and use a proper loop
def filetolist(filename):
with open(filename) as f:
return [int(line.rstrip()) for line in f]
def main():
while True:
filename = input("what is the file named including the file extension?")
try:
listnums = filetolist(filename)
print(f'numbers in file: {listnums}')
print(f' sum of before mentioned numbers is: {sum(listnums)}')
except ValueError, IOError:
again = input('Error! Try again? (y/n)')
if again.lower() != 'y':
break
main()
I think (i might be wrong) that the problem is that when you fail to read a file and try again you need to recall openfile and not the whole main.
If you call the whole main you are opening a new file doing all the routine and then returning nothing.
Try that And tell me if it works
def openfile():
try:
file = open(input("what is the file named including the file extension?"), "r")
return file
except IOError:
tryagain = input("File could not be found \n" + "if you would like try again type 1 and press enter, to exit press enter")
if tryagain == "1":
return openfile()
else:
exit()
here a screenshot

Having a compiling error with Python using PyCharm 4.0.5

The reason for me asking the question here is that I did not find a solution elsewhere. I'm having the following error with my PyCharm 4.0.5 program while trying to run a Python script. It was working fine the one day and when I tried using it this afternoon I got the following error after tying to run a program which I am 100% has no errors in it.
In the message box I got the following error:
Failed to import the site module
Traceback (most recent call last):
File "C:\Python34\lib\site.py", line 562, in <module>
main()
File "C:\Python34\lib\site.py", line 544, in main
known_paths = removeduppaths()
File "C:\Python34\lib\site.py", line 125, in removeduppaths
dir, dircase = makepath(dir)
File "C:\Python34\lib\site.py", line 90, in makepath
dir = os.path.join(*paths)
AttributeError: 'module' object has no attribute 'path'
Process finished with exit code 1
I have never seen an error of this kind and don't know where to start tackling this problem.
Any feedback will be greatly appreciated!
The code looks like the following, and I seem to have forgotten to mention that it gives me the exact same error for every single .py script on my computer.
import turtle
wn = turtle.Screen()
alex = turtle.Turtle()
def hexagon(var):
for i in range(6):
alex.right(60)
alex.forward(var)
def square(var):
for i in range(4):
alex.forward(var)
alex.left(90)
def triangle(var):
for i in range(3):
alex.forward(var)
alex.left(120)
def reset():
alex.clear()
alex.reset()
x = True
while x:
alex.hideturtle()
choice = input("""
Enter the shape of choice:
a. Triangle
b. Square
c. Hexagon
""")
if choice.lower() == "a":
length = input("Enter the desired length of the sides: ")
triangle(int(length))
restart = input("Do you wish to try again? Y/N ")
if restart.lower() == "n":
x = False
else:
reset()
if choice.lower() == "b":
length = input("Enter the desired length of the sides: ")
square(int(length))
restart = input("Do you wish to try again? Y/N ")
if restart.lower() == "n":
x = False
else:
reset()
if choice.lower() == "c":
length = input("Enter the desired length of the sides: ")
hexagon(int(length))
restart = input("Do you wish to try again? Y/N ")
if restart.lower() == "n":
x = False
else:
reset()
print("Thank you for using your local turtle services!")
You must have a python file named os.py which is being imported instead of the "real" os module.

How can I repeat a function in python 3?

So here is my code:
membership_data = open("C:\\Users\\user\Desktop\Pre-release\membership_data.txt", "w")
def ValidateMemberID(MemberID):
if len(MemberID) !=6:
return("Wrong Format")
elif MemberID[:1] == (MemberID[:1]).lower():
return("Wrong Format")
elif MemberID[1:3] == (MemberID[1:3]).upper():
return("Wrong Format")
elif (MemberID[3:]).isdigit() == False:
return("Wrong Format")
else:
return("Correct Format")
def inputdata():
Name = input("Please input member name")
MemberID = input("Please input member ID")
ValidateMemberID(MemberID)
if ValidateMemberID(MemberID) == "Correct Format":
NameID = [Name, MemberID, "\n"]
else:
print ("Invalid MemberID")
membership_data.writelines(NameID)
for _ in range(5):
do()
inputdata(_)
membership_data.close
The issue I get is:
Traceback (most recent call last):
File "C:\Users\user\Desktop\Pre-release\task_3.1.py", line 31, in <module>
do()
NameError: name 'do' is not defined
What I want to do is to input 5 different records upon the first instance of my program. Essentially I need to run inputdata() for 5 times. However, my for in range do function keeps giving back this error. I tried different ways of writing it but to no avail.
I think you must delete 'do()' from your code
for x in range(5):
inputdata()
membership_data.close()

Categories

Resources