Trying to store information - python

I want to save all the users' registered ids to a text file. If the user gives 9 users, then I want it to store all the information. But when I run the code and finish it seems to be overwriting all the information. I know there is something that I'm missing. Can someone please help me?
student_count = int(input("how many students are registering?:"))
reg_form = []
for x in range(student_count):
if student_count >= 0:
registered_user = input("Please enter your I.D number for registeration: ")
id_information = [registered_user + reg_form]
student_count - 1
student_count2 = str(student_count)
with open ("reg_form.txt", 'w') as f:
f.write(registered_user + "\n")
f.close()

Try it that way:
student_count = int(input("how many students are registering?:"))
counter = 0
for x in range(student_count):
if counter < student_count + 1:
registered_user = input("Please enter your I.D number for registeration: ")
counter += 1
reg_form = open('reg_form.txt', 'a')
reg_form.write(registered_user + "\n")
reg_form.close()
You basically do not need reg_form and student_count2.
It appears that you use write mode on every iteration of the loop, which overwrites existing file. You need to use append mode like this:
open('reg_form.txt', 'a')

Related

How to not duplicate elements when entering array in csv

I have a piece of code used to enter student information. But I want to transform it so that Admission no. cannot be repeated, when entering an existing number, a message will be printed if you want to re-enter an existing number. below is my code
import csv
student_fields = ['Admission no.','Name','Age','Email','Phone']
student_database = 'students.csv'
def add_student():
print("-------------------------")
print("Add Student Information")
print("-------------------------")
global student_fields
global student_database
student_data = []
for field in student_fields:
print(field)
value = input("Enter " + field + ": ")
student_data.append(value)
with open(student_database,"a",encoding = "utf-8") as f:
writer = csv.writer(f)
writer.writerows([student_data])
print("Data saved successfully")
input("Press any key to continue")
return
You can do something like this. As Barmar suggested, put the admission numbers in a set at the start of your definition. Then, check the user's input against those numbers. Create a while loop that doesn't let the user input any other value until they enter a new Admission no (and tell them that they are entering a duplicate admission number). Once everything looks good, write it to the csv.
import csv
student_fields = ['Admission no.','Name','Age','Email','Phone']
student_database = 'students.csv'
def add_student():
print("-------------------------")
print("Add Student Information")
print("-------------------------")
global student_fields
global student_database
# create a set of the already entered admission numbers
with open('students.csv', 'r') as file:
reader = csv.reader(file)
admissionNums = {x[0] for x in reader if x}
student_data = []
for field in student_fields:
print(field)
value = input("Enter " + field + ": ")
# while the user is entering the admission no. field and they are entering a duplicate, keep prompting them for a new/unique number
while field == 'Admission no.' and value in admissionNums:
print("Admission no. already in file, try again")
value = input("Enter " + field + ": ")
student_data.append(value)
# I also added `newline=''` so that it would stop creating an empty row when writing to the file
# You can remove this if you want to keep making a new row every time you write to it
with open(student_database,"a",encoding = "utf-8", newline='') as f:
writer = csv.writer(f)
writer.writerows([student_data])
print("Data saved successfully")
input("Press any key to continue")
# The return statement here is not necessary

How to delete given element from a python dictionary?

I am practicing python and doing an exercise where I have to ask for input of different information from patients of a hospital (name, last name, etc) this information has to be saved in a different json file. I managed to do it however I also have to make it so, with an input, I can remove/edit a specific patient from the dictionary (along with all of their info) while keeping the others intact.
I was thinking that maybe I could assign a number to every patient that's added, so this patient can be tracked with the number, however I'm not sure how to code that. I did however made a function to clear everything from the json file, but it has to remove/edit someone specific, not everyone.
My code so far is:
import json
def read_file(file_name):
obj_arch = open(file_name, 'rt', encoding='utf-8')
str_contenido = obj_arch.read()
res = json.loads(str_contenido)
obj_arch.close()
return res
def save_file(file_name, lista):
obj_arch = open(file_name, 'wt', encoding='utf-8')
str_content_to_save = json.dumps(lista)
print(str_content_to_save)
obj_arch.write(str_content_to_save)
obj_arch.close()
opcion = int(input("choose an option: 1 - read. 2 - save"))
if opcion == 1:
lista = read_file('prueba_json.json')
print("Full list:")
print(lista)
else:
lista = read_file('prueba_json.json')
while True:
print("--- PATIENT INFO ---")
Name = input("Input name: ")
Lastname = input("Input lastname: ")
DateB= input("Input date of birht: ")
repeat = input("Do you want to add more info?: ")
clean_file = input("Clean everything from the json file? (yes/no): ")
lista.append({
"Name": Name,
"Lastname": Lastname,
"Date of Birth": DateB
})
if repeat == 'no' or repeat == 'NO':
break
save_file('prueba_json.json',lista)
With this I was able to sabe the patients info in the json file, but how can I write another input like "Insert number of patient to remove or delete" to do that?
In order to clean the whole json file I've done it with this:
def clean_json():
with open('prueba_json.json', 'w') as arc:
arc.writelines(["[{}]"])
if clean_file == "yes" or clean_file == "YES":
clean_json()
Maybe I could adapt some of this to remove or delete someone instead of the whole file?

