Python beginner - using constant to open file traceback - python

I'm trying to start using constants in my project and this happened.
Traceback (most recent call last):
File "C:\Users\aletr\Desktop\Python projects\Restaurant software\r_0.py", line 39, in <module>
with constants.NAMES_R as f :
File "C:\Python30\lib\io.py", line 456, in __enter__
self._checkClosed()
File "C:\Python30\lib\io.py", line 450, in _checkClosed
if msg is None else msg)
ValueError: I/O operation on closed file.
I know is because the file it's been closed. But I don't understand how I was using the same code without constant and it would work perfectly.
constants:
F_NAMES = 'names.txt'
NAMES_R = open(F_NAMES, 'r+')
NAMES_W = open(F_NAMES, 'w+')
script:
import constants
with constants.NAMES_R as f :
f_n = f.read().splitlines()
print("Welcome to NAME.app")
##############
# USER LOGIN #
##############
while True:
name = input("""
\n - Insert name to logg in
\n - ADD to save new user
\n - LIST to see saved users
\n - REMOVE to delete a user
\n - EXIT to finish
\n - ...""")
lname = name.lower()
if lname == "add":
n_input = input("Name:")
with open('names.txt', 'a') as f:
f.write(n_input + '\n')
elif lname == "list":
with constants.NAMES_R as f :
print(f.read().splitlines())
f.close()
elif name in f_n:
print("Logged as", name.upper())
user = name
input('Welcome, press enter to continue \n')
break
elif lname == 'remove':
remove = input("Insert user name to remove \n ...")
with constants.NAMES_R as f :
lines = f.readlines()
lines = [line for line in lines if remove not in line]
with constants.NAMES_W as f :
f.writelines(lines)
elif lname == "exit":
exit()

Related

List not defined even when defined in earlier cases

prompt = " Type add, show, edit, complete or exit: "
while True:
user_action = input( prompt.strip())
match user_action:
case "add":
todo = input("Enter a todo:") + "\n"
file= open("todos.txt", "r")
todos = file.readlines()
file.close()
todos.append(todo)
file= open("todos.txt", "w")
file.writelines(todos)
file.close()
case "show" | "display":
file=open('todos.txt', "r")
todos= file.readlines()
file.close()
for index, item in enumerate(todos):
item= item.strip("\n")
row = f"{index+1}-{item.capitalize()}"
print(row)
case 'edit':
number= input("Enter a number: ")
print(number)
new_todo= input("Enter new tod0:")
todos[int(number)-1]= new_todo
print(new_todo)
case "complete":
number = int(input("Number of the todo:"))
row=todos.pop(int(number))
print(row)
case "exit":
break
# # case whatever:
# # print("wrong message!!! Baaaka")
print('Bye!')
In above code, when entering new to dos and using complete, it shows following error:
File "C:\Users\HP\OneDrive\Desktop\python apps\app1.py", line 40, in <module>
row=todos.pop(int(number))
NameError: name 'todos' is not defined
n above code, when entering new to dos and using complete, it shows following error:
File "C:\Users\HP\OneDrive\Desktop\python apps\app1.py", line 40, in <module>
row=todos.pop(int(number))
NameError: name 'todos' is not defined

ValueError: not enough values to unpack error in python3 while coding a very basic passwd manager

