def CreateDataBaseByActor(file):
dataBase = dict()
set = {}
f = open(file,"r")
for line in f:
set = line.split(', ')
for movie in set[1:]:
dataBase[movie] = set[0]
return dataBase
i have a file that each line is written by the format: actor_name, movie1, movie2, movie3...
example:
Sylvester Stallone, Rocky, Rambo, Assassins
Julianne Moore, Assassins, Hannibal
the problem is that when i try to add to a movie, another actor name (for example: in the first line, the key - Assassins- has the value Sylvester Stallone, and in the second line value of - Assassin - is replaced instead of added)
Assuming you want to return a dictionary that maps movie titles to a list of actors within each (which isn't clear from the name of the function), then this code should do it for you. (Note that I changed the variable named set to be called fields since it's not a good idea to name variables after types.)
def CreateDataBaseByActor(file):
dataBase = dict()
f = open(file, "r")
for line in f:
fields = line.split(', ')
actor = fields[0]
for movie in fields[1:]:
dataBase.setdefault(movie, []).append(actor)
return dataBase
Related
Hi my assignment is to read the company names and the shorten names of the companies
In def name_to_symbol(companyname, tickerdict)
I cant get the companyname variable and the tickerdict variable, i dont know why can someone help me
pe_8_4_tickers.txt
YAHOO:YHOO
GOOGLE INC:GOOG
Harley-Davidson:HOG
Yamana Gold:AUY
Sotheby's:BID
inBev:BUD
f = open('pe_8_4_tickers.txt', 'r')
file = f.readlines()
ticker_dict = {}
f.close()
def tickers_to_dict(file):
for line in file:
line_sepperated = line.split(':')
companyname = line_sepperated[0]
symbol = line_sepperated[1]
ticker_dict[line_sepperated[0]] = line_sepperated[1]
return companyname, symbol, ticker_dict
def name_to_symbol(companyname, ticker_dict):
tickers_to_dict(file)
ticker_dict = {}
# the assesment has one more def statement but i couldnt reach there
name_to_symbol(symbol, ticker_dict)
output i expect:
Enter Company name: YAHOO
Ticker symbol: YHOO
Enter Ticker symbol: BUD
Company name: inBev
f = open('pe_8_4_tickers.txt', 'r')
file = f.readlines()
f.close()
def tickers_to_dict(file):
for line in file:
line_sepperated = line.split(':')
companyname = line_sepperated[0]
symbol = line_sepperated[1]
ret_dict[line_sepperated[0]] = line_sepperated[1]
return ret_dict
def name_to_symbol(companyname):
ticker_dict=tickers_to_dict(file)
return ticker_dict[companyname]
# the assesment has one more def statement but i couldnt reach there
name_to_symbol(symbol)
returns the result you expected. But it will read from file every time when you call a company. So if you want to read file once you need to call tickers_to_dict function in somewhere else rather than in name_to_symbol
You're (a) returning the global variable ticker_dict out of tickers_to_dict; (b) shadowing the global variable ticker_dict with an argument in name_to_symbol, and (c) setting ticker_dict to {} after you've read it.
You're also calling name_to_symbol with a symbol, even though company name is expected.
In addition, (a) you don't need the readlines() call (you can directly use a file in a for loop); (b) for splitting up the lines, it's better to use the csv module rather than doing it manually (unless your assignment specifically forbids this); (c) use a with statement to make sure the file is closed even if an exception is raised; and (d) it's better not to do much at the top level of a script, instead put everything into functions.
def tickers_to_dict(file):
result = {}
for companyname, symbol in csv.reader(file, delimiter=':'):
result[companyname] = symbol
return result
def name_to_symbol(companyname, ticker_dict):
...
def main():
with open('pe_8_4_tickers.txt', 'r') as f:
ticker_dict = tickers_to_dict(f)
... get company name from user ...
symbol = name_to_symbol(companyname, ticker_dict)
... show result to user ...
if __name__ == "__main__":
main()
So basically I want to create a variable that changes after every iteration of a for loop to be the same as the search term that is used in the for loop in question, is that possible? I explained better in the code I think.
with open ('lista1.txt','r') as file_1:
reader_0 = file_1.readlines() # Reads a list of searchterms,
# the first search term of this list is "gt-710".
for search in reader_0:
file_0 = search.replace("\n","") +".txt"
file_1 = str(file_0.strip())
try: #if the file named the same as the searchterm exists, read its contents
file = open(file_1,"r")
search = file.readlines() # How do I create a variable that
# changes names? for example I want the
# content of file readlines be saved in
# a variable called the same as the
# searchterm in this ase I want it to
# be gt-710 = file.readlines()...in the
# next iteration I want it to be
# next_search_term_in_the_list =
# file.readlines()..an so on...
print(str(search) + "I actually tried")
except: #if not, create it
file = open(file_1,"w")
file.write("hello")
print("I didnt")
file.close()
This is impossible in Python, but you can do something similar. Enter stage left, the DICTIONARY! A dictionary is like a list, but you set your own keys. Make it like this:
my_dict = {}
You can add to the dictionary like so:
my_dict["key"] = "value"
A way you could implement this into your code could be as follows:
the_dict = {}
with open ('lista1.txt','r') as file_1:
[...]
file = open(file_1,"r")
file_contents = file.readlines()
the_dict[search] = file_contents
print(str(file_contents) + "I actually tried")
[...]
I'm new in Python and i'm challenging myself by making an online library management with prompt for the 1st phase.I'm stacked in search function.I have found how to print a user's input,but i can't find how to print and the following data.I want to search a book by name.If book's name is in the text,i want to print the details of the book,like author,isbn etc.
Here is the following code i have made:
def search():
search_book = input('Search a book: ')
with open('library.txt', mode='r', encoding='utf-8') as f:
index = 0
for line in f:
index += 1
if search_book in line:
print(f'{search_book} is in line {index}')
for details in range(index,index+5):
print(line[details])
And this is the text file's data:
FIRST
ME
9781234
2000
Science
SECOND
YOU
9791234
1980
Literature
It is separated by new line.As example a user input the name FIRST and the result will be:
FIRST
ME
9781234
2000
Science
There are two file options we can consider,
Csv file - Instead of individual readline, you could use one line for one book entry.
# ---------test.csv -------------
# BookName, ItemCode, Price
# Book1, 00012, 14.55
# Book2, 00232, 55.12
# -----End Csv-------------------
import csv
def read_csv(filename:str):
file_contents = None
# reading csv file
with open(filename, 'r') as csvfile:
file_contents = csv.reader(csvfile)
return file_contents
def search(file_contents, book_name:str):
if not file_contents:
return None
for line in file_contents:
if book_name in line:
return line
if __name__ == '__main__':
file_contents = read_csv('test.csv')
line = search(file_contents, 'ME')
print(line if line else 'No Hit Found')
Json - This is much better option than csv file
import json
def read_json(filename:str) -> dict:
with open(filename) as json_file:
all_books = json.load(json_file)
return all_books
def search(all_books:dict, book_name:str):
for book_id, book_details in all_books.items():
if book_details['Name'] == book_name:
return book_details
return None
if __name__ == '__main__':
all_books = read_json('books.json')
book = search(all_books, 'YOU')
print(book if book else 'Not hit found')
If your file contents can't change, then I will go with #tripleee suggestion above. Good luck.
You are reading a line at a time, and looping over the first line's contents. At this point in the program, there are not yet any additional lines. But a fix is relatively easy:
def search():
search_book = input('Search a book: ')
with open('library.txt', mode='r', encoding='utf-8') as f:
index = 0
print_this_many = 0
for line in f:
index += 1
if search_book in line:
print(f'{search_book} is in line {index}')
print_this_many = 5
if print_this_many:
print(line, end='')
print_this_many -= 1
We don't have the next lines in memory yet, but we can remember how many of them to print as we go ahead and read more of them. The print_this_many variable is used for this: When we see the title we want, we set it to 5 (to specify that this and the next four lines should be printed). Now, each time we read a new line, we check if this variable is positive; if it is, we print the line and decrement the variable. When it reaches zero, we will no longer print the following lines. This allows us to "remember" across iterations of the for loop which reads each new line whether we are in the middle of printing something.
A much better solution is to read the database into memory once, and organize the lines into a dictionary, for example.
def read_lib(filename):
library = dict()
with open(filename) as lib:
title = None
info = []
for line in lib:
line = line.rstrip('\n')
if title is None:
title = line
elif line == '':
if title and info:
library[title] = info
title = None
else:
info.append(line)
def search(title, library):
if title in library:
return library[title]
else:
return None
def main():
my_library = read_lib('library.txt')
while True:
sought = input('Search a book: ')
found = search(sought, my_library)
if found:
print('\n'.join(found))
else:
print('Sorry, no such title in library')
Create a function that takes a file name (and path if needed) as the argument. In the function, open and read in the file mountains.csv. Use a try/catch to be sure the file exists and is readable. If the file location is wrong or it can't be opened, print an error that begins with "Error:". (You can test it with a junk path or filename that doesn't exist.)
Split each line by the comma, and make a dictionary where the key is the mountain name (the first element) and the height is the value, the second element. Make sure to convert the height to a number. Then print the keys and values of the dictionary using .items(), in readable sentences that say, for instance, "The height of K2 is 8611 meters." Return the dictionary at the end of the function.
Reminder about print with {} in your string: use print(string.format(variable)) to fill in the {} with your variable. If there are 2 {}'s, use .format(var1, var2)
This is what I got so far:
import csv
def mountain_height(filename):
""" Read in a csv file of mountain names and heights.
Parse the lines and print the names and heights.
Return the data as a dictionary.
The key is the mountain and the height is the value.
"""
mountains = dict()
msg = "The height of {} is {} meters."
err_msg = "Error: File doesn't exist or is unreadable."
# TYPE YOUR CODE HERE.
with open('mountains.csv', 'r') as handle:
reader = csv.reader(handle, delimiter=',')
for row in reader:
name = row[0]
height = row[1]
int(height)
dictionary = {name: height}
for k,v in dictionary.items():
print(k,v)
return dictionary
And there's the csv file:
You're nearly there. You simply need to add an entry to mountains for each iteration of the loop:
mountains = dict()
with open('mountains.csv', 'r') as handle:
reader = csv.reader(handle, delimiter=',')
for row in reader:
name = row[0]
height = row[1]
mountains[name] = int(height)
Don't forget to check if the file exists! I added an extra check so the function works with or without ".csv" file extension specified.
You also want to print a nice string using msg.format(name, height)
Lastly don't return the dictionary inside of the for loop! This ends your function and you will only see one message printed out.
For bonus points you can use csv.DictReader to read CSV files more efficiently. If the CSV does not have a header column, you need to pass fieldnames (i.e. name, height) yourself.
from csv import DictReader
def mountain_height(filename):
msg = "The height of {} is {} meters."
err_msg = "Error: File doesn't exist or is unreadable."
if filename.split('.')[-1] != 'csv':
filename += '.csv'
try:
open(filename)
except FileNotFoundError:
print(err_msg)
with open(filename) as f:
reader = DictReader(f, fieldnames=['name', 'height'], delimiter=',')
mountain_heights = {
row['name']: int(row['height']) for row in reader
}
for name, height in mountain_heights.items():
print(msg.format(name, height))
return mountain_heights
My intention was to copy a piece of string after either a colon or equal sign from File 1 , and pasting that string in File 2 in a similar location after either a colon or equal sign.
For instance, if File 1 has:
username: Stack
File 2 is originally empty:
username=
I want Stack to be copied over to File 2 after username. Currently, I'm stuck and not sure what to do. The program piece I made below doesn't copy the username. I would greatly appreciate any input!
with open("C:/Users/SO//Downloads//f1.txt", "r") as f1:
with open("C:/Users/SO//Downloads//f2.txt", "r+") as f2:
searchlines = f1.readlines()
searchlines_f2=f2.readlines()
for i, line in enumerate(searchlines):
if 'username' in line:
for l in searchlines[i:i+1]:
ind = max(l.find(':'), l.find('='), 0) #finding index of specific characters
copy_string=l[ind+1:].strip() #copying string for file 2
for l in searchlines_f2[i:i+1]:
if 'username' in line:
f2.write(copy_string)
I think something like this will get you what you need in a more maintainable and Pythonic way.
Note the use of regex as well as some string methods (e.g., startswith)
import re
SOURCE_PATH = "C:/Users/SO//Downloads//f1.txt"
TARGET_PATH = "C:/Users/SO//Downloads//f2.txt"
def _get_lines(filepath):
""" read `filepath` and return a list of strings """
with open(filepath, "r+") as fh:
return fh.readlines()
def _get_value(fieldname, text):
""" parse `text` to get the value of `fieldname` """
try:
pattern = '%s[:=]{1}\s?(.*)' % fieldname
return re.match(pattern, text).group(1)
except IndexError:
# you may want to handle this differently!
return None
def _write_target(filepath, trgt_lines):
""" write `trgt_lines` to `filepath` """
with open(filepath, "w+") as fh:
fh.writelines(trgt_lines)
src_lines = _get_lines(SOURCE_PATH)
trgt_lines = _get_lines(TARGET_PATH)
# extract field values from source file
fields = ['username', 'id', 'location']
for field in fields:
value = None
for cur_src in src_lines:
if cur_src.startswith(field):
value = _get_value(field, cur_src)
break
# update target_file w/ value (if we were able to find it)
if value is not None:
for i, cur_trgt in enumerate(trgt_lines):
if cur_trgt.startswith('{0}='.format(field)):
trgt_lines[i] = '{0}={1}'.format(field, value)
break
_write_target(TARGET_PATH, trgt_lines)