How can I delete a row from .csv file

I am a new learner in python trying to understand the logic and the solution of this problem.Exercise says to create an order app for a coffee shop .
import uuid # GET A RANDOM ID FOR THE CUSTOMER
from datetime import date # GET CURRENT DATE
from csv import DictWriter
inlist = -1
length = 0
Total_Amount = 0.0
CustomerList = []
AddressList = []
Today_Key = date.toordinal(date.today())
Today_Date = date.today()
Print_Today = Today_Date
Customers = {}
Dates = {}
FirstEmployeeAccountUsername = "coffee1"
FirstEmployeeAccountPassword = "coffeeshop1"
SecondEmployeeAccountUsername = "coffee2"
SecondEmployeeAccountPassword = "coffeeshop2"
ThirdEmployeeAccountUsername = "coffee3"
ThirdEmployeeAccountPassword = "coffeeshop3"
print("Welcome to our coffee shop!")
print("Login")
# EMPLOYEE LOGIN PROCESS STARTS
LoginEnter = True
while LoginEnter:
username = input("Username: ")
password = input("Password: ")
if username == FirstEmployeeAccountUsername and password == FirstEmployeeAccountPassword or username == SecondEmployeeAccountUsername and password == SecondEmployeeAccountPassword or username == ThirdEmployeeAccountUsername and password == ThirdEmployeeAccountPassword:
print("Login Successful")
LoginEnter = False
else:
print("Invalid Login. Try again")
# EMPLOYEE LOGIN PROCESS ENDS
# PROCESS AFTER ORDER PLACEMENT STARTS
process1 = True
process2 = True
while process1:
while process2:
Customer_Name = input("Customer's Name:")
CustomerList.append(Customer_Name)
Customers_Address = input("Customer's Address:")
AddressList.append(Customers_Address)
if Today_Key not in Dates:
Dates[Today_Key] = {}
if Customer_Name not in Dates[Today_Key]:
Dates[Today_Key][Customer_Name] = 1
else:
Dates[Today_Key][Customer_Name] += 1
if Customer_Name in Customers:
Customers[Customer_Name]['Orders'] += 1
Customers[Customer_Name]['TotalAmount'] = Total_Amount
else:
Customers[Customer_Name] = {}
Customers[Customer_Name]['Address'] = Customers_Address
Customers[Customer_Name]['ID'] = uuid.uuid1()
Customers[Customer_Name]['Orders'] = 1
Customers[Customer_Name]['TotalAmount'] = 0
print(Customer_Name, "has ordered {} time(s)".format(Customers[Customer_Name]['Orders']))
if Customers[Customer_Name]['TotalAmount'] == 0:
print("This is the first time", Customer_Name, "orders")
else:
print(Customer_Name, "has spent", Customers[Customer_Name]['TotalAmount'], "in total")
print("Current Date is: {}".format(Today_Date))
Order_Price = float(input("Total amount of order:"))
Total_Amount = Order_Price + Total_Amount
if Print_Today != Today_Date:
print("Total amount of orders today is: ", float(Total_Amount))
answer1 = input("Send another order? (Y/N)").lower()
if answer1 == "y":
process2 = True
else:
process2 = False
LengthCustomersList = len(CustomerList)
length += 1
inlist += 1
file = open('CustomerNames.txt', 'w')
file.write(str(CustomerList[0:]) + '\n') # TAKE CARE FOR DUPLICATE NAMES FROM SAME ADDRESS
file.close()
file1 = open('Orders_Per_Users.txt', 'a')
file1.write(Customer_Name + " has ordered " + str(
Customers[Customer_Name]['Orders']) + " times in total\n") # FIX DUPLICATES SAME NAME SAME ADDRESS
file1.close()
with open('data_entered.csv', 'a') as f:
csv_writer = DictWriter(f, fieldnames=['Customer Name', 'Customer Address', 'Customer ID', 'Total Orders',
'Total Amount'])
csv_writer.writeheader()
csv_writer.writerows([{'Customer Name': CustomerList[inlist], 'Customer Address': AddressList[inlist],
'Customer ID': Customers[Customer_Name]['ID'],
'Total Orders': Customers[Customer_Name]['Orders'],
'Total Amount': Customers[Customer_Name]['TotalAmount']}])
if int(length) == int(LengthCustomersList):
process1 = False
My idea is to do something like an if statement so when the same Customer ID and the same CustomerName show up in the .csv file , one of them gets deleted, so the file does not contain any duplicates like those in the screenshot above.
I am not sure we are going to eventually solve your question but I wanted to give you some inputs that you can use to fix your code.
Use of variable Today_Date and Print_Today in your code
Today_Date = date.today()
Print_Today = Today_Date
if Print_Today != Today_Date:
These two lines are set to the same value. Later on in the code, you are checking if the are not equal. I checked Print_Today and Today_Date for reassignment. None occurs. So how do you expect these two variables to have different values?
If this program runs for infinite number of days, it will still NOT change the value of these two variables. The reason is they were defined at the beginning of the program and never changed. You may want to look into it.
The use of Today_Key in Dates dictionary in your code.
Today_Key = date.toordinal(date.today())
Dates = {}
You are using Today_Key to count the number of times a customer name was entered. I don't see a point in having Today_Key as the key unless you plan to have more than one key in the dictionary. This was set at the beginning of the program and never changed. So what do you intend to do with this key? I don't think you should have that as key. Instead you should just keep track of the customer names. Also, you are not printing or writing this information into a file. Are you intending to use this later in the program? I dont see the value and it may just be using up memory space and processing time.
Use of multiple names for Username & Password.
You have created 6 variables to store username & password. In other places, you are using dictionary. So why are you not taking advantage of the dictionary here?
FirstEmployeeAccountUsername = "coffee1"
FirstEmployeeAccountPassword = "coffeeshop1"
SecondEmployeeAccountUsername = "coffee2"
SecondEmployeeAccountPassword = "coffeeshop2"
ThirdEmployeeAccountUsername = "coffee3"
ThirdEmployeeAccountPassword = "coffeeshop3"
Instead of these, can't you just define a dict variable and check for the value as shown below?
UserLogin = {"coffee1":"coffeeshop1", "coffee2": "coffeeshop2", "coffee3": "coffeeshop3"}
username = password = ''
while True:
username = input("Username: ")
password = input("Password: ")
if (username in UserLogin) and (UserLogin[username] == password):
print("Login Successful")
break
else:
print("Invalid Login. Try again")
For your customer name counter portion, try this. I dont think you are actually doing anything with the counter. If you are, this code is much simpler.
CustomerCounts = defaultdict(int)
while True:
Customer_Name = input("Customer's Name:")
CustomerList.append(Customer_Name)
Customers_Address = input("Customer's Address:")
AddressList.append(Customers_Address)
CustomerCounts[Customer_Name] += 1
similarly, try using defaultdict and reduce a lot of code you have written. In the end, there is lot of code optimization and logic corrections you can do. However, it does not solve the infinite loop situation.

