I am working on this project for school and I can't seem to get it perfect. I got the majority of it working but there's two things I am struggling with. After a few hours of googling and attempting various different workaround I have decided I need to ask for help.
def main():
movieCollectionDict = {"Munich":[2005, "Steven Spielberg"],
"The Prestige": [2006, "Christopher Nolan"],
"The Departed": [2006, "Martin Scorsese"],
"Into the Wild": [2007, "Sean Penn"],
"The Dark Knight": [2008, "Christopher Nolan"],
"Mary and Max": [2009, "Adam Elliot"],
"The King\'s Speech": [2010, "Tom Hooper"],
"The Help": [2011, "Tate Taylor"],
"The Artist": [2011, "Michel Hazanavicius"],
"Argo": [2012, "Ben Affleck"],
"12 Years a Slave": [2013, "Steve McQueen"],
"Birdman": [2014, "Alejandro G. Inarritu"],
"Spotlight": [2015, "Tom McCarthy"],
"The BFG": [2016, "Steven Spielberg"]}
promptForYear = True
while promptForYear:
yearChoice = int(input("Enter a year between 2005 and 2016:\n"))
if yearChoice<2005 or yearChoice>2016:
print("N/A")
else:
for key, value in movieCollectionDict.items():
if value[0] == yearChoice:
print(key + ", " + str(value[1]) )
promptForYear = False
menu = "MENU" \
"\nSort by:" \
"\ny - Year" \
"\nd - Director" \
"\nt - Movie title" \
"\nq - Quit\n"
promptUser = True
while promptUser:
print("\n" + menu)
userChoice = input("Choose an option:\n")
if userChoice == "q":
promptUser = False
elif userChoice=="y":
for key, value in sorted(movieCollectionDict.items(), key=lambda item: (item[1], item[0])):
print (value[0],end=':\n')
print("\t"+key + ", " + str(value[1])+"\n")
elif userChoice == "d":
for key, value in sorted(movieCollectionDict.items(), key=lambda key_value: key_value[1][1]):
print(value[1],end=':\n')
print("\t" + key + ", " + str(value[0])+"\n")
elif userChoice == "t":
for key, value in sorted(movieCollectionDict.items(), key=lambda item: (item[0], item[1])):
print(key,end=':\n')
print("\t" + str(value[1]) + ", " + str(value[0])+"\n")
else:
print("Invalid input")
main()
Basically I am having an issue, when I put in the year 2006. Instead of showing both movies from that year it prints them twice. Where did I go wrong with this?
I am also having an issue with an extra space at the end before the menu comes back up, it should have one space but it currently prints two blank lines.
This is the output:
2005:
Munich, Steven Spielberg
2006:
The Prestige, Christopher Nolan
2006:
The Departed, Martin Scorsese
2007:
Into the Wild, Sean Penn
2008:
The Dark Knight, Christopher Nolan
I need both the movies from 2006 to be together and not separate.
Here is the example of the extra space:
2016:
The BFG, Steven Spielberg
MENU
Sort by:
y - Year
d - Director
t - Movie title
q - Quit
Choose an option:
Any help at all would be really appreciated!
Here is the solution. All the changes are in the if conditions of the while loop. To group the items based on year/director/title, a variable prev_value is used. Only when prev_value changes it is printed. This ensures grouping while printing sorted data. Also note the change where newlines are printed. They are now printed before the group header. That solves the double space issue.
def main():
movieCollectionDict = {"Munich":[2005, "Steven Spielberg"],
"The Prestige": [2006, "Christopher Nolan"],
"The Departed": [2006, "Martin Scorsese"],
"Into the Wild": [2007, "Sean Penn"],
"The Dark Knight": [2008, "Christopher Nolan"],
"Mary and Max": [2009, "Adam Elliot"],
"The King\'s Speech": [2010, "Tom Hooper"],
"The Help": [2011, "Tate Taylor"],
"The Artist": [2011, "Michel Hazanavicius"],
"Argo": [2012, "Ben Affleck"],
"12 Years a Slave": [2013, "Steve McQueen"],
"Birdman": [2014, "Alejandro G. Inarritu"],
"Spotlight": [2015, "Tom McCarthy"],
"The BFG": [2016, "Steven Spielberg"]}
promptForYear = True
while promptForYear:
yearChoice = int(input("Enter a year between 2005 and 2016:\n"))
if yearChoice<2005 or yearChoice>2016:
print("N/A")
else:
for key, value in movieCollectionDict.items():
if value[0] == yearChoice:
print(key + ", " + str(value[1]) )
promptForYear = False
menu = "MENU" \
"\nSort by:" \
"\ny - Year" \
"\nd - Director" \
"\nt - Movie title" \
"\nq - Quit\n"
promptUser = True
while promptUser:
prev_val = ''
print("\n" + menu)
userChoice = input("Choose an option:\n")
if userChoice == "q":
promptUser = False
elif userChoice=="y":
for key, value in sorted(movieCollectionDict.items(), key=lambda item: (item[1], item[0])):
if(prev_val!=value[0]):
print ("\n",value[0],end=':\n',sep='')
prev_val = value[0]
print("\t"+key + ", " + str(value[1]))
elif userChoice == "d":
for key, value in sorted(movieCollectionDict.items(), key=lambda key_value: key_value[1][1]):
if(prev_val!=value[1]):
print("\n",value[1],end=':\n',sep='')
prev_val = value[1]
print("\t" + key + ", " + str(value[0]))
elif userChoice == "t":
for key, value in sorted(movieCollectionDict.items(), key=lambda item: (item[0], item[1])):
if(prev_val!=key):
print("\n",key,end=':\n',sep='')
prev_val = key
print("\t" + str(value[1]) + ", " + str(value[0]))
else:
print("Invalid input")
main()
Let's first understand the actual problem :
So suppose you have a list :
a=[(2006,1),(2007,4),(2008,9),(2006,5)]
And you want to convert this to a dict as the first element of the tuple as key and second element of the tuple. something like :
{2008: [9], 2006: [5], 2007: [4]}
But there is a catch you also want that those keys which have different values but keys are same like (2006,1) and (2006,5) keys are same but values are different. you want that those values append with only one key so expected output :
{2008: [9], 2006: [1, 5], 2007: [4]}
for this type of problem we do something like this:
first create a new dict then we follow this pattern:
if item[0] not in new_dict:
new_dict[item[0]]=[item[1]]
else:
new_dict[item[0]].append(item[1])
So we first check if key is in new dict and if it already then add the value of duplicate key to its value:
full code:
a=[(2006,1),(2007,4),(2008,9),(2006,5)]
new_dict={}
for item in a:
if item[0] not in new_dict:
new_dict[item[0]]=[item[1]]
else:
new_dict[item[0]].append(item[1])
print(new_dict)
Now let's back to your problem, you also want something like this so we can do :
elif userChoice=="y":
new={}
for key, value in sorted(movieCollectionDict.items()):
for k in value:
if value[0] not in new:
new[value[0]]=[(key,value[1])]
else:
new[value[0]].append((key,value[1]))
print({key: set(value) for key, value in new.items()})
So full code:
def main():
movieCollectionDict = {"Munich":[2005, "Steven Spielberg"],
"The Prestige": [2006, "Christopher Nolan"],
"The Departed": [2006, "Martin Scorsese"],
"Into the Wild": [2007, "Sean Penn"],
"The Dark Knight": [2008, "Christopher Nolan"],
"Mary and Max": [2009, "Adam Elliot"],
"The King\'s Speech": [2010, "Tom Hooper"],
"The Help": [2011, "Tate Taylor"],
"The Artist": [2011, "Michel Hazanavicius"],
"Argo": [2012, "Ben Affleck"],
"12 Years a Slave": [2013, "Steve McQueen"],
"Birdman": [2014, "Alejandro G. Inarritu"],
"Spotlight": [2015, "Tom McCarthy"],
"The BFG": [2016, "Steven Spielberg"]}
promptForYear = True
while promptForYear:
yearChoice = int(input("Enter a year between 2005 and 2016:\n"))
if yearChoice<2005 or yearChoice>2016:
print("N/A")
else:
for key, value in movieCollectionDict.items():
if value[0] == yearChoice:
print(key + ", " + str(value[1]) )
promptForYear = False
menu = "MENU" \
"\nSort by:" \
"\ny - Year" \
"\nd - Director" \
"\nt - Movie title" \
"\nq - Quit\n"
promptUser = True
while promptUser:
print("\n" + menu)
userChoice = input("Choose an option:\n")
if userChoice == "q":
promptUser = False
elif userChoice=="y":
new={}
for key, value in sorted(movieCollectionDict.items()):
for k in value:
if value[0] not in new:
new[value[0]]=[(key,value[1])]
else:
new[value[0]].append((key,value[1]))
print({key: set(value) for key, value in new.items()})
elif userChoice == "d":
for key, value in sorted(movieCollectionDict.items(), key=lambda key_value: key_value[1][1]):
print(value[1],end=':\n')
print("\t" + key + ", " + str(value[0])+"\n")
elif userChoice == "t":
for key, value in sorted(movieCollectionDict.items(), key=lambda item: (item[0], item[1])):
print(key,end=':\n')
print("\t" + str(value[1]) + ", " + str(value[0])+"\n")
else:
print("Invalid input")
main()
PS : you can format the output as you want like key(year) in first line and values (movies name) in second line.
Your problem is with the logic. This is the part where you'll be interested in.
elif userChoice=="y":
prev_years = []
for key, value in sorted(movieCollectionDict.items(), key=lambda item: (item[1], item[0])):
if value[0] in prev_years:
print("\t"+key + ", " + str(value[1])+"\n")
else:
print (value[0],end=':\n')
print("\t"+key + ", " + str(value[1])+"\n")
prev_years.append(value[0])
Notice I have added a list prev_years
where I add years when I see them first.
For the first time i'll just check if 2005
is in my prev_years
list. But starting it'll be empty. Hence the else
part will execute!
else:
print (value[0],end=':\n')
print("\t"+key + ", " + str(value[1])+"\n")
Then i'll do this,
prev_years.append(value[0])
So now,
prev_years = [2005]
So when I see 2006
for the first time I do the same as above! and add it in my prev_years
list
So now,
prev_years = [2005,2006]
Next comes the trick!
Take a look at my condition,
if value[0] in prev_years:
print("\t"+key + ", " + str(value[1])+"\n")
So when the next year is already is in my prev_years
list i just do the above. This gives you what you want!
Take a look at this in interpreter,
>>>
>>> print("hello");print("Vishnu")
hello
Vishnu
>>> print("hello"+"\n");print("Vishnu"+"\n")
hello
Vishnu
>>>
That's basically why extra space. print()
by default puts a new line at the end. So remove all the backslash \\n
's and you've got what you wanted.
Enter a year between 2005 and 2016:
2006
The Prestige, Christopher Nolan
The Departed, Martin Scorsese
MENU
Sort by:
y - Year
d - Director
t - Movie title
q - Quit
Choose an option:
y
2005:
Munich, Steven Spielberg
2006:
The Prestige, Christopher Nolan
The Departed, Martin Scorsese
2007:
Into the Wild, Sean Penn
2008:
The Dark Knight, Christopher Nolan
2009:
Mary and Max, Adam Elliot
2010:
The King's Speech, Tom Hooper
2011:
The Artist, Michel Hazanavicius
The Help, Tate Taylor
2012:
Argo, Ben Affleck
2013:
12 Years a Slave, Steve McQueen
2014:
Birdman, Alejandro G. Inarritu
2015:
Spotlight, Tom McCarthy
2016:
The BFG, Steven Spielberg
MENU
Sort by:
y - Year
d - Director
t - Movie title
q - Quit
Choose an option:
Improvement performed:
I prefer using extra dictionary and clear variable name to make the code easier to read. Here is what I come up with. This is lengthy but seems logical to me. I assume you are learning programming. In this time, the more solutions you see of a particular problem, the more you will learn.
def main():
movieCollectionDict = {"Munich":[2005, "Steven Spielberg"],
"The Prestige": [2006, "Christopher Nolan"],
"The Departed": [2006, "Martin Scorsese"],
"Into the Wild": [2007, "Sean Penn"],
"The Dark Knight": [2008, "Christopher Nolan"],
"Mary and Max": [2009, "Adam Elliot"],
"The King\'s Speech": [2010, "Tom Hooper"],
"The Help": [2011, "Tate Taylor"],
"The Artist": [2011, "Michel Hazanavicius"],
"Argo": [2012, "Ben Affleck"],
"12 Years a Slave": [2013, "Steve McQueen"],
"Birdman": [2014, "Alejandro G. Inarritu"],
"Spotlight": [2015, "Tom McCarthy"],
"The BFG": [2016, "Steven Spielberg"]}
promptForYear = True
while promptForYear:
yearChoice = int(input("Enter a year between 2005 and 2016:\n"))
if yearChoice<2005 or yearChoice>2016:
print("N/A")
else:
for key, value in movieCollectionDict.items():
if value[0] == yearChoice:
print(key + ", " + str(value[1]) )
promptForYear = False
menu = "MENU" \
"\nSort by:" \
"\ny - Year" \
"\nd - Director" \
"\nt - Movie title" \
"\nq - Quit\n"
promptUser = True
first_time = True
while promptUser:
if first_time == True:
print()
first_time = False
print(menu)
userChoice = input("Choose an option:\n")
if userChoice == "q":
promptUser = False
elif userChoice=="y":
year_sorted = {}
for key, value in sorted(movieCollectionDict.items(), key=lambda item: (item[1], item[0])):
year = value[0]
title = key
director = value[1]
if year not in year_sorted:
year_sorted[year] = [[title, director]]
else:
year_sorted[year].append([title, director])
for year in sorted(year_sorted):
print (year,end=':\n')
movies = year_sorted[year]
for movie in sorted(movies, key = lambda x:x[0]):
print("\t"+movie[0] + ", " + movie[1])
print()
elif userChoice == "d":
director_sorted = {}
for key, value in sorted(movieCollectionDict.items(), key=lambda item: (item[1][1])):
year = value[0]
title = key
director = value[1]
if director not in director_sorted:
director_sorted[director] = [[title, year]]
else:
director_sorted[director].append([title, year])
for director in sorted(director_sorted):
print (director,end=':\n')
movies = director_sorted[director]
for movie in sorted(movies, key = lambda x:x[0]):
print("\t"+movie[0] + ", " + str(movie[1]))
print()
elif userChoice == "t":
for key, value in sorted(movieCollectionDict.items(), key=lambda item: (item[0], item[1])):
print(key,end=':\n')
print("\t" + str(value[1]) + ", " + str(value[0])+"\n")
else:
print("Invalid input")
main()
Output:
Enter a year between 2005 and 2016:
2006
The Prestige, Christopher Nolan
The Departed, Martin Scorsese
MENU
Sort by:
y - Year
d - Director
t - Movie title
q - Quit
Choose an option:
y
2005:
Munich, Steven Spielberg
2006:
The Departed, Martin Scorsese
The Prestige, Christopher Nolan
2007:
Into the Wild, Sean Penn
2008:
The Dark Knight, Christopher Nolan
2009:
Mary and Max, Adam Elliot
2010:
The King's Speech, Tom Hooper
2011:
The Artist, Michel Hazanavicius
The Help, Tate Taylor
2012:
Argo, Ben Affleck
2013:
12 Years a Slave, Steve McQueen
2014:
Birdman, Alejandro G. Inarritu
2015:
Spotlight, Tom McCarthy
2016:
The BFG, Steven Spielberg
MENU
Sort by:
y - Year
d - Director
t - Movie title
q - Quit
Choose an option:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.