Hi everyone!
I just finished my Python Terminal Game Portfolio Project. My aim was to do something useful. I made an app called FilmBox, where the user can input their name and save movie titles to a list, giving them a rating from 1 to 5 stars and a comment. The user can also list all movies they added, search for specific entries, clear their list or export their list as a CSV file. With some help from ChatGPT, I was also able to implement a SQLite 3 database system to store persistent data. If the user is a returning user, the program identifies it and loads the movie list related to that specific user ID.
Here’s my code:
import csv
import sqlite3
print("""
______ _ _ ____
| ____(_) | | _ \
| |__ _| |_ __ ___ | |_) | _____ __
| __| | | | '_ ` _ \| _ < / _ \ \/ /
| | | | | | | | | | |_) | (_) > <
|_| |_|_|_| |_| |_|____/ \___/_/\_\
""")
print("Welcome to FilmBox!")
print("With this app, you can add movies to a list and give them ratings and commnets!")
movies_and_ratings = {}
first_use = True
is_active = True
user_input_yes_no = ""
user_input = ""
def initialize_db():
conn = sqlite3.connect("filmbox.db")
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT UNIQUE
)
""")
cursor.execute("""
CREATE TABLE IF NOT EXISTS movies (
id INTEGER PRIMARY KEY,
user_id INTEGER,
title TEXT,
rating INTEGER,
comment TEXT,
FOREIGN KEY(user_id) REFERENCES users(id)
)
""")
conn.commit()
return conn, cursor
conn, cursor = initialize_db()
def get_or_create_user(user_name):
cursor.execute("SELECT id FROM users WHERE name = ?", (user_name,))
user_id = cursor.fetchone()
if user_id:
print(f"Welcome back, {user_name}")
return user_id[0], False
else:
cursor.execute("INSERT INTO users (name) VALUES (?)", (user_name,))
return cursor.lastrowid, True
def load_movies_from_db():
cursor.execute("SELECT title, rating, comment FROM movies WHERE user_id = ?", (user_id,))
for row in cursor.fetchall():
title, rating, comment = row
movies_and_ratings[title] = {'rating': str(rating), 'comment': comment}
user_name = input("Please type your name: ")
user_id, is_new_user = get_or_create_user(user_name)
load_movies_from_db()
def add_comment(movie_name):
user_input_comment = input("Write a comment about the movie: ")
return user_input_comment
def save_movie_to_db(movie_name, rating, comment):
cursor.execute("INSERT INTO movies (user_id, title, rating, comment) VALUES (?, ?, ?, ?)", (user_id, movie_name, rating, comment))
conn.commit()
def add_movie_and_rating():
while True:
user_input_movie = input("Please type the name of a movie: ")
if user_input_movie not in movies_and_ratings:
break
else:
print("Movie is already on your list!")
movies_and_ratings[user_input_movie] = {}
user_input_rating = input("Please give {} a rating from 1 to 5 stars: ".format(user_input_movie))
while user_input_rating not in ["1", "2", "3", "4", "5"]:
user_input_rating = input("Please type a number from 1 to 5: ")
movies_and_ratings[user_input_movie]["rating"] = user_input_rating
comment = add_comment(user_input_movie)
movies_and_ratings[user_input_movie]["comment"] = comment
save_movie_to_db(user_input_movie, user_input_rating, comment)
cursor.execute("INSERT OR REPLACE INTO movies (title, rating, comment) VALUES (?, ?, ?)", (user_input_movie, user_input_rating, comment))
conn.commit()
def show_list():
if not movies_and_ratings:
print("Your movie list is empty!")
return
print("Movies in your list:")
print("-" * 20)
for movie_name, details in movies_and_ratings.items():
print("Ttile:" + str(movie_name))
print("Rating:", "★" * int(details["rating"]))
print("Comment:", details.get("comment", "No comment provided."))
print("-" * 20)
def clear_list():
user_confirmation = input("Are you sure you want to clear your list? This action is not unduable! (\"yes\" or \"no\"): ")
while user_confirmation.lower() not in ["yes", "no"]:
user_confirmation = input("Please type \"yes\" or \"no\": ")
if user_confirmation == "yes":
movies_and_ratings.clear()
cursor.execute("DELETE FROM movies")
else:
return "Action cancelled."
def add_first_movie():
user_input_yes_no = input("Hello {}! Do you want to add your first movie to the list? (\"yes\" or \"no\"): ".format(user_name))
user_input_yes_no.lower()
while user_input_yes_no not in ["yes", "no"]:
user_input_yes_no = input("Please type \"yes or \"no\": ")
if user_input_yes_no == "no":
print("Closing app...")
exit()
else:
add_movie_and_rating()
print("Movie added to your list!")
def search_movies():
search_query = input("Enter a movie name or part of it to search: ").lower()
found_movies = {title: details for title, details in movies_and_ratings.items() if search_query in title.lower()}
if not found_movies:
print("No movies found matching your search.")
else:
print("Found movies:")
print("-" * 20)
for movie_name, details in found_movies.items():
print("Title:", movie_name)
print("Rating:", "★", int(details["rating"]))
print("Cooment:", details.get("comment", "No comment provided."))
print("-" * 20)
def main_menu():
global is_new_user
while True:
if not movies_and_ratings and not is_new_user:
print("Your movie list is empty!")
add_first_movie()
continue
elif is_new_user:
add_first_movie()
is_new_user = False
continue
user_input = \
input("Now that you have movie(s) in your list, you can: type \"1\" to see your list, type \"2\" to add another movie, type \"3\" to clear your list, \
type \"4\" to export your list as a CSV file or type \"5\" to search for a movie or type \"6\"to leave the app: ")
if user_input == "1":
show_list()
elif user_input == "2":
add_movie_and_rating()
print("Movie added to your list!")
elif user_input == "3":
clear_list()
elif user_input == "4":
fields = ["Film", "Rating", "Comment"]
with open("films_rating_and_comments.csv", "w") as films_csv:
doc_writer = csv.DictWriter(films_csv, fieldnames=fields)
doc_writer.writeheader()
for movie_name, details in movies_and_ratings.items():
row_data = {"Film": movie_name, "Rating": details["rating"], "Comment": details["comment"]}
doc_writer.writerow(row_data)
print("Exporing your list as a CSV file...")
elif user_input == "5":
search_movies()
elif user_input == "6":
conn.close()
print("Closing App...")
exit()
main_menu()
I know that probably this code could be much smaller and probably there’s some redundancy. I’m very keen to hear what you think! What could I do better? Where are the redundancies? Is there another way of storing persistent data?
Thank you in advance and happy coding