im trying to create a database by using dictionaries. i convert the dictionary into a string once ive finished adding and deleting things from it but when i want to save the string, i would like the the keys to be on a new line from each other.
here is my code so far:
print('|-----Welcome to the Address Book-------|')
print('|----------------------------------------|')
print('|Please choice from the following:-------|')
print('|----------1: Find Contact------------|')
print('|----------2: Add Contact------------|')
print('|----------3: Delete Contact------------|')
print('|----------4: Quit Address Book----------|')
choice = [1, 2, 3, 4, 5]
document = open('addresses.txt', 'r+')
address = {}
for line in document:
if line.strip():
key, value = line.split(None, 1)
address[key] = value.split()
document.close()
open('addresses.txt', 'w')
while 1:
answer = 0
while answer not in choice:
try:
answer = int(input("Enter here: "))
except ValueError:
0
if answer == 1:
x = input('Enter his/her name: ')
if x in address:
print("This is their address: ", address[x])
else:
print('Contact does not exist!')
if answer == 2:
x = (input('Enter new contact: '))
x = x.replace(" ", "_")
if x in address:
while True:
z = str(input('Contact '+x+' with address: '+str(address[x]) + ' already existed, do you want to override?(Yes/No)'))
if z == 'yes':
b = input('Enter Address: ')
c = input('Enter postcode: ')
del address[x]
break
elif z == 'no':
break
else:
print('Please choose yes or no')
else:
b = input('Enter Address: ')
c = input('Enter postcode: ')
b = b.replace(" ", "_")
c = c.replace(" ", "_")
address[x] = b, c
if answer == 3:
z = input('Enter whom you would like to delete: ')
if z in address:
del address[z]
else:
print('Contact does not exist!')
if answer == 4:
a = "{}':(),[]"
ok = str(address)
for char in a:
ok = ok.replace(char, "")
document = open('addresses.txt', 'r+')
document.write(ok + '\n')
document.close()
break
when saving to file, i would like to save each key and its info like this:
>Bob address postcode
>Sam address postcode
but instead it is saved like this:
>Bob address postcode Sam address postcode
When writing a dictionary to file, do the following:
with open('/file/path', 'w') as f:
for k, v in d.items():
f.write(k + v + "\n")
This assumes a few things:
You want to overwrite the file, not append; if you do, switch 'w' to 'a'
All the key and value items are str
I don't like using 'r+'. You should open(filename, "r") when you want to read from a file and open(filename, "w") when you want to read your file. In my opinion, it's way easier because while using 'r+', you have to think about where the seek is (the blinking cursor that you see while writing/editing somewhere).
For that you'll need something like:
file=open(filename,"r+")
file.seek(0)
file.write("something" + "\n")
Well, I don't really use the "r+" method very much so I can't explain anymore. I suggest that you read more about it in the docs.
If you print str(address) to your screen, you will understand why this happens. The str command converts everything (i.e. keys and values) to a concatanated string and that will be stored in your document file.
Instead you should save the items of your address book one by one, iterating over all persons.
ok = ""
for person in address:
ok += person + " " + address[person] + "\n"
with open('addresses.txt', 'w') as file_out:
file_out.write(ok)
Related
I don't expect any coding answers, more just guidance. For my project I have to date-mine apple stock prices from a csv-file and implement it in my code. I provided a sample output below.
https://imgur.com/rPOPN1I
Right now, I am not getting any error messages but my code is not posting the columns requested from the csv.file. Are my definitions at fault or am I missing something else?
# Project No.: 5
# Author: burntchickennuget
# Description: making definitions, reading from a .csv file, validating input, data-mining,
f_list = list()
file_object = ()
my_tot = dict()
new_list = list()
def get_input_descriptor():
while True:
filename = input("Enter a file name: ")
if filename == 'table.csv':
with open(filename, "r") as infile:
infile.readlines()[1:]
# for line in lines:
# print(line.rstrip())
break
else:
print("Bad file name, try again")
return filename
def get_data_list(file_object, column_number):
dict = {}
for val in file_object:
date = val.split(",")[0]
data = float(val.split(",")[column_number])
dict[date] = data
return dict.items()
def average_data(new_list):
for date, price in new_list:
my_tot[date] = my_tot.get(date, 0) + float(price)
my_times[date] = my_times.get(date, 0) + 1
for key in my_tot:
f_list.append((float(my_tot[key] / my_times[key]), key))
def main():
get_input_descriptor()
column_number = int(input("Which column: "))
date_list = get_data_list(file_object, column_number)
final_list = average_data(date_list)
x = sorted(f_list)
print('Lowest 6:')
for tup in x[:6]:
print
tup[0], tup[1]
print('Highest 6:')
x = sorted(f_list, reverse=True)
for tup in x[:6]:
print
tup[0], tup[1]
while 1:
flag = input("do you want to continue? ")
if flag == '' or not flag[0].lower() in ['y', 'n']:
print("Please answer with a yes or no")
else:
break
if flag[0].lower() == 'y':
column = input("Which column: ")
print(column)
if flag[0].lower() == 'n':
print("Bye!")
if __name__ == "__main__":
main()
What can I try next?
Take a look around your get_input_descriptor method.
What are you returning from the method?
Where is the returned information being stored in the main method (is it being stored at all?)
What are you doing with the lines that you read from the file?
What is the file_object you are passing into get_data_list
My main advice would be to add print everywhere for debugging. See what it stored in your variables at different points in the program and see where a variable doesn't contain what you think it should
I have made three inputs (firstname, surname and age) and put them into a file. The last part is to use this information to print out the inputs of someone if the age is above 18. I have tried using a dictionary but I did it wrong somehow. Can I use a list or a file? What can I do in order to use an if statement using that age to find out whether the details should be printed or not. Sample below.
def details():
c = input('Press 1 to enter details, press 2 to browse users or press 3 to check age')
if c == '1':
firstname = input('Please enter your firstname')
surname = input('Please enter your surname')
age = input('Please enter your age')
myfile=open('details.txt', 'at')
myfile.write(firstname + '\n')
myfile.write(surname + '\n')
myfile.write(age + '\n')
myfile.close()
detail2 = {'Fname': firstname, 'Sname': surname, 'Age': age}
details()
elif c == '2':
detail2 = {'Fname': firstname, 'Sname': surname, 'Age': age}
read()
elif c == '3':
detail2 = {'Fname': firstname, 'Sname': surname, 'Age': age}
read18()
else:
details()
def read():
myfile=open('details.txt', 'rt')
x = myfile.read()
print(x)
def read18():
for item in detail2:
if Age> 18:
print('Over 18')
elif Age< 18:
print('Under 18')
"""I need to know what to do so this will print the details. Just using over or under 18 as a starting point"""
details()
You're trying to use the local variable detail2 within read18() where it is out of scope. You might want to open the file and read in the existing details to evaluate your 'if' loop conditions.
Ok, I think your code could use some improvements.
If you keep calling details(), you will eventualy hit the limit of the max recursions allowed. For that you can just put your code into while True: cycle and call break to break it
input() returns a string, but age is usually a number (integer), so it is good practise to convert your string into integer using int(). You can use it directly on the input() -> age = int(input('Please enter your age: '))
Since you have a list of users, you should use list to keep track of them. If every user has firstname, surname and age, you call use a dictionary to keep data of every user and then add this dictionay to your list of all users
For writing/reading files, Python has an inbuilt with statement, that will take care of closing the file for you
If you want to quickly save a list/dictionary, you can use JSON
If you will use all of these advices, you can get code similar to this:
import json
FILE_SAVEFILE = "details.json"
list_persons = [] # list with user's data
def data_save():
"""
Saves user's data into FILE_SAVEFILE
"""
with open(FILE_SAVEFILE, 'wt') as f:
json.dump(list_persons, f)
def data_load():
"""
Loads data into list_persons from FILE_SAVEFILE
"""
global list_persons
with open(FILE_SAVEFILE, 'rt') as f:
list_persons = json.load(f)
while True:
c = input('Press 1 to enter details, press 2 to browse users or press 3 to check age: ')
if c == "1":
new_person_data = {
"firstname": input('Please enter your firstname: '),
"surname": input('Please enter your surname: '),
"age": int(input('Please enter your age: ')),
}
list_persons.append(new_person_data)
data_save()
continue
if c == "2":
data_load()
for dict_user in list_persons:
print('Firstname: ' + dict_user["firstname"])
print('Surname: ' + dict_user["surname"])
print('Age: ' + str(dict_user["age"]))
continue
if c == "3":
for dict_user in list_persons:
str_agestr = " is over 18" if dict_user["age"] > 18 else " is under 18"
print(dict_user["firstname"] + " " + dict_user["surname"] + str_agestr)
continue
There are many improvements that could be made to your code, indeed the answer from E. Aho uses a few of them but they may be a tad confusing if you are new to python.
Mildly adapting your code and adding a few comments:
def details():
c = input('Press 1 to enter details, press 2 to browse users or press 3 to check age: ')
if c == '1':
firstname = input('Please enter your firstname: ')
surname = input('Please enter your surname: ')
age = input('Please enter your age: ')
myfile=open('details.txt', 'at')
# write data as a single record
myfile.write(firstname + ',' + surname + ',' + age + '\n')
myfile.close()
details()
elif c == '2':
read()
elif c == '3':
read18()
else:
details()
def read():
myfile=open('details.txt', 'r')
# read file line by line
x = myfile.readlines()
for item in x:
print (item.strip()) #Strip newline
myfile.close()
def read18():
myfile=open('details.txt', 'r')
x = myfile.readlines()
for item in x:
# split each line into component parts, splitting on comma separator and strip newline
firstname,surname,age = item.strip().split(',')
detail2 = {'Fname': firstname, 'Sname': surname, 'Age': int(age)}
if detail2['Age'] > 17:
print('Over 18 via Dict')
else:
print('Under 18 via Dict')
# or dispense with the dictionary
if int(age) > 17:
print(firstname,surname,'at',age,'is 18 or over')
else:
print(firstname,surname,'at',age,'is under 18')
myfile.close()
"""I need to know what to do so this will print the details. Just using over or under 18 as a starting point"""
details()
This is my code for entering student details. Once the user has entered the details and inputs yes, the details are exported to StudentDetails.csv (Microsoft Excel) where it should go below the headers but ends up going somewhere else.
def EnterStudent():
uchoice_loop = False
ask_loop = False
while uchoice_loop == False:
surname = raw_input("What is the surname?")
forename = raw_input("What is the forname?")
date = raw_input("What is the date of birth? {Put it in the format D/M/Y}")
home_address = raw_input("What is the home address?")
home_phone = raw_input("What is the home phone?")
gender = raw_input("What is their gender?")
tutor_group = raw_input("What is their tutor group?")
email = (forename.lower() + surname.lower() + ("#school.com"))
print(surname+" "+forename+" "+date+" "+home_address+" "+home_phone+" "+gender+" "+tutor_group+" "+email)
ask = raw_input("Are these details correct?"+"\n"+"Press b to go back, or yes to add entered data on your student.").lower()
if ask == "yes":
f = open("StudentDetails.csv","rt")
lines = f.readlines()
f.close()
lines.append(surname+","+forename+","+date+","+home_address+","+home_phone+","+gender+","+tutor_group+","+email+"\n")
f = open("StudentDetails.csv", "w")
f.writelines(lines)
f.close()
uchoice_loop = True
printMenu()
elif ask == "b":
uchoice_loop = False
else:
print("Plesase enter 'b' to go back or 'yes' to continue")
This is my csv file.
enter image description here
There's a few things you can do to make this work. You dont need to open the StudentDetails.csv and read all of the lines. Instead you can make a lines string variable and append it the the StudentDetails.csv like in the example below
#f = open("StudentDetails.csv","rt")
#lines = f.readlines()
#f.close()
lines = surname+","+forename+","+date+","+home_address+","+home_phone+","+gender+","+tutor_group+","+email
# the "a" appends the lines variable to the csv file instead of writing over it like the "w" does
f = open("StudentDetails.csv", "a")
f.writelines(lines)
f.close()
uchoice_loop = True
Eric is right in that you best open the file in append-mode (see https://docs.python.org/3.6/library/functions.html#open) instead of cumbersomely reading and rewriting your file over and over again.
I want to add to this that you probably will enjoy using the standard library's csv module as well (see https://docs.python.org/3.6/library/csv.html), especially if you want to use your output file in Excel afterwards.
Then, I'd also advise you to not use variables for while loop conditionals, but learning about the continue and break statements. If you want to break out of the outer loop in the example, research try, except and raise.
Finally, unless you really have to use Python 2.x, I recommend you to start using Python 3. The code below is written in Python 3 and will not work in Python 2.
#!/usr/bin/env python
# -*- codig: utf-8 -*-
import csv
def enterStudent():
b_or_yes = 'Press b to go back, or yes to save the entered data: '
while True:
surname = input('What is the surname? ')
forename = input('What is the first name? ')
date = input(
'What is the date of birth? {Put it in the format D/M/Y} ')
home_address = input('What is the home address? ')
home_phone = input('What is the home phone? ')
gender = input('What is the gender? ')
tutor_group = input('What is the tutor group? ')
email = forename.lower() + surname.lower() + '#school.com'
studentdata = (
surname,
forename,
date,
home_address,
home_phone,
gender,
tutor_group,
email)
print(studentdata)
while True:
reply = input('Are these details correct?\n' + b_or_yes).lower()
if reply == 'yes':
with open('studentdetails.csv', 'a', newline='') as csvfile:
studentwriter = csv.writer(csvfile, dialect='excel')
studentwriter.writerow(studentdata)
break
elif reply == 'b':
break
if __name__ == '__main__':
enterStudent()
Best of luck!
I am having trouble getting past writing user input to my list what am I doing wrong here? This is an address book program that I am writing, the assignment is to create parallel lists that will store user input data in the appropriate list using a for or while loop. The program must also have a search function which you can see is at the bottom of the code. My issue that I am having is getting the program to store data within my lists. Unfortunately lists are something that give me lots of trouble I just cant seem to wrap my head around it no matter how much research I have done. The issue im running into is the append.data function when trying to write lastname and firstname to my list of names. what am I doing wrong?
#NICHOLAS SHAFFER
#5/11/2016
#MYADDRESSBOOK
def menu():
index = 0
size = 100
count = 0
answer = raw_input("Are You Creating An Entry [Press 1] \nOr Are You Searching An Entry [Press 2] ")
if answer == "1" :
print ("This is where we create")
append_data(index, size, count)
elif answer == "2" :
print ("this is where we search")
search_database()
name[size]
phone[size]
addresss[size]
# IF we are creating
def append_data(index, size, count):
# collect information
for index in range(0, 100):
optOut = 'no'
while optOut == 'no':
lastname[count] = raw_input("What is the persons last name? ")
firstname[count] = raw_input("What is the persons first name? ")
phone[count] = raw_input("What id the persons phone number? ")
address[count] = raw_input("What is the persons address? ")
count = count + 1
print 'Would you like to create another entry?'
optOut = raw_input('Would you like to create another entry? [ENTER YES OR NO]:')
if optOut == 'yes':
menu()
#create string to print to file
#print temp1
#print (firstname + " " + lastname + ", " + phone + ", " + email + ", " + address)
print listName[index]
print listPhone[index]
print listAddress[index]
print 'file has been added to your addressbook sucessfuly'
menu()
# SEARCHING FOR A RECORD
def search_database():
searchcriteria = raw_input("Enter your search Criteria, name? phone, or address etc ")
print searchcriteria
if searchcriteria == "name":
temp1 = open(listName[lastname, firstname],"r")
print temp1
if searchcriteria == "phone":
temp1 = open(listPhone[0], "r")
print temp1
if searchcriteria == "address":
temp1 = open(listAddress[0], "r")
print temp1
else:
print "sorry you must enter a valid responce, try again."
menu()
for line in temp1:
if searchcriteria in line:
print line
errorMessage()
# USER DID NOT PICK CREATE OR SEARCH
def errorMessage():
print ("Incorrect Answer")
exit()
menu()
Your error message says it all:
line 34, in append_data lastname[count]... NameError: global name 'lastname' is not defined
You'll get this same error if you type lastname[4] in any interpreter -- you've simply never defined a list called lastname, so you can't access items in it. In the short term, you can fix this with a line
lastname = list()
You're going to end up with more troubles though; lastname won't be accessible outside the function where you define it, neither will listName. I'd probably approach that by writing them into a data file/database, or maybe creating a quick class whose members will all have access to self.lastname.
My final append for lists thanks again Noumenon
def append_data(index, size, count):
lastnames = list()
if count < size -1:
lastname = raw_input("What is the persons last name? ")
lastnames.append(lastname)
print lastnames
firstnames = list()
if count < size - 1:
firstname = raw_input("What is the persons first name? ")
firstnames.append(firstname)
print firstnames
phones = list()
if count < size - 1:
phone = raw_input("What id the persons phone number? ")
phones.append(phone)
print phones
addresss = list()
if count < size - 1:
address = raw_input("What is the persons address? ")
addresss.append(address)
print addresss
listName = (lastnames, firstnames)
addressbook =(listName, phones, addresss)
index = index + 1
count = count + 1
print addressbook
optOut = raw_input('Would you like to create another entry? [Enter YES or NO]: ')
if optOut == 'YES':
menu()
print 'file has been added to your addressbook sucessfuly'
menu()
I am trying to print the variable 'Number' But it come up with a error.
'TypeError: list indices must be integers, not tuple'
I dont understand? What is a tuple and how could i fix this problem?
How do i assign a line number in a text file to a variable?
def CheckDatabase():
print ("====Check Database===== \nA)Would you like to check details? \nB)Check if they are a member?")
TC = input(": ")
if TC == "A" or TC == "a":
NameDetail = input ("Please enter the name you would like to check the details of.\nThis will only work if they are a member\n: ")
with open('Name.txt') as ND:
for number, line in enumerate(ND, 1):
if (str(NameDetail)) in line:
Number = number, line in enumerate(ND, 1)
print ("\nName = ", NameDetail)
A = open("Address.txt", "r")
AData =[line.rstrip() for line in A.readlines()]
print ("Address = ",(AData[Number]))
HN = open("Home Number.txt", "r")
HNData =[line.rstrip() for line in HN.readlines()]
print ("Home Number = ",(HNData[Number]))
MN = open("Mobile Number.txt", "r")
MNData =[line.rstrip() for line in MN.readlines()]
print ("Mobile Number = ",(MNData[Number]))
EAS = open("Email Address.txt", "r")
EAData =[line.rstrip() for line in EAS.readlines()]
print ("Email Address = ",(EAData[Number]))
MDND = open("Email Address.txt", "r")
MDNData =[line.rstrip() for line in MDND.readlines()]
print ("Medical/Dietry Needs = ",(MDNData[Number]))
else:
print ("Person not found!")
EDIT:
import time
def AddToDatabase():
print ("\nYou are adding to the Database. \nA)Continue \nB)Go Back")
ATD = input(": ")
if ATD == "A" or ATD == "a":
Name = input("\nEnter Name of Member [First Name and Surname]: ")
with open("Name.txt", "a") as N:
N.write("\n{}".format(Name))
time.sleep(1)
print ("\nAdding...")
time.sleep(1)
print ("\nEnter Address of "+Name+" all on one line")
print ("In format [Include Commas]")
print ("\nRoad name with house number [e.g. 1 Morgan Way], Borough [e.g Harrow], City [e.g London], Postcode [e.g. HA5 2EF]")
Address = input("\n: ")
with open("Address.txt", "a") as A:
A.write("\n{}".format(Address))
time.sleep(1)
print ("\nAdding...")
time.sleep(1)
Home_Number = input("\nEnter Home Number of "+Name+": ")
with open("Home Number.txt", "a") as HN:
HN.write("\n{}".format(Home_Number))
time.sleep(1)
print ("\nAdding...")
time.sleep(1)
Mobile_Number = input ("\nEnter Mobile Number of "+Name+": ")
with open("Mobile Number.txt", "a") as MN:
MN.write("\n{}".format(Mobile_Number))
time.sleep(1)
print ("\nAdding...")
time.sleep(1)
Email_Address = input ("\nEnter Email Address of "+Name+": ")
with open("Email Address.txt", "a") as EA:
EA.write("\n{}".format(Email_Address))
time.sleep(1)
print ("\nAdding...")
time.sleep(1)
Dietry_Needs = input("\nEnter Medical/Dietry Needs of "+Name+": ")
with open("Medical Dietry Needs.txt", "a") as MDN:
MDN.write("\n{}".format(Dietry_Needs))
time.sleep(1)
print ("\nAdding...")
time.sleep(1)
print ("All information for "+Name+" has been added. Redirecting Back To Main...")
time.sleep(5)
Main()
elif ATD == "B" or ATD == "b":
Main()
def CheckDatabase():
print ("====Check Database===== \nA)Would you like to check details? \nB)Check if they are a member?")
TC = input(": ")
if TC == "A" or TC == "a":
NameDetail = input ("Please enter the name you would like to check the details of.\nThis will only work if they are a member\n: ")
with open('Name.txt') as ND:
for number, line in enumerate(ND, 1):
if (str(NameDetail)) in line:
Number, junk = number, line in enumerate(ND, 1)
print ("\nName = ", NameDetail)
A = open("Address.txt", "r")
AData =[line.rstrip() for line in A.readlines()]
print ("Address = ",(AData[number]))
HN = open("Home Number.txt", "r")
HNData =[line.rstrip() for line in HN.readlines()]
print ("Home Number = ",(HNData[Number]))
MN = open("Mobile Number.txt", "r")
MNData =[line.rstrip() for line in MN.readlines()]
print ("Mobile Number = ",(MNData[Number]))
EAS = open("Email Address.txt", "r")
EAData =[line.rstrip() for line in EAS.readlines()]
print ("Email Address = ",(EAData[Number]))
MDND = open("Email Address.txt", "r")
MDNData =[line.rstrip() for line in MDND.readlines()]
print ("Medical/Dietry Needs = ",(MDNData[Number]))
else:
print ("Person not found!")
elif TC == "B" or TC == "b":
NameChoice = input("Enter persons name: ")
with open('Name.txt') as NAME:
for number, line in enumerate(NAME, 1):
if (str(NameChoice)) in line:
print (NameChoice)
print ("is a member")
else:
print ("Not a member!")
def Main():
print ("\nSVA of UK Database")
while True:
print ("\nA)Check Database \nB)Add to Database \nC)Exit Program")
choice = input(": ")
if choice == "A" or choice == "a":
CheckDatabase()
elif choice == "B" or choice == "b":
AddToDatabase()
elif choice == "C" or choice == "c":
break
else:
print ("Invalid Input")
Main()
Main()
EDIT 2:
Name.txt :
Sagar Bharadia
Address.txt
8 John Road
Home Number.txt
02089563524
Mobile Number.txt
02045745854
Medical Dietry Needs.txt
None
EDIT 3:
SVA of UK Database
A)Check Database
B)Add to Database
C)Exit Program
: A
====Check Database=====
A)Would you like to check details?
B)Check if they are a member?
: A
Please enter the name you would like to check the details of.
This will only work if they are a member
: Sagar Bharadia
Name = Sagar Bharadia
1
Traceback (most recent call last):
File "H:\SVA UK PROGRAM\SVA of UK.py", line 126, in <module>
Main()
File "H:\SVA UK PROGRAM\SVA of UK.py", line 114, in Main
CheckDatabase()
File "H:\SVA UK PROGRAM\SVA of UK.py", line 74, in CheckDatabase
print ("Address = ",(AData[Number]))
IndexError: list index out of range
>>>
You define Number as a tuple when you do Number = number, line in enumerate(ND, 1). You already created number, line in enumerate(ND, 1) with your for loop anyway. Why not just use that? i.e. AData[number].
Just using an example, this is what essentially what you are setting Number to:
>>> for x, y in enumerate([1,2,3], 1):
print x, y in enumerate([1,2,3], 1)
1 False
2 False
3 False
It is a tuple containing the number from your for loop, and the value of line in enumerate(ND, 1) (a boolean expression, either it's in there or it's not).
You also have several other problems:
You start number at 1 instead of 0 by providing the 1 to enumerate. In python, list indices start at 0. So if the length of a list is 1 then sub-indexing at [1] is actually out of bounds. You should be doing enumerate(ND) instead to start at 0.
You need to .close() your files that you open(), or use with/as like you do with your first file.
You are opening Email Address.txt twice... did you mean to do that?
In this line:
Number = number, line in enumerate(ND, 1)
You are assigning two values to Number -- this produces a tuple.
You could do something like this:
Number, junk = number, line in enumerate(ND, 1)
This would result in Number being a single value, no longer a tuple.
Tuples are a kind of a "list". See doc on:
http://docs.python.org/release/1.5.1p1/tut/tuples.html
You are probably assigning 2 or more values for the var Number