now i have this code and i need to use better the function try and except and improve the code, like which parts i should change of place
this is the beginning of my code:
contador = 0
name = input("Put the name of the file:")
while name != "close":
validation=0
try:
file = open(name,"r",1,"utf-8")
validation = validation + 1
except FileNotFoundError:
validation = validation
if validation >= 1:
Games=[]
countrylist = []
lines = 0
File = open(name,"r")
line = File.readline().strip()
while line != "":
parts= line.split(";")
country=parts[0]
game= parts[1]
sales= int(parts[2])
price= float(parts[3])
format= parts[4]
Games.append(parts)
countrylist.append(country)
line = File.readline().strip()
lines = lines + 1
contador = contador + 1
I don't know exactly the objective of the code, however.
I had to work out how would the file be structured by the code Correct me if I'm wrong but I believe that the file is meant to have a list of parameters separated by ";" and each line being an entry in that list.
You do nothing with the data, in any case just breaking the file into a list of parameters and sending said list of lists back would be enough for a function and then you could do the separation later
So that I could see that the code was doing what I wanted I added a print at the end to get the result
This is the code I ended with I tried to explain most of the issues in comment (probably a bad idea and I shall be berated by this till the end of ages)
# Why is there a global counter
# contador = 0
name = None # you need to declare the name before the loop
# check if the name is empty instead of an arbitrary name
while name != "":
name = input("Put the name of the file:")
# have the call defenition of the name in the loop so you can run the
# loop until the anme is "" (nothing)
# otherwhise if you don't break on the catch block it will loop forever
# since the name will be constant inside the loop
try:
File = open(file=name,encoding="utf-8").read()
# when using a function and you don't want to use the arguments
Games=[]
countrylist = []
# lines = 0
lst = File.strip().split("\n") # break the whole text into lines
for line in lst: # iterate over the list of lines
# seperate it into a list of data
parts= line.strip().split(";") #make each line into a list that you can adress
# elem[0] -> county
countrylist.append(parts[0]) # here you can just append directly isntead of saving extra variables
# same as the previous example
Games.append(parts[1])
sales= int(parts[2])
price= float(parts[3].replace(",","."))
style = parts[4] # format is already an existing function you shoudn't name your variable like that
# line = File.readline().strip() -> you don't need to prepare the next line since all lines are
# already in the array lst
# lines += 1
# contador += 1
# you don't need to count the lines let the language do that for you
# and why do you need a counter in the first place
# you were using no for loops or doing any logic based around the number of lines
# the only logic you were doing is based on their
print(parts)
except FileNotFoundError as e0:
print("File not found: " + str(e0))
except ValueError as e1 :
print("Value Error: " + str(e1))
For a text file with the format:
Portugal;Soccer;1000;12.5;dd/mm/yyyy
England;Cricket;2000;13,5;mm/dd/yyyy
Spain;Ruggby;1500;11;yyyy/dd/mm
I got an output in the form of:
['Portugal', 'Soccer', '1000', '12.5', 'dd/mm/yyyy']
['England', 'Cricket', '2000', '13,5', 'mm/dd/yyyy']
['Spain', 'Ruggby', '1500', '11', 'yyyy/dd/mm']
Related
I'm trying to replace a specific part of a line in a txt file, but it says "AttributeError: 'list' object has no attribute 'replace'".
This is part of my code:
with open("credentials.txt",'r+') as f:
credentials_array = f.readlines() # credentials_array contains the txt file's contents, arranged line by line. so credentials_array[0] would be the first login info in the file
lines_in_credentials = len(credentials_array) # if there are 7 credentials in the text file, lines_in_credentials = 7.
while x < lines_in_credentials:
if user in credentials_array[x]: # go through each line in turn to see if the login_username is in one. line 1, credentials_array[1].
credentials_desired_line = credentials_array[x]
username_password_score = credentials_array[x].split(",") # username_password_score is the contents of each line, the contents are split by commas
stored_username = username_password_score[0] # username is part 1
stored_password = username_password_score[1] # password is part 2
stored_score = username_password_score[2] # score is part 3
stored_score_int = int(stored_score)
if user == stored_username:
if new_score > stored_score_int:
print("Congratulations! New high score!")
print(stored_score_int,"-->",new_score)
credentials_array_updated = stored_username+","+stored_password+","+str(new_score) # reassign the array[x] to having new_score at the end instead of stored_score
credentials_array.replace(credentials_array[x],credentials_array_updated)
break
Is there any other way to do it?
Your missing a line setting x = 0 in your presented problem, but that's not important - I think that's just a typo you've missed when writing it out.
Your line:
credentials_array.replace(credentials_array[x], credentials_array_updated)
is your problem. Try:
credentials_array[x].replace(credentials_array[x], credentials_array_updated)
replace operates on the string, and you want to replace the string within credentials_array[x], not the whole list.
Now, I have assumed there are more entries to credentials_desired_line than what you've outlined in username_password_score. Otherwise you could do just a straight replacement such as:
credentials_array[x] = credentials_array_updated
As a bigger change, you could try this:
iLines = 0
with open("credentials.txt",'r+') as f:
credentials_array = f.readlines()
for line in credentials_array:
if user in line: #user we want is in this line
currScore = int(credentials_array[x].split(",")[2])
if new_score > currScore:
print("Congratulations! New high score!")
print(Str(currScore),"-->",str(new_score))
credentials_array[iLines].replace(str(currScore),str(newScore))
break
iLines =+1
With you wanting to update the text file, the minimal mod to your code would be to put this at the end (beyond/outside) the previous "with open()" loop:
with open('credentials.txt', 'w') as f:
for line in credentials_array:
f.write("%s\n" % line)
I have a program that reads a txt file with names "surname, first name, Y". one of the names does not have a "Y" and i want to change the code, instead of saying "did not attend any days" to ignore / remove if from the list and not print anything in the output.
from time import strftime # import time
print("Report date: " + strftime("%d/%m/%Y")) #Prints clock time
with open("confPack.txt", "r") as confPack: # open file as confpack
cPack = confPack.read().splitlines() # create cpak variable
with open("employees.txt") as fp: #open file as fp
for line in fp:
Name = line.strip().split(",") # iterate through employees, strip, split and list
surname = Name[0]
firstName = Name[1]
# is the last value not a Y (meaning no Y's)
if Name[-1] != 'Y':
packs = 'did not attend any days'
# if that's false, meaning there is a Y, is the one before it a Y too
elif Name[-2] == 'Y':
packs = (cPack[1]) # they get bonus pack
# if the first 2 conditions are not met
else:
packs = (cPack[0]) #they get conference pack
print(f"Attendee: {surname}, {firstName}: {packs}") #print surname, first name and pack using f-string
thanks in advance
This is what ggorlen means:
from time import strftime # import time
print("Report date: " + strftime("%d/%m/%Y")) #Prints clock time
with open("confPack.txt", "r") as confPack: # open file as confpack
cPack = confPack.read().splitlines() # create cpak variable
with open("employees.txt") as fp: #open file as fp
for line in fp:
Name = line.strip().split(",") # iterate through employees, strip, split and list
surname = Name[0]
firstName = Name[1]
# is the last value not a Y (meaning no Y's)
if Name[-1] != 'Y':
continue
# if that's false, meaning there is a Y, is the one before it a Y too
elif Name[-2] == 'Y':
packs = (cPack[1]) # they get bonus pack
# if the first 2 conditions are not met
else:
packs = (cPack[0]) #they get conference pack
print(f"Attendee: {surname}, {firstName}: {packs}") #print surname, first name and pack using f-string
#ggorlen is definitely right. You can use try-except block inside the for-loop.
for line in fp:
try:
{code}
except:
continue
Even if you have an error, the loop will continue with the next iteration.
I am having trouble with matching variables to lines in txt, and removing the lines.
I am currently doing a hotel room booking program in which I am having trouble removing a booking from my text file.
This is how my lines in my text file are formatted:
first_name1, phonenumber1 and email 1 are linked to entry boxes
jeff;jeff#gmail.com;123123123;2019-06-09;2019-06-10;Single Room
def edit_details(self,controller):
f = open("Bookings.txt")
lines = f.readlines()
f.close()
x = -1
for i in lines:
x += 1
data = lines[x]
first_name1 = str(controller.editName.get())
phonenumber1 = str(controller.editPhone.get())
email1 = str(controller.editEmail.get())
checkfirst_name, checkemail, checkphone_num, checkclock_in_date, checkclock_out_date, checkroom = map(str, data.split(";"))
if checkfirst_name.upper() == first_name1.upper() and checkemail.upper() == email1.upper() and checkphone_num == phonenumber1:
controller.roomName.set(checkfirst_name)
controller.roomEmail.set(checkemail)
controller.roomPhone.set(checkphone_num)
controller.roomCheckin.set(checkclock_in_date)
controller.roomCheckout.set(checkclock_out_date)
controller.roomSelect.set(checkroom)
print(controller.roomName.get())
print(controller.roomSelect.get())
controller.show_frame("cancelBooking")
break
elif x > len(lines) - int(2):
messagebox.showerror("Error", "Please Enter Valid Details")
break
I have the user to enter their details to give me the variables but I don't know how to match these variables to the line in the text file to remove the booking.
Do I have to format these variables to match the line?
This is what i have tried but it deletes the last line in my file
line_to_match = ';'.join([controller.roomName.get(),controller.roomEmail.get(),controller.roomPhone.get()])
print(line_to_match)
with open("Bookings.txt", "r+") as f:
line = f.readlines()
f.seek(0)
for i in line:
if i.startswith(line_to_match):
f.write(i)
f.truncate()
I have kind of added a pseudocode here. You can join the variables using ; and validate if the line startswith those details, like below.
first_name1, phonenumber1, email1 = 'jeff', 'jeff#gmail.com', '123123123'
line_to_match = ';'.join([first_name1, email1, phonenumber1])
for i in line:
...
if i.startswith(line_to_match):
# Add your removal code here
...
#
# Obtain user input for file name, and open it
#
inFile = open(input("Enter file name: "), "r")
#
# Process data and address possible errors
#
countDinner = 0
countLodging = 0
countConference = 0
valueDinner = 0
valueLodging = 0
valueConference = 0
done = False
while not done :
line = inFile.readline()
try :
s = line
serviceAmount = ';'.join(s.split(';')[1:-1]) #Removes date and name regardless of format
serviceAmount.split(";")
s.lower()
if "dinner" in s :
countDinner = countDinner + 1
valueDinner = valueDinner + int(filter(str.isdigit, s))
print("Dinners: ", countDinner, "Value of Dinner sales: ", valueDinner)
elif "lodging" in s :
countLodging = countLodging + 1
valueLodging = valueLodging + int(filter(str.isdigit, s))
print("Lodging: ", countLodging, "Value of Lodging sales: ", valueLodging)
elif "conference" in s :
countConference = countConference + 1
valueConference = valueConference + int(filter(str.isdigit, s))
print("Conferences: ", countConference, "Value of Conference sales: ", valueConference)
elif line == "" :
done = True
else :
print("Invalid file format.")
except FileNotFoundError :
print("Unable to find file.")
finally :
done = True
inFile.close()
Returns "Invalid file format" even when the document is set up specifically for this code. I'm not getting a syntax error, so I'm not sure whats wrong.
The document contains the text:
John;Lodging;123;050617
Tyler;Conference;123;081497
Taylor;Dinner;453;041798
There are a lot of things you aren't doing quite right here. I tried to not only fix the issue you posted about, but also write some code that should be more clear and easier to use. I left comments to explain things.
# Don't open the file here, just get the file name. We will open in later
fname = input("Enter file name: ")
# I think using dicts is more clearn and organized. Having so many variables I think makes the code messy
counts = {"Dinner": 0,
"Lodging": 0,
"Conference": 0}
values = {"Dinner": 0,
"Lodging": 0,
"Conference": 0}
# Lets try to open the file
try:
with open(fname, 'r') as inFile: # Use "with", this way the file is closed automatically when we are done reading it
for linenum, line in enumerate(inFile): # I want to enumerate each line. If there is an error on a line, we can display the line nmber this way
line = line.lower().split(';')[1:-1] # lets make it all lower case, then split and drop as needed
print(line)
if "dinner" in line :
counts["Dinner"] += 1 # x += 1 is the same as x = x + 1, but cleaner
values["Dinner"] += int(line[1])
print("Dinners: {} Value of Dinner sales: {}".format(counts["Dinner"], values["Dinner"]))
elif "lodging" in line :
counts["Lodging"] += 1
values["Lodging"] += int(line[1])
print("Lodging: {} Value of Dinner sales: {}".format(counts["Lodging"], values["Lodging"]))
elif "conference" in line :
counts["Conference"] += 1
values["Conference"] += int(line[1])
print("Conference: {} Value of Dinner sales: {}".format(counts["Conference"], values["Conference"]))
else :
print("Invalid file format on line {}".format(linenum)) # Here is why we used enumerate in the for loop
except FileNotFoundError:
print("Unable to find file.")
Here is your problem:
serviceAmount = ';'.join(s.split(';')[1:-1]) #Removes date and name regardless of format
serviceAmount.split(";")
You should do:
serviceAmount = ';'.join(s.lower().split(';')[1:-1])
You are checking against lower case strings, but not actually lower casing your input.
It is also important to note that s.lower() doesn't actually change s, it just returns a string where all the letters of s have been switched to lower case. Same thing for split (as in not changing the string its called on, not that it returns a string).
Another problem you are going to run into is getting the numbers from your strings.
int(filter(str.isdigit, s))
Won't work. You can use split again like you did earlier (or just not re-join since you only care about the first element in the comparisons).
int(serviceAmount.split(';')[1])
The last thing is the
finally:
done = True
inFile.close()
finally always runs when exiting a try, meaning that you are always done after each loop (and close the file after you read the first line).
If you remove the finally and add inFile.close() inside the elif line == "" it will close, and set done only when you've reached the end of the file.
It could be done as simple as
categories = {}
filename = input("Enter file name: ")
with open(filename, "r") as file:
name, category, value, date = file.readline().split(";")
if category not in categories:
categories[category] = {"count": 0, "value": 0}
categories[category]["count"] += 1
categories[category]["value"] += int(value)
At the end, you'll have a dict with categories, their count, and value, and also their names are not hard-coded.
I'm making a program that stores data in a text file, I can search for data line by line, and I made a (delete function) that is quoted below, making a variable 'a' adding to it the (non deleted lines), and ask before deletion for results and if not confirmed it would be added also to 'a', then rewrite the (file) with'a' omitting the deleted lines.
THE PROBLEM IS:
all results are deleted not only the confirmed one desbite that:
#deleting line
confirm = input('confirm to delete [y]/[n]>>')
if confirm != 'y':
a += line
so, why did this problem happen and how to fix it?
Next is the whole code of delete function:
searching = input('enter any information about query: ')
searching = searching.lower() # converting words in lower case
f = open(file, 'r')
lines = f.readlines()
f.close()
print('Word | Definition | Remarks')
a = '' # we will store our new edited text here
for line in lines:
line_lower_case = line.lower() # changing line in lower case temporary
# because contact != COntact and will not appear in searcch
if searching in line_lower_case:
print('Query found')
print()
print('>>',line, end = '') # printing words in the same case as been added
# end = '', to prevent printing new line avoiding extra empty line
#deleting line
confirm = input('confirm to delete [y]/[n]>>')
if confirm != 'y':
a += line
#elif confirm =='y':
# pass # it will just do nothing, and will not add line to 'a'
continue # to search for more queries with the same searching entry
print()
a += line #we add each line to the 'a' variable
f = open(file,'w')
f.write(a) #we save our new edited text to the file
f.close()
I changed the indentations of the program and that was the issue as I agreed with #TheLazyScripter and that should work now if I understood your problem correctly, I did a bunch of tests and they did work. I noticed that you didn't define what input file will be and I add that line of code at line 3 which will through an error if the file not defined.
searching = input('enter any information about query: ')
searching = searching.lower() # converting words in lower case
file = "test.txt" #your file
f = open(file, 'r')
lines = f.readlines()
f.close()
print('Word | Definition | Remarks')
a = '' # we will store our new edited text here
for line in lines:
line_lower_case = line.lower() # changing line in lower case temporary
# because contact != COntact and will not appear in searcch
if searching in line_lower_case:
print('Query found')
print()
print('>>',line, end = '') # printing words in the same case as been added
# end = '', to prevent printing new line avoiding extra empty line
#deleting line
confirm = input('confirm to delete [y]/[n]>>')
if confirm != 'y':
a += line
#elif confirm =='y':
# pass # it will just do nothing, and will not add line to 'a'
continue # to search for more queries with the same searching entry
print()
a += line #we add each line to the 'a' variable
f = open(file,'w')
f.write(a) #we save our new edited text to the file
f.close()