i'm a noob to programming and i keep getting this error while using the vedere() function. Sorry if it's a stupid question but i am totally new to python and to this forum. Also sorry if some part of the code is in italian. Btw it's a very basic password manager with some encryption for the passwords, here is the code:
import pyfiglet
from cryptography.fernet import Fernet
r = pyfiglet.figlet_format("Petrux Passwd Manager", font="slant")
print(r)
'''def write_key():
key = Fernet.generate_key()
with open("key.key", "wb") as k:
k.write(key)'''
def load_key():
file = open("key.key", "rb")
key = file.read()
file.close()
return key
pwd = input("Inserisci la pswd master:\n")
key = load_key() + pwd.encode()
fernet = Fernet(key)
def aggiungi():
dominio = input("Dominio:\n")
email = input("Email o username:\n")
passwd = input("Password:\n")
with open("5f4dcc3b5aa765d61d8327deb882cf99.txt", "a") as f:
f.write(dominio + "|" + email + "|" + fernet.encrypt(passwd.encode()).decode() + "\n")
print("Credenziali aggiunte con successo!")
def vedi():
with open("5f4dcc3b5aa765d61d8327deb882cf99.txt", "r") as f:
for line in f.readlines():
data = line.rstrip()
dominio, user, passw = data.split("|")
print("Dominio: ", dominio,"User: ", user, "| Password: ",
fernet.decrypt(passw.encode()).decode())
while True:
if pwd == "p3truxx":
mode = input("Vuoi aggiungere una password o vedere le esistenti?\n(aggiungere/vedere)\n \nOppure scrivi q per uscire\n").lower()
if mode == "vedere":
vedi()
elif mode == "aggiungere":
aggiungi()
elif mode == "q":
quit()
else:
print("Input non valido coglione")
else:
print("Password sbagliata")
continue
And here is the error:
Traceback (most recent call last):
File "C:\Users\invic\PycharmProjects\adventure\main.py", line 43, in <module>
vedi()
File "C:\Users\invic\PycharmProjects\adventure\main.py", line 35, in vedi
dominio, user, passw = data.split("|")
ValueError: not enough values to unpack (expected 3, got 1)
Thanks to an user who responded in the comment i tried to create a new file with the same code and worked just fine.
Probably the older .txt file contains some line that doesn't have a "|".

Python beginner - Writing text file - problem: information doesn't save when opening with 'r+'

