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()
Related
dictionary = {}
name = input("Name: ")
while name: #while the name is not blank
age = input("Age: ")
dictionary[name] = age
name = input("Name: ")
print("Thank you, bye!")
f = open("1ex.txt","w")
f.write( str(dictionary) )
f.close()
So I have this code, it does what I want, but I cant seems to figure it out how can I write the file, so that it would have not a dictionary, but smth like this:
Jane, 25
Jim, 24
I tried putting everything into a list, but it doesn't work out for me.
Try this:
dictionary = {}
name = input("Name: ")
while name: #while the name is not blank
age = input("Age: ")
dictionary[name] = age
name = input("Name: ")
print("Thank you, bye!")
# Open the file
with open("1ex.txt","w") as f:
# For each key/value pair in the dictionary:
for k, v in dictionary.items():
# Write the required string and a newline character
f.write(f"{k}, {v}\n")
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)
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 need to create a program that saves people's information e.g. their name in a text file depending on the first letter of their surname so if their surname starts with a K it goes into MyFile1.
I need it to loop like I have done because it's an unknown number of people however I want each person to be written in a different line in the text file is there a way to do this.
The code at the bottom puts each separate information into a new line and I don't want that I want each different person to be in a new line.
MyFile1 = open("AL.txt", "wt")
MyFile2 = open("MZ.txt", "wt")
myListAL = ([])
myListMZ = ([])
while 1:
SurName = input("Enter your surname name.")
if SurName[0] in ("A","B","C","D","E","F","G","H","I","J","K","L"):
Title = input("Enter your title.")
myListAL.append(Title);
FirstName = input("Enter your first name.")
myListAL.append(FirstName);
myListAL.append(SurName);
Birthday = input("Enter birthdate in mm/dd/yyyy format:")
myListAL.append(Birthday);
Email = input("Enter your email.")
myListAL.append(Email);
PhoneNumber = input("Enter your phone number.")
myListAL.append(PhoneNumber);
for item in myListAL:
MyFile1.write(item+"\n")
elif SurName[0] in ("M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"):
Title = input("Enter your title.")
myListMZ.insert(Title);
FirstName = input("Enter your first name.")
myListMZ.append(FirstName);
myListMZ.append(SurName);
Birthday = input("Enter birthdate in mm/dd/yyyy format:")
myListMZ.append(Birthday);
Email = input("Enter your email.")
myListMZ.append(Email);
PhoneNumber = input("Enter your phone number.")
myListMZ.append(PhoneNumber);
line.write("\n")
for item in myListMZ:
MyFile2.write(line)
elif SurName == "1":
break
MyFile1.close()
MyFile2.close()
You are looking for join.
When you have a list of items you can join them in a single string with.
l = ['a', 'b', 'c']
print(''.join(l))
produces
abc
You can not only use the empty string but also another string which will be used as separator
l = ['a', 'b', 'c']
print(', '.join(l))
which now produces
a, b, c
In your examples (for example the first write)
MyFile1.write(','.join(MyListAL) + '\n')
If you happen to have something in the list which is not a string:
MyFile1.write(','.join(str(x) for x in MyListAL) + '\n')
(you can also use map, but a generator expression suffices)
Edit: adding the map:
MyFile1.write(','.join(map(str, MyListAL)) + '\n')
In your case I would rather use a list of dictionaries, where a person with all its infos is a dictionary. Then you can convert it to a JSON string, which is a standard format for representing data. (Otherwise you need to define your own format, with delimiters between the items.)
So something like this:
import json # at the top of your script
# I would create a function to get the information from a person:
def get_person_input():
person = {}
person["surname"] = input("Surname: ")
person["title"] = input("Title: ")
person["email"] = input("Email: ")
# TODO: do whatever you still want
return person
# Later in the script when you want to write it to a file:
new_line = json.dumps( person )
myfile.write( new_line + "\n" )
Parsing a json is also very easy after all:
person = json.loads(current_line) # you can handle exception if you want to make sure, that it is a JSON format
You can use in your code for the decision in which array it should be written something like this:
SurName = input("Enter your surname name.")
if SurName[0] <= 'L':
...
else:
...
This will make your script more clear and robust.