How to write to a text file using iteration?

My code does not write to a file, what am I doing wrong? I am trying to program to continue to ask for products until the user does not enter a product code. I want all products to be saved in the file.
store_file = open("Database.txt", "w")
NewProduct = ""
while NewProduct != False:
contine = input("Press 1 to enter a new product press 2 to leave: ")
if contine == "1":
print("Enter your product information")
information = []
product = input("What's the product code: ")
information.append(product)
description = input("Give a description of the product: ")
information.append(description)
price = input("Enter price of product: ")
information.append(price)
information = str(information)
clean = information.replace("]","").replace("[","").replace(",","").replace("'","")
store_file.write(clean)
elif contine == "2":
NewProduct = False
else:
print("Your input is invalid")
store_file.close
I got the program working with the following adjustments. See comments for explanations:
store_file = open("Database.txt", "w")
NewProduct = ""
while NewProduct != False:
continue = raw_input("Press 1 to enter a new product press 2 to leave: ")
#Changed to raw_input because input was reading in an integer for 1 rather than a
#string like you have set up. This could be specific to my IDE
if continue == "1":
print("Enter your product information")
information = []
product = raw_input("What's the product code: ")
information.append(product)
description = raw_input("Give a description of the product: ")
information.append(description)
price = raw_input("Enter price of product: ")
information.append(price)
information = str(information)
clean = information.replace("]","").replace("[","").replace(",","").replace("'","")
store_file.write(clean + "\n")
#Added a line break at the end of each file write
elif contine == "2":
NewProduct = False
else:
print("Your input is invalid")
store_file.close() #Added parentheses to call the close function
I'm assuming the problem here is that you're using Python 2, and input isn't doing what you think it does. In Python 2, input evals the input as if it were Python source code, so if someone enters 2, it's going to return the int value 2, not "2". In Python 2, you want to use raw_input, always (eval-ing random user input not being secure/reliable).
Also, while on CPython (the reference interpreter) files tend to naturally close themselves when they go out of scope, you made an effort to close, but forgot to actually call the close method; store_file.close looks up the method without calling it, store_file.close() would actually close it. Of course, explicit close is usually the wrong approach; you should use a with statement to avoid the possibility of forgetting to close (or of an exception skipping the close). You can replace:
store_file = open("Database.txt", "w")
...
store_file.close()
with:
with open("Database.txt", "w") as store_file:
... do all your work that writes to the file indented within the with block ...
... When you dedent from the with block, the file is guaranteed to be closed ...
There are other issues though. What you're doing with:
information = str(information)
information = information.replace("]","").replace("[","").replace(",","").replace("'","")
is terrible. I'm 99% sure what you really wanted was to just join the inputs with spaces. If you switch all your input calls to raw_input (only on Python 2, on Python 3, input is like raw_input on Python 2), then your list is a list of str, and you can just join them together instead of trying to stringify the list itself, then remove all the list-y bits. You can replace both lines above with just:
information = ' '.join(information)