This is the last part of my project and I've been stuck for at least two weeks trying to figure out how to do it.
Now I have this problem that: I create a text file to save information on each line (f.write(str(tobill) + '\n')) I already use this line on another parts and works perfectly.
Now what is happening is that every time is supposed to save the info in a new line in the file. Instead of saving it is like overwriting the info that I already had in the file. So it never goes to a new line and save the new info, just overwrites the first line in the file.
elif action.lower() == 'bill' :
p_b = input('Please insert number of table. \n -... ')
with open (('T' + p_b)+ '.txt', 'r+') as p :
tobill = 0
for line in p : tobill = int(tobill) + int(line)
xtra = input('Group table (+10 ppl)? y/n: \n')
if xtra == 'y' :
tobill = tobill + (tobill/100)*10
print('SERVICE CHARGE ADDED.')
elif xtra == 'n' : print ('Processing bill...')
print('Total to pay:', tobill)
print('Serviced by', user)
#### Closing added part to bill.
with open('closing.txt', 'w+') as f :
f.write(str(tobill) + '\n')
# Closing days balance.
elif action.lower() == 'closing' :
result = 0
with open('closing.txt', 'r+') as f :
for line in f :
result = int(result) + int(line)
print(result)
This code above is the part where I have the problem.
Basically what I want to do is to: Write the output of 'Bill' in my program into the new text file 'closing', every time that I run 'Bill' this should add the total to 'closing'. This with the purpose that when the day finishes you could have a balance of all the tables created and billed.
Full code for better understanding:
#C
with open('names.txt', 'r') as r :
f_n = r.read().splitlines()
print("Welcome to NAME.app")
##############
# USER LOGIN #
##############
while True:
name = input("""
\n - Insert name to logg in
\n - ADD to save new user
\n - LIST to see saved users
\n - REMOVE to delete a user
\n - EXIT to finish
\n - ...""")
lname = name.lower()
if lname == "add":
n_input = input("Name:")
with open('names.txt', 'a') as f:
f.write(n_input + '\n')
elif lname == "list":
with open('names.txt') as f:
print(f.read().splitlines())
f.close()
elif name in f_n:
print("Logged as", name.upper())
user = name
input('Welcome, press enter to continue \n')
break
elif lname == 'remove':
rem = input("Insert user name to remove \n ...")
with open('names.txt', 'r+') as f:
l = f.readlines()
l = [z for z in l if rem not in z]
with open('names.txt', 'w') as f:
f.writelines(l)
elif lname == "exit":
exit()
####################
# TABLE MANAGEMENT #
####################
#C:
while True:
action = input ('''
- NEW table
\n - ADD table
\n - BILL
\n - CLOSING
\n - EXIT
\n - ... ''')
d = {'(1) chburger': 19,'(2) bncburger': 23,'(3) plpasta': 6}
if action == 'new' :
tn = input('Insert table number \n - ...')
name = 'T' + tn
t = open(name + '.txt', 'w+')
print('Done')
elif action.lower() == 'add':
# Select table
table = input ('Select desired table number: \n - ...')
fulltab = 'T' + table
with open(fulltab + '.txt', 'w+') as f :
# Order list and add Order
while True:
for k, v in d.items() :
print(k, v)
addprod = input('Insert order. \n - ...')
for k, v in d.items() :
if addprod == k[1] :
f.write(str(v) + '\n')
#Option to continue.
q = input('Add more? y/n \n -...')
if q.lower() == 'y' : continue
if q.lower() == 'n' : break
#File as F
elif action.lower() == 'bill' :
p_b = input('Please insert number of table. \n -... ')
with open (('T' + p_b)+ '.txt', 'r+') as p :
tobill = 0
for line in p : tobill = int(tobill) + int(line)
xtra = input('Group table (+10 ppl)? y/n: \n')
if xtra == 'y' :
tobill = tobill + (tobill/100)*10
print('SERVICE CHARGE ADDED.')
elif xtra == 'n' : print ('Processing bill...')
print('Total to pay:', tobill)
print('Serviced by', user)
#### Closing added part to bill.
with open('closing.txt', 'w+') as f :
f.write(str(tobill) + '\n')
# Closing days balance.
#Closing added to bill line 95
elif action.lower() == 'closing' :
result = 0
with open('closing.txt', 'r+') as f :
for line in f :
result = int(result) + int(line)
print(result)
# Exit command.
elif action.lower() == "exit":
exit()
I know it's not the best, but it's my first project after studying and researching for 4 weeks.
The problem is that you are using open with the argument 'r+' while what you want to use is 'a' or 'a+'.
opening a file in 'r+' will open file at the beginning and writing will overwrite lines instead of appending. that is why you should use 'a' or 'a+' as it writes new lines at the end of the file.
from: http://www.manpagez.com/man/3/fopen/
``r'' Open text file for reading. The stream is positioned at the
beginning of the file.
``r+'' Open for reading and writing. The stream is positioned at the
beginning of the file.
``w'' Truncate to zero length or create text file for writing. The
stream is positioned at the beginning of the file.
``w+'' Open for reading and writing. The file is created if it does not
exist, otherwise it is truncated. The stream is positioned at
the beginning of the file.
``a'' Open for writing. The file is created if it does not exist. The
stream is positioned at the end of the file. Subsequent writes
to the file will always end up at the then current end of file,
irrespective of any intervening fseek(3) or similar.
``a+'' Open for reading and writing. The file is created if it does not
exist. The stream is positioned at the end of the file. Subse-
quent writes to the file will always end up at the then current
end of file, irrespective of any intervening fseek(3) or similar.
ereldebel's answer is probably the way to go,
but if you're having problems you can always do it the hard and simple way,
by getting the text from the file and adding them together:
oldText = ''
with open('names.txt', 'r') as f:
oldText = f.read()
with open('names.txt', 'w') as f:
f.writelines(oldText + YourNewText)

Why the context of the file cannot read from the txt file?

