Text file to dictionary then to print information in python - python

Hey everyone just have an issue with a text file and putting it into a dictionary.
So my code first starts off by gathering data from a website and writes it to a text file. From there I reopen the file and make it into a dictionary to transfer the data from the text to the dictionary. In the while loop, I am getting the error of
key,value = line.split()
ValueError: too many values to unpack (expected 2)
Which I'm not sure why if I'm using the wrong method to write the text file data to the new place in the program of "countryName"
def main():
import requests
webFile = "https://www.cia.gov/library/publications/the-world-factbook/rankorder/rawdata_2004.txt"
data = requests.get(webFile) #connects to the file and gest a response object
with open("capital.txt",'wb') as f:
f.write(data.content) #write the data out to a file – wb used since thecontent from the response object is returned as abinary object.
f.close()
infile = open('capital.txt', 'r')
line = infile.readline()
countryName = {}
while line != "":
key,value = line.split()
countryName[key] = value
line = infile.readline()
infile.close()
userInput = input("Enter a country name: ")
for i in countryName:
while(userInput != 'stop'):
print("The per capita income in",countryName[key], "is",countryName[value])
userInput = input("Enter a country name: ")
main()
while line != "":
key,value = line.split()
countryName[key] = value
line = infile.readline()
infile.close()
This is where my issue pops up.
I am trying to have the text file information be put into a dictionary.
Once done I want to iterate through the dictionary, and have the user enter a country name. Then in response, the program finds the country name and returns the name of the country and the capital income as well.
So if "United States" is inputed the output would be "The per capita income in the United States is $54000" That as an example to show what im doing.
The key being the country name and the value being the income.
countryName = {}
with open('capital.txt','r') as infile:
for line in infile:
num,key,value = line.split()
countryName[key] = value
num,key,value = infile.readline().split()
#print(line)
print(countryName)

The issue is that the lines return three values each: The line number, the country, and the per-capita income:
fh.readline().split()
['2', 'Qatar', '$124,500']
To fix that, you can capture that third value in a throwaway variable:
n, key, val = fh.readline().split()
However, there's a different problem, what if your country name has spaces in it?
['190', 'Micronesia,', 'Federated', 'States', 'of', '$3,400']
You can use the *arg syntax to capture any number of arguments in a variable:
myline = ['190', 'Micronesia,', 'Federated', 'States', 'of', '$3,400']
num, *key, value = myline
# key is now ['Micronesia,', 'Federated', 'States', 'of']
You can then use join to create a single string
key = ' '.join(key)
# 'Micronesia, Federated States of'
Furthermore, it's important to keep your conventions consistent in your program. You use the with context handler to open and close an earlier file, that's a good practice, so keep it with the other file as well. Also, you can iterate over the file-handle directly like so:
with open('capital.txt', 'r') as infile:
for line in infile: # no need to check the line contents or call readline
num, *key, value = line.split()
key = ' '.join(key)
# No need to close your file at the end either
Last, your print statement will raise a KeyError:
print("The per capita income in",countryName[key], "is",countryName[value])
You've already stored value at countryName[key], so the lookup is only against key, rather than value:
# key is already a string representing the country name
# countrName[key] is the value associated with that key
print("The per capita income in", key , "is", countryName[key])

Related

How to remember something from a loop after the loop is done?

I am trying to read a file and then have it print specific integers (Retail Prices) that I put into a dictionary from that file. This part I got. But when I try and print the Retail Prices outside of the loop, it cannot find them. If I include it within the loop, the file only reads one line! Help!!
while line != '':
line = fh.readline()
line = line.replace(',', '')
line = line.replace('"', '')
line = line.replace(';', ',')
linesplit = line.split(',')
linesplit = line.split(',')
dictionary = dict(zip(headerItems, linesplit))
RetailPrice = dictionary.get('retailprice')
print(RetailPrice)
RetailPrice = Retail_Prices
z = z + 1
if z == 4:
price = 'goodbye'
price = input('Enter a valid Retail Price to find all products below that price, or type anything else to exit: ')
print(Retail_Prices)
You can have the keyword dictionary outside the while loop set to None or empty dict and then over-ride it in the while loop.

Why is my try / except not giving any value for csv file?

I am limited to not use lists, using only the CSV library, use one loop and one if statement to parse through a txt file that has CSV data. I used the if statement to filter the rows for a specific job and that's why I used a try and except statements to find the average of those specific row and print it, but I can't seem to get a value.
Here's the code. OK here is the edit. the problem now is that the salary is a float so I can't use it for sum() — but am I on the right track?
here is the message i get in the output. i also fixed the indentation, i think it got missed up while editing.
File "C:/Users/USER1/PycharmProjects/pythonProject/main.py", line 32, in <module>
total_salaries = sum(salary)
TypeError: 'float' object is not iterable
import csv
file = open('SP21-Emp1.txt', 'r')
reader = csv.reader(file)
total_salaries = 0
instructor_count = 0
print("Reading from file SP21-Emp1.txt" "\n")
for line in reader:
name, job, salary = line
salary = float(salary)
salary = salary + (salary*0.1)
instructor_count = len(line)
total_salaries = sum(salary)
if job == 'Instructor':
first_name, last_name = name.split(' ', 1)
print(f'Name: {last_name} {first_name} \t Job: {job} \t Income: {salary}',)
try:
average_instructor_salary = total_salaries / instructor_count
except ValueError:
print('can not calculate average because there were no instructor salaries found.')
average_instructor_salary = "No instructor salary found"
print("\n" "The average of the instructors' salaries is:", average_instructor_salary)

Reading (somewhat) unstructured data from a text file to create Python Dictionary

