I am wanting to create a loop for my book reader so that when the user inputs a number other than 1-10, an error message comes up, and when they press 0 the program quits. However, an error message appears saying FileNotFoundError: No such file or directory: '11.txt'(etc)
import time
option = str(input('Which Book would you like to read? (1-10): '))
while option !=0:
number_of_words = 0
f=open(option + '.txt', encoding='utf-8')
file_contents=f.read()
lines = file_contents.split()
number_of_words += len(lines)
print('Word Count:',number_of_words)
time.sleep(2)
f=open(option + '.txt', encoding='utf-8')
for line in f:
print(line)
time.sleep(0)
else:
print("404 file not found")
print()
option=str(input('Which Book would you like to read?(1-10):'))
print("Goodbye")
Try this:
import time
while True:
try: # Wrap the input in a try except and try to convert it directly to an integer.
option=int(input('Which Book would you like to read? (1-10): '))
except:
print("Please only enter a number.")
continue
if option == 0:
print("Goodbye")
break
if option > 10:
print("Invalid book entered, try again, must be between 1 and 10.")
continue
with open(str(option) + '.txt', encoding='utf-8') as f: # Use a context manager to open files, it will make sure your files are closed after opening
file_contents=f.read()
number_of_words = len(file_contents.split())
print('Word Count:',number_of_words)
time.sleep(2)
for line in file_contents:
print(line)
Results:
Which Book would you like to read? (1-10): few
Please only enter a number.
Which Book would you like to read? (1-10): 121
Invalid book entered, try again, must be between 1 and 10.
Which Book would you like to read? (1-10): 0
Goodbye
Related
I'm trying to convert string in list into float without using join() map() enumerate() replace() these built-in function as assignment requirement. What else can I use to remove comma after the number?
Create an ordering system for customer to buy something that uploaded by admin.
This is the whole purchasing function that i do:
def place_order():
try:
fileHandler= open('groceries_list.txt','r')
except:
print('File cannot be opened.')
exit()
gro=fileHandler.readlines()
if len(gro) == 0:
print("Sorry! There are no groceries in our store yet.")
else:
repeat = True
while repeat == True:
try:
fo= open('groceries_list.txt')
fr= fo.readlines()
except:
print('File cannot be read.')
order_list=[]
total=0
onp=[]
view_gro()
product= input('Please enter groceries name you want to purchase: ').upper()
for line in fr:
line=line.rstrip()
if not product in line:
continue
print(line)
line=line.split()
print('The price for',product,'is RM',(line[3]))
######################need to convert line[3] in list to float
line[3]=float(line[3])
total=total+line[3]
order_list.append(product)
print('Product successful added to you shopping cart!')
again= input('Do you need anything else? YES for continue or NO for quit.').upper()
if again == 'YES':
continue
elif again == 'NO':
print("Here's your shopping cart item")
print(order_list)
print('Total amount for your purchasing is RM',total)
try:
while True:
pay=int(input('You pay: RM '))
balance= total-pay
if balance == 0:
print('Pay successfully! Thanks for your purchasing')
fw= open('order_list_c.txt','w')
fw.write(order_list)
fw.write('\n')
fw.close()
repeat=False
#break
else:
print('Pay unsuccessfully! Please try again.')
continue
except ValueError:
print('Please enter numeric proper amount.')
continue
else:
print('Please enter YES or NO')
print('==============================')
continue
# else:
# print('Product not in list.')
# continue
#else:
# print('No products found. Try again.')
# continue
fo.close()
fileHandler.close()
This is the part Im talking about.
for line in fr:
line=line.rstrip()
if not product in line:
continue
print(line)
line=line.split()
print('The price for',product,'is RM',(line[3]))
######## need to convert line[3] in list to float but contains comma ######
line[3]=float(line[3])
total=total+line[3]
This is error showed
line[3]=float(line[3])
ValueError: could not convert
string to float: '40.0,'
This is the list:
['FOOD', 'vege', 2022, 40.0, 'fresh']
Assuming you get from the file, a str: "['FOOD', 'vege', 2022, 40.0, 'fresh']"
then when you line=line.split() it will split on the spaces, so your array of strings will look like:
[ "['FOOD',", "'vege',", "2022,", "40.0,", "'fresh']"]
and then float() chokes on the unexpected ,.
Try to split(", "), but keep in mind, your 0th (first) and -1th (last) elements will have an extra [ or ] in their strings.
Use ast.literal_eval() to parse the line, rather than using split() and float().
import ast
for line in fr:
line_list = ast.literal_eval(line)
if product not in line_list:
continue
price = line_list[3]
print('The price for',product,'is RM',price)
I am looking to correct this code so that when the user inputs 99999 then the code stops running, im also looking to make it so that if the user input is 999 it sets the total to 0
import sys
def money_earned():
total = int()
try: # try open the file
file = open("total.txt", "r")
data = file.readline()
total = int(data)
except: # if file does not exist
file = open("total.txt", "w+") # create file
total = 0
file.close() # close file for now
while True:
try:
pay_this_week = int(input("How much money did you earn this week? "))
break
except ValueError:
print("Oops! That was no valid number. Try again...")
pay_this_week_message = "You've earned £{0} this week!".format(pay_this_week)
total = pay_this_week + total
total_message = "You have earned £{0} in total!".format(total)
print(pay_this_week_message)
print(total_message)
if pay_this_week == "99999":
sys.exit()
file = open("total.txt", "w") # wipe the file and let us write to it
file.write(str(total)) # write the data
file.close() # close the file
money_earned()
So you're taking the input as a string and immediately converting it to an int, but you could actually convert it to an int later and check for some words in your input first.
Right now you have
pay_this_week = int(input("..."))
but if you change this to
input_from_user = input("...")
pay_this_week = int(input_from_user)
then we can add some more code inbetween
input_from_user = input("...")
if input_from_user == "done":
return # this will exit the function and so end execution
elif input_from_user == "reset":
total = 0 # reset the total
else:
pay_this_week = int(input_from_user)
this should have the desired effect
The basics of the program are to ask the user for a .txt file and count how many lines in the file. Then the program displays the number of lines in the file and the user will input a number to display a certain line in the file. If the user hits 0 the program will end.
The program runs fine until I enter a number besides 1 or the last line number in the .txt file. The program proceeds to display the "Enter a line number, want to quit? Hit 0" Over and over.
inName = input("Enter the a valid file name: ")
inputFile = open(inName, "r")
count = 0
for line in inputFile:
count = count + 1
print("The file has " + str(count) + " lines.")
inputFile.close()
while True:
try:
n = int(input("Enter a line number, want to quit? Hit 0: "))
lineno = 0
break
except ValueError:
print("Try again. Line number must be between 1 and " + str(count))
while n != 0:
if n >= 0 and n <= count:
inputFile = open(inName, "r")
for line in inputFile:
lineno = lineno + 1
if lineno == n:
print(line)
inputFile.close()
else:
print("Try again. Line number must be between 1 and " + str(count))
while True:
try:
n = int(input("Enter a line number, hit 0 to quit: "))
lineno = 0
break
except ValueError:
print("Try again. Line number must be between 1 and " + str(count))
I will not address the multitude of issues with your code, since the comments and answer have done a pretty thorough job there already. Instead, I'd like to discuss the I/O problem you are creating by opening and closing the file over and over. It's expensive to do that. For a program that spends virtually all its time waiting for user input, is probably won't be noticeable, but opening and closing files without need is a bad habit.
I would suggest one of two solutions to get around this. If you are dealing with small text files, just load the whole thing into memory, e.g. with file.readlines():
inName = input("Enter the a valid file name: ")
with open(inName, "r") as file:
data = file.readlines()
count = len(data)
print(f"The file has {count} lines.")
while True:
try:
n = int(input("Enter a line number, want to quit? Hit 0: "))
except ValueError:
print(f"Try again. Line number must be between 1 and {count}")
else:
if n == 0:
break
print(data[n - 1])
For large files, I would agree with your technique of loading only one line at a time, but you have to be smart about it. I would open the file once, create a table of offsets to the line starts, and move around the file using that table:
inName = input("Enter the a valid file name: ")
with open(inName, "r") as file:
table = [0]
table.extend(file.tell() for _ in file)
count = len(table) - 1 # last entry is size of file
print(f"The file has {count} lines.")
while True:
try:
n = int(input("Enter a line number, want to quit? Hit 0: "))
except ValueError:
print(f"Try again. Line number must be between 1 and {count}")
else:
if n == 0:
break
file.seek(table[n - 1])
print(file.readline()
Refactored your code and made some changes in the loops, removed the part where you were closing the file mid-loop and replaced it with break.
Try this if it works :
inName = input("Enter the a valid file name: ")
inputFile = open(inName,"r")
count = 0
for line in inputFile:
count = count + 1
print("The file has "+str(count)+" lines.");
inputFile.close()
while True:
try:
n = int(input("Enter a line number, want to quit? Hit 0: "))
lineno = 0
except ValueError:
print("Try again. Line number must be between 1 and "+str(count))
if n != 0:
if n >= 0 and n <= count:
inputFile = open(inName, "r")
for line in inputFile:
if lineno == n:
print(line)
#inputFile.close()
break
else:
lineno = lineno + 1
else:
print("Try again. Line number must be between 1 and "+str(count))
else:
break
So I am trying to create a password system in Python, whereby after a certain number of incorrect attempts, the user will be blocked from accessing it for, say, 5 minutes. I am currently unsure how the values of the variables can be kept after rerunning the same file and then used in this manner. Could someone help me with this, as I am currently still new to Python?
Update:
After experimenting for a while with the code Jonas Wolff provided me I finalised my code to the following:
def password():
count = 0
currentTime = float(time.time())
passwordList = ["something", "password", "qwerty", "m42?Cd", "no"]
passwordNum = random.randint(0, 4)
password = passwordList[passwordNum]
with open("password.txt", "r") as file:
check = file.readline()
initialTime = file.readline()
if initialTime=="":
initialTime==0
if int(check)==1 and (currentTime-float(initialTime))<300:
print("You are still locked")
print("Please try again in", int(300-(currentTime-float(initialTime))), "seconds.")
quit()
print("The randomised password is No.", passwordNum+1) #Prints a string to let the user know which password was randomly selected
while count<5:
inp = input("Enter the Password: ")
if inp==password:
print("Access Granted")
print()
f = open("password.txt", "w")
f.write("0\n0")
f.close()
select()
elif (count+1)==5:
print("You have been locked")
print("Please try again in 5 minutes")
f = open("password.txt", "w")
f.write("1\n")
f.write(str(currentTime))
f.close()
quit()
else:
count+=1
print("Incorrect Password")
print("You have", 5-count, "tries left.")
continue
Thanks a lot for the help you have provided and the patience with which you answered my questions.
import YourProgram # this is the program you want to run, if the program runs automaticly when opened then move the import to the part where i wrote YourProgram() and delete the YourPregram() line
import time
pswd = "something"
count = 0
with open("PhysxInit.txt","r") as file:
file_info = file.readline()
numa = file_info.count("1")
count = numa
while True:
with open("PhysxInit.txt","r") as file:
file_info = file.readline()
tima = file.readline()
inp = input("What is the password:")
if inp == pswd:
if tima == "":
tima = "0" # this should solve yoúr problem with float convertion however it doesn't make sence that this step should be needed
if str(file_info[:5]) != "11111" or time.time() > float(tima):
YourProgram() # this is just meant as the thing you want to do when when granted acces i magined you where blocking acces to a program.
f = open("PhysxInit.txt", "w")
f.write("\n")
f.close()
break
else:
count += 1
f = open("PhysxInit.txt", "w")
f.write(("1"*count)+"\n"+str(tima))
if count == 5:
f.write(str(time.time()+60*5))
f.close()
#f = open("PhysxInit.txt", "w")
#f.write("\n")
#f.close()
does this work?
just make sure you have a text file called PhysxInit.txt
after running the program, and having guessed wrong a few times my txt file look like this.
11111
1536328469.9134998
it should look something like mine though the numbers may be diffrent.
To read a specific line as you requested you need to do:
with open("PhysxInit.txt", "r") as f:
for w,i in enumerate(f):
if w == #the number line you want:
# i is now the the line you want, this saves memory space if you open a big file
I have a try/except block in a function that asks the user to enter the name of a text file to open. If the file does not exist, I want the program to ask the user for the filename again either until it is located or the user hits ENTER.
Right now the try/except block just runs infinitely.
def getFiles(cryptSelection):
# Function Variable Definitions
inputFile = input("\nEnter the file to " + cryptSelection +\
". Press Enter alone to abort: ")
while True:
if inputFile != '':
try:
fileText = open(inputFile, "r")
fileText.close()
except IOError:
print("Error - that file does not exist. Try again.")
elif inputFile == '':
input("\nRun complete. Press the Enter key to exit.")
else:
print("\nError - Invalid option. Please select again.")
return inputFile
You need to break out of the while loop, this has to be done at 2 places:
After reading the file (when it is a correct file)
After the Enter key is pressed. because we want to end.
Also you need to prompt the question inside the loop so the question is asked again at every iteration and the inputFile value is updated with the latest user input
One last thing, I think your else clause can be removed as it is never accessed, the if and elif catch all the possibilities (ie, inputFile has a value or not).
def getFiles(cryptSelection):
while True:
inputFile = input("\nEnter the file to %s. Press Enter alone to abort:" % cryptSelection)
if inputFile != '':
try:
fileText = open(inputFile, "r")
fileText.close()
# break out of the loop as we have a correct file
break
except IOError:
print("Error - that file does not exist. Try again.")
else: # This is the Enter key pressed event
break
return inputFile
you have a while True but no break in your code you probably want to break after the fileText.close() like this:
try:
fileText = open(inputFile, "r")
fileText.close()
break
except IOError:
print("Error - that file does not exist. Try again.")
but really you should change this check to use os.path.isfile like this:
import os
def getFiles(cryptSelection):
inputFile = input("\nEnter the file to " + cryptSelection +\
". Press Enter alone to abort: ")
while True:
if inputFile != '':
if os.path.isfile(inputFile):
return inputFile
else:
print("Error - that file does not exist. Try again.")
elif inputFile == '':
input("\nRun complete. Press the Enter key to exit.")
else:
print("\nError - Invalid option. Please select again.")
That is because you don't assign a new value to inputFile within the while loop.
It will hold the same value forever...
EDIT
Once you will assign a new value to inputFile within the loop - make sure to break out when the exit condition is met ("user hits Enter")