I have creat a new empty txt file, but the code below read and write it.
f = open('users.txt', 'r+')
users = eval(f.read()) #f.read()read a string,eval()transfer string to dict
for i in range(4):
name = input('Input Username: ')
passwd = input('Input password: ')
c_passwd = input('Confirm password again: ')
if len(name.strip()) != 0 and name not in users and len(passwd.strip()) != 0 and passwd == c_passwd:
users[name]= {'passwd':passwd, 'role':1} #insert new data, role 1: Customer; role 2: Restaurant; role 3: Admin
f.seek(0)
f.truncate() #clear file
f.writelines(str(users)) #write data to file from dict
print('Congratulations, Register Success. ')
f.close()
break
elif len(name.strip()) == 0:
print('Username could not be empty. Remain %d chance' %(3-i))
elif name in users:
print('Username repeat. Remain %d chance' %(3-i))
elif len(passwd.strip()) == 0:
print('Password could not be empty. Remain %d chance' %(3-i))
elif c_passwd != passwd:
print('Password not same. Remain %d chance' %(3-i))
#log in
f = open('users.txt', 'r', encoding='utf8')
users = eval(f.read())
for count in range(3):
name = input('Input Username: ')
password = input('Input password: ')
if name in users and password == users[name]['passwd']:
print('Log in successful!')
break
else:
print('Username or/and Password is/are wrong,You still have %d chance'%(2-count))
f.close()
The System showed
Traceback (most recent call last):
File "C:/Users/zskjames/PycharmProjects/Fit5136/Register, log in.py", line 4, in <module>
users = eval(f.read()) #f.read()read a string,eval()transfer string to dict
File "<string>", line 0
^
SyntaxError: unexpected EOF while parsing
Do anybody could tell me how to fix that? And how to avoid this mistakes in the future.
You probably want your text file to contain JSON, in order to easily interact with it and turn it into a dict.
In order to do that, you would need to replace your eval with a json.load:
import json
with open('users.txt', 'r+') as f:
users = json.load(f)
# rest of your code
In order for it to work, your text file should look something like the following:
{"John Doe": {"passwd": "somepass", "role": 1}}
In addition, you need to replace:
f.writelines(str(users)) #write data to file from dict
to:
json.dump(users, f)

Change text in file with Python

def false_to_true():
name = input("Input name: ")
file=open("users.txt","r")
lines = file.readlines()
file.close()
for line in lines:
username, lel, type = line.split("/")
while name == username:
name = input("input name again: ")
tip = True
with open("users.txt", "w") as users:
users.write(str(red))
#
#I do not know how to perform a given modification and enrollment into place in #the text.
#
#I wont to change word False to True for username i input.
#I have this text in file users:
#Marko123/male/False
#Mimi007/female/False
#John33/male/False
#Lisa12/female/False
#Inna23/female/False
#Alisa27/female/False
I won't to change word False to True for username I input.
I have this text in file users:
Marko123/male/False
Mimi007/female/False
John33/male/False
Lisa12/female/False
Inna23/female/False
Alisa27/female/False
You can just use the csv library and forget about string manipulation:
import csv
def false_to_true():
#read from user.txt file into list(data)
with open('users.txt', 'r') as userfile:
data = [row for row in csv.reader(userfile,
delimiter="/",
quoting=csv.QUOTE_NONE)]
while True:
#waiting for input until you enter nothing and hit return
username = input("input name: ")
if len(username) == 0:
break
#look for match in the data list
for row in data:
if username in row:
#change false to true
row[2] = True
#assuming each username is uniqe break out this for loop
break
#write all the changes back to user.txt
with open('users.txt', 'w', newline='\n') as userfile:
dataWriter = csv.writer(userfile,
delimiter="/",
quoting=csv.QUOTE_NONE)
for row in data:
dataWriter.writerow(row)
if __name__ == '__main__':
false_to_true()
Open the input and output files, make a set out of the user-input names (terminated by a blank line), then create a generator for strings of the proper format that check for membership in the user-input names, then write these lines to the output file:
with open('names.txt') as f, open('result.txt', 'w') as out:
names = {name for name in iter(input, '')}
f = ('{}/{}/{}'.format(a,b,'True\n' if a in names else c) for a,b,c in (line.split('/') for line in f))
output.writelines(f)
To modify a text file inplace, you could use fileinput module:
#!/usr/bin/env python3
import fileinput
username = input('Enter username: ').strip()
with fileinput.FileInput("users.txt", inplace=True, backup='.bak') as file:
for line in file:
if line.startswith(username + "/"):
line = line.replace("/False", "/True")
print(line, end='')
See How to search and replace text in a file using Python?
Ask for name and iterate throw your lines to check for username, like this:
def false_to_true():
name = input("Input name: ")
file=open("users.txt","r")
lines = file.readlines()
file.close()
users = open("users.txt", "w")
for line in lines:
username, lel, type = line.split("/")
if name == username:
type = 'True\n'# \n for new line type ends with '\n'
users.write("/".join([username, lel, type]))
users.close()
false_to_true()

Categories

Resources