I have the following data in a text file named 'user_table.txt':
Jane - valentine4Me
Billy
Billy - slick987
Billy - monica1600Dress
Jason - jason4evER
Brian - briguy987321CT
Laura - 100LauraSmith
Charlotte - beutifulGIRL!
Christoper - chrisjohn
I'm trying to read this data into a Python dictionary using the following code:
users = {}
with open("user_table.txt", 'r') as file:
for line in file:
line = line.strip()
# if there is no password
if '-' in line == False:
continue
# otherwise read into a dictionary
else:
key, value = line.split('-')
users[key] = value
print(users)
I get the following error:
ValueError: not enough values to unpack (expected 2, got 1)
This most likely results because the first instance of Billy doesn't have a '-' to split on.
If that's the case, what's the best way to work around this?
Thanks!
Your condition is wrong, must be:
for line in file:
line = line.strip()
# if there is no password
# if '-' not in line: <- another option
if ('-' in line) == False:
continue
# otherwise read into a dictionary
else:
key, value = line.split('-')
users[key] = value
or
for line in file:
line = line.strip()
# if there is password
if '-' in line:
key, value = line.split('-')
users[key] = value

How to print in a specific element in a list in a sorted order in python

I'm tasked to create a function that takes a string filename as an argument, reads the file with the name filename, and prints
all confirmed reservations in order of the time.
A line in the file is formatted like so
name, time, reservation_status (can either be confirmed or canceled in uppercase)
An example of a file "reservations.txt" could look like this:
Alex, 20, CONFIRMED
Thomas, 16, CANCELLED
William, 18, CONFIRMED
The correct output when calling the function on this example file should look like this:
show_reservations("reservations.txt")
>>> William, 18
Alex, 20
My solution:
def show_reservations(filename):
with open(filename) as f:
for line in f.readlines():
line = line.replace(',', '').split()
status = line[2]
if status == "CONFIRMED":
name = line[0]
time = line[1]
print(name + ",", time)
However, calling my solution on the example file above gives me following output:
show_reservations("reservations.txt")
>>> Alex, 20
William, 18
What to do?
you don't store your data and you also need some sorting
def funct(e):
return e['time']
def show_reservations(filename):
with open(filename) as f:
l=[]
for line in f.readlines():
line = line.replace(',', '').split()
dict={}
status = line[2]
if status == "CONFIRMED":
dict["name"] = line[0]
dict["time"] = line[1]
name = line[0]
time = line[1]
l.append(dict)
l.sort(key=funct)
for i in l:
print('{0} , {1}'.format(i["name"],i["time"]))
show_reservations("input.txt")
It happens because your original sequence comes in this way:
Alex, 20, CONFIRMED
...
William, 18, CONFIRMED
So you can save your filtered elements into a list and apply sorting on it. For example using sorted function.
You could try something like this:
def show_reservations(filename):
confirmed_orders = []
with open(filename) as f:
for line in f.readlines():
line = line.replace(',', '').split()
name, _time, status = line
if status == "CONFIRMED":
confirmed_orders.append((name, _time))
confirmed_orders_by_time = sorted(confirmed_orders, key=lambda x: x[1])
for name, _time in confirmed_orders_by_time:
print(name + ",", _time)
Also several additional suggestions in case the snippet you've provided is a real production code:
time is a bad name for variable because it can clash with built-in Python's module time.
split gives you tuple, so instead of messing with accessing by index you can unpack it:
name, _time, status = line
This thing line.replace(',', '').split() won't work correctly if name or status in the file will have a "space". Consider to use csv or something else for parsing data file.
If you use Python 3.5 or higher f-string is a preferable way instead of manual string concatenation:
print(f"{name}, {_time}")
def show_reservations(filename):
reservations = []
with open(filename) as f:
for line in f.readlines():
splitted_line = line.replace(',', '').split()
status = splitted_line[2]
if status == "CONFIRMED":
time = splitted_line[1]
name = splitted_line[0]
reservations.append({"time":time, "name":name})
return sorted(reservations, key=lambda k: k['time'])
for reservation in show_reservations("reservations.txt"):
print(reservation["name"] + ",", reservation["time"])
Instead of directly printing, append the entries to a list of tuples (time, name). Then after the list, sort it (li.sort()), and loop through it again, this time printing.

How to replace/change element in txt.file

Im trying to replace a cetain element in a txt file.
let say that if i find the name in telephonelist.txt, i want i to change the number to this person with the input value of newNumber.
let's say that name = Jens, then i want it to return 99776612 that is the tlf number to Jens, and then the input of 'newNumber' will replace this number. i am new to python.
def change_number():
while True:
try:
name = input('Name: ') #Enter name
newNumber = input('New number: ') # Wanted new number
datafile = open('telephonelist.txt')
if name in open('telephonelist.txt').read():
for line in datafile:
if line.strip().startswith(name):
line = line.replace(name,newNumber)
print('I found', name)
quit()
else:
print('I could not find',name+',','please try again!\n')
continue
except ValueError:
print('nn')
change_number()
This i telephonelist.txt
Kari 98654321
Liv 99776655
Ola 99112233
Anne 98554455
Jens 99776612
Per 97888776
Else 99455443
Jon 98122134
Dag 99655732
Siv 98787896
Load content, modify it, seek to beginning of the file, write the modified content again and then truncate the rest.
def change_number():
name = input('Name: ') #Enter name
newNumber = input('New number: ') # Wanted new number
with open('telephonelist.txt', 'r+') as file:
data = file.read().splitlines()
data = [line if not line.split()[0] == name else f"{name} {newNumber}" for line in data]
file.seek(0)
file.write("\n".join(data))
file.truncate()
change_number()

Categories