python: Adding to username

I am fairly new to python and I need to make a program to ask 10 questions, save the score into a file and allow someone to read the scores in from the file.
My problem: I need to check if the person who has done the quiz already has a record in the file, and if so, I need to add their score to the end of their record.
The records should look like this:
name,score,score,score,score,
etc so they can be split using commas.
I am also looking for the simplest answer, not the most efficient. Also, if you could comment the code, it would make it much easier. Here is my code so far:
import random
import math
import operator as op
import sys
import re
def test():
num1 = random.randint(1, 10)
num2 = random.randint(1, num1)
ops = {
'+': op.add,
'-': op.sub,
'*': op.mul,
}
keys = list(ops.keys())
rand_key = random.choice(keys)
operation = ops[rand_key]
correct_result = operation(num1, num2)
print ("What is {} {} {}?".format(num1, rand_key, num2))
while True:
try:
user_answer = int(input("Your answer: "))
except ValueError:
print("Only enter numbers!")
continue
else:
break
if user_answer != correct_result:
print ("Incorrect. The right answer is {}".format(correct_result))
return False
else:
print("Correct!")
return True
print("1. Are you a student?")
print("2. Are you a teacher?")
print("3. Exit")
while True:
try:
status = int(input("Please select an option:"))
except ValueError:
print("Please enter a number!")
else:
if status not in {1,2,3}:
print("Please enter a number in {1,2,3}!")
else:
break
if status == 1:
username=input("What is your name?")
while not re.match("^[A-Za-z ]*$", username) or username=="":
username=input(str("Please enter a valid name (it must not contain numbers or symbols)."))
print ("Hi {}! Wellcome to the Arithmetic quiz...".format(username))
while True:
try:
users_class = int(input("Which class are you in? (1,2 or 3)"))
except ValueError:
print("Please enter a number!")
else:
if users_class not in {1,2,3}:
print("Please enter a number in {1,2,3}!")
else:
break
correct_answers = 0
num_questions = 10
for i in range(num_questions):
if test():
correct_answers +=1
print("{}: You got {}/{} {} correct.".format(username, correct_answers, num_questions,
'question' if (correct_answers==1) else 'questions'))
if users_class == 1:
class1 = open("Class1.txt", "a+")
newRecord = username+ "," + str(correct_answers) + "," + "\n"
class1.write(newRecord)
class1.close()
elif users_class == 2:
class2 = open("Class2.txt", "a+")
newRecord = username+ "," + str(correct_answers) + "," + "\n"
class2.write(newRecord)
class2.close()
elif users_class == 3:
class3 = open("Class3.txt", "a+")
newRecord = username+ "," + str(correct_answers) + "," + "\n"
class3.write(newRecord)
class3.close()
else:
print("Sorry, we can not save your data as the class you entered is not valid.")
EDIT:
Add this function before your "test" function:
def writeUserScore(file, name, score):
with open (file, "r") as myfile:
s = myfile.read()
rows = s.split("\n")
data = {}
for row in rows:
tmp = row.split(",")
if len(tmp) >= 2: data[tmp[0]] = tmp[1:]
if name not in data:
data[name] = []
data[name].append(str(score))
output = ""
for name in data:
output = output + name + "," + ",".join(data[name]) + "\n"
handle = open(file, "w+")
handle.write(output)
handle.close()
After that, where you have "if users_class == 1:" do this:
writeUserScore("Class1.txt", username, str(correct_answers))
Do the same for the other two else ifs.
Let me know what you think!
Try using a dictionary to hold the existing file data.
Read the file in a variable called "str" for example. And then do something like this:
rows = str.split("\n")
data1 = {}
for row in rows:
tmp = row.split(",")
data1[tmp[0]] = tmp[1:]
When you have a new score you should then do:
if username not in data1:
data1[username] = []
data1[username] = str(correct_answers)
And to save the data back to the file:
output = ""
for name in data1:
output = outupt + name + "," + ",".join(data1[name]) | "\n"
And save the contents of "output" to the file.
PS: If you are not bound by the file format you can use a JSON file. I can tell you more about this if you wish.
Hope that helps,
Alex
First, define these functions:
from collections import defaultdict
def read_scores(users_class):
"""
If the score file for users_class does not exist, return an empty
defaultdict(list). If the score file does exist, read it in and return
it as a defaultdict(list). The keys of the dict are the user names,
and the values are lists of ints (the scores for each user)
"""
assert 0 <= users_class <= 3
result = defaultdict(list)
try:
lines =open("Class%d.txt"%users_class,'r').readlines()
except IOError:
return result
for line in lines:
# this line requires python3
user, *scores = line.strip().split(',')
# if you need to use python2, replace the above line
# with these two lines:
# line = line.strip().split(',')
# user, scores = line[0], line[1:]
result[user] = [int(s) for s in scores]
return result
def write_scores(users_class, all_scores):
"""
Write user scores to the appropriate file.
users_class is the class number, all scores is a dict kind of dict
returned by read_scores.
"""
f = open("Class%d.txt"%users_class,'w')
for user, scores in all_scores.items():
f.write("%s,%s\n"%(user, ','.join([str(s) for s in scores])))
def update_user_score(users_class, user_name, new_score):
"""
Update the appropriate score file for users_class.
Append new_score to user_name's existing scores. If the user has
no scores, a new record is created for them.
"""
scores = read_scores(users_class)
scores[user_name].append(new_score)
write_scores(users_class, scores)
Now, in the last portion of your code (where you actually write the scores out) becomes much simpler. Here's an example of writing some scores:
update_user_score(1, 'phil', 7)
update_user_score(1, 'phil', 6)
update_user_score(1, 'alice', 6)
update_user_score(1, 'phil', 9)
there will be two lines in Class1.txt:
phil,7,6,9
alice,6
We read the whole file into a dict (actually a defaultdict(list)),
and overwrite that same file with an updated dict. By using defaultdict(list), we don't have to worry about distinguishing between updating and adding a record.
Note also that we don't need separate if/elif cases to read/write the files. "Scores%d.txt"%users_class gives us the name of the file.

Categories