The best way to learn Python? Build real projects.
When you code hands-on, you retain more, stay motivated, and develop skills that actually matter. No more passively memorizing syntax—you’ll be applying what you learn right away.
The only problem? Finding the right project ideas.
That’s where I come in. I've created more than 40 real-world, portfolio-worthy Python projects—ranging from beginner-friendly builds to professional-level applications, all with step-by-step tutorials, and even video walkthroughs. Whether you're just starting or sharpening your skills, these projects will help you level up.
Let’s start coding!
Professional Portfolio Projects
I've designed each of these projects to act like step-by-step tutorials, so it's almost like taking a free Python course while growing your Python portfolio.
Web Scraping for Python Automated Real Estate Data Pipeline with Dashboard
This is Part 1 of a four-part series on building a Python Automated Real Estate Data Pipeline. In this stage, we focus on web scraping real estate listings using Selenium to extract key property details like prices, addresses, beds, baths, and geolocation data. The collected data is stored in a structured format, setting the foundation for analysis in the next phase.
Want to master web scraping and build a real-world data pipeline that's worthy of a professional portfolio? This web scraping project is the perfect challenge.
Data Analysis for Python Automated Real Estate Data Pipeline with Dashboard
This is Part 2 of a four-part series on building a Python Automated Real Estate Data Pipeline. In this stage, we focus on cleaning and analyzing the scraped real estate data to prepare it for visualization and deeper insights.
Using Pandas, NumPy, Matplotlib, and Seaborn, we handle missing values, format numerical data, and explore trends in property prices, sizes, and features. This step ensures our dataset is structured, reliable, and ready for interactive visualization in Part 3.
Want to sharpen your data analysis skills while working on a real-world data pipeline? This data analysis project is the perfect hands-on experience!
Streamlit Dashboard for an Automated Real Estate Data Pipeline
This is Part 3 of a four-part series on building a Python Automated Real Estate Data Pipeline. In this stage, we focus on building an interactive dashboard using Streamlit to visualize real estate trends dynamically.
With Streamlit, Folium, Matplotlib, and Seaborn, we create a user-friendly interface where users can filter listings by price, bedrooms, bathrooms, and square footage, explore interactive maps, and analyze price distributions and market trends in real time.
Want to build a fully interactive, data-driven application that turns raw real estate data into valuable insights? This dashboard project is the perfect opportunity to showcase your skills!
Automating and Tracking Historical Data for Python Real Estate Data Pipeline
This is Part 4 and the final installment of a four-part series on building a Python Automated Real Estate Data Pipeline. In this stage, we take our project to the next level by implementing automation and historical tracking, allowing our scraper to run on a schedule and accumulate data over time.
With APScheduler, we automate the scraping and analysis processes, ensuring real-time data collection. We also enhance our pipeline by storing timestamped datasets, tracking price trends, and integrating historical filtering into our Streamlit dashboard for deeper real estate insights.
Want to build a fully automated, real-world data pipeline that continuously tracks market trends? This final automation and historical tracking project is the perfect way to complete your portfolio-worthy project!
Python File Organizer App
Tired of a cluttered downloads folder? A Python file organizer is a perfect project to simplify your life while leveling up your coding skills. Using Python’s os and shutil modules, you’ll learn to automate file sorting into categories like Images, Videos, and Documents. It’s beginner-friendly, practical, and introduces you to file handling, directory management, and automation.
Want to streamline your workflow and learn Python automation? Try your hand at building this Python file organizer app with me as I've created a video walkthrough to guide you every step of the way.
Python Unit Converter App with GUI
A Python unit converter app is an excellent project to learn GUI programming with tkinter and practical Python skills. It lets you create a user-friendly tool to convert units like miles to kilometers or Fahrenheit to Celsius, while introducing key concepts like reusable functions, dynamic UI updates, and basic mathematical operations.
Want a hands-on way to sharpen your Python skills and build something you can use daily? Dive in and build your own Python unit converter app with me as I've created a video tutorial to guide you step by step.
Python QR Code Generator App with GUI
A Python QR code generator is a fun and practical project that enhances your skills in GUI development and image processing.
Using libraries like qrcode, tkinter, and Pillow, you’ll create a user-friendly app to generate QR codes for URLs, contact info, or secret messages with just a few clicks.
Want to combine creativity with coding and build something useful?
Try building this Python QR code app with me as I've created a video walkthrough to help you follow along step by step.
Python Image Editor App with GUI
A Python image editor is a practical and creative project that enhances your programming skills. By using Pillow for image processing and tkinter for GUI development, you’ll create an app that can load, edit, and save images with filters like blur, sharpen, and more.
Want to sharpen your Python skills while building a real-world tool? Test yourself by building this image editor app in Python with me as I've created a video tutorial to to guide you every step of the way.
Python PDF Merger App with GUI
A Python PDF merger app is a practical project that combines the power of PyPDF2 for PDF manipulation and tkinter for GUI development. By using Object-Oriented Programming (OOP), you’ll create an intuitive app that allows users to select, manage, and merge multiple PDF files seamlessly.
Want to build a tool that's both useful and educational? Try your hand at building this PDF merger app with me and check out the video walkthrough I've made to guide you step by step.
Python URL Shortener App with GUI
A Python URL shortener is a fun and practical project that combines functionality with a polished GUI. Using PyQt5 for the interface and pyshorteners for URL generation, you’ll create a sleek application that shortens long URLs and copies them to the clipboard.
Want to enhance your Python skills while building a visually appealing and useful tool? Test your skills by building this URL shortener app.
Python Real-Time Error Notification App
A Python log monitoring system is a practical project to automate real-time file monitoring and notifications. Using watchdog for file changes and smtplib for email alerts, you’ll create a tool that detects critical events or errors in logs and notifies you instantly.
Want to streamline your workflow and build a tool that’s useful for developers and system admins? This project is a perfect choice, so dive in and build this error notification app.
Fun & Interactive Games
Python Hangman Game with GUI
A Python Hangman Game combines fun and practicality, making it an excellent project for both learning and showcasing your coding skills. With Tkinter for the GUI and OOP for structure, you can create a game that’s both interactive and scalable.
Want to explore how Python can bring games to life while enhancing your programming skills? Jump in and start building this Python hangman project.
Tic-Tac-Toe Game with GUI
A Tic-Tac-Toe game is a great project to learn Object-Oriented Programming (OOP), GUI design, and event handling in Python using PyQt5. This beginner-friendly project will help you master interactive UI components, button handling, and game logic implementation in Python.
By the end of this step-by-step tutorial, you'll have a fully functional Tic-Tac-Toe game where two players can compete in a graphical interface, making it an excellent portfolio project! Want to test yourself, try your hand at this tic-tac-toe project.
Blackjack Game with GUI
A Blackjack game is an exciting project that combines game logic, OOP, UI development, and event handling in Python using PyQt5. This is perfect for anyone looking to improve their Object-Oriented Programming (OOP) skills while creating an interactive, real-world game.
By the end of this blackjack project tutorial, you'll have a fully functional Blackjack game where you can play against the dealer using an intuitive graphical interface. This is a great portfolio project to demonstrate Python programming and UI development expertise.
Pac-Man Game
A Python Pac-Man game is a fun project to learn game development concepts with Pygame. This is perfect for beginners who want to learn 2D game mechanics, and collision detection.
By the end of this tutorial, you'll have a fully playable Pac-Man game where you can navigate a maze, eat pellets, and avoid ghosts—all while sharpening your Python programming skills.
Pong Arcade Game
A Pong Arcade Game is a fun project that introduces you to essential game development concepts in Python using the built-in Turtle module. This is perfect for beginners who want to learn object movement, collision detection, and user input handling in a simple yet exciting environment.
By the end of this step-by-step tutorial, you'll have a fully playable Pong game where two players can compete by controlling paddles to bounce the ball back and forth — all while building your Python skills.
Speed Typing Test
A speed typing test is a fun and challenging project that introduces essential GUI development in Python using Tkinter. This is perfect if you want to learn event handling, user input validation, and time-based calculations in an interactive environment.
By the end of this tutorial, you'll have a fully functional speed typing test where users can measure their typing speed and track their Words Per Minute (WPM).
Python Projects for Beginners
If you're new to the language or still learning Python, these are the perfect projects for you to dive into, as they're designed to help you grasp some fundamental concepts of Python programming. Plus if you're looking for some extra help, I've also released my own course, Python with Dr. Johns, where I take an academic approach to teaching while also building portfolio-worthy Python projects.
Mad Libs Generator
A Python Mad Libs Generator is a fun and interactive way to practice user input, string manipulation, and loops. This beginner-friendly project allows users to enter words that are dynamically inserted into a story template, generating hilarious and unexpected results.
Looking for a creative and engaging way to sharpen your Python skills? This Mad Libs project is the perfect choice!
Number Guessing
A Python Number Guessing Game is an exciting and beginner-friendly project that introduces random number generation, loops, and user input handling. This interactive game challenges players to guess a randomly chosen number, providing hints along the way while tracking their best score.
Looking for a fun way to practice core Python concepts while building a simple yet engaging game? This number guessing project is the perfect choice.
Rock Paper Scissors
Dice Roll Generator
A Dice Roll Generator is a simple yet engaging Python project that simulates rolling one or two dice. This project introduces random number generation, user input validation, loops, and screen clearing, making it perfect for beginners.
Want to learn how to create interactive Python programs while building a tool that can be used for board games, RPGs, or just for fun? This dice roll project is an excellent way to test yourself.
Calculator
A Python Calculator is a simple yet powerful project that allows users to perform basic arithmetic operations, exponentiation, and store or recall results using a memory feature. This project introduces user input handling, function-based modular programming, loops, and conditional logic, making it a great choice for beginners.
Want to learn how to build interactive Python programs while developing a practical tool for quick calculations? This calculator project is an excellent way to sharpen your coding skills.
Password Strength Checker
A Python password strength checker is a practical project that evaluates password security based on entropy, length, and character diversity. This introduces secure password handling, entropy calculations, user input validation, and looping for multiple checks, making it an excellent choice for beginners interested in cybersecurity.
Want to learn how to analyze password strength and improve security best practices? This password checker project is a great way to enhance your Python skills while building a useful security tool.
Countdown Clock and Timer
This Python project idea is fun! Here, we’ve created a countdown timer that asks the user for a number of seconds via user input, and it then counts down, second by second, until it displays a message.
We’ve used the Python time module’s .sleep() function to pause for 1-second intervals. We combine this with some nifty string formatting to produce the countdown display.
Source Code:
'''
Countdown Timer
-------------------------------------------------------------
'''
import time
def countdown(user_time):
while user_time >= 0:
mins, secs = divmod(user_time, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print(timer, end='\r')
time.sleep(1)
user_time -= 1
print('Lift off!')
if __name__ == '__main__':
user_time = int(input("Enter a time in seconds: "))
countdown(user_time)
Number to Words
This Python project idea converts an integer number provided via user input to its equivalent words. This program is set up to support numbers with a maximum of 12 digits, but feel free to modify the program to handle larger numbers (hint: requires conditional statements and loops).
As an easy-to-understand example of basic Python projects, this simple but effective program can expand your skills with loops, user input, and conditional statements, not to mention Python tuples and lists.
You’ll also be able to experiment with some mathematical operations that may be new to you like the modulo (%) operator to return the remainder from integer division.
If any of these techniques are new to you, you might consider installing an AI coding assistant in your Python IDE to help offer help with any code blocks you find challenging to understand.
Source Code:
'''
Numbers To Words
-------------------------------------------------------------
'''
ones = (
'Zero', 'One', 'Two', 'Three', 'Four',
'Five', 'Six', 'Seven', 'Eight', 'Nine'
)
twos = (
'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen',
'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'
)
tens = (
'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty',
'Seventy', 'Eighty', 'Ninety', 'Hundred'
)
suffixes = (
'', 'Thousand', 'Million', 'Billion'
)
def fetch_words(number, index):
if number == '0': return 'Zero'
number = number.zfill(3)
hundreds_digit = int(number[0])
tens_digit = int(number[1])
ones_digit = int(number[2])
words = '' if number[0] == '0' else ones[hundreds_digit]
if words != '':
words += ' Hundred '
if tens_digit > 1:
words += tens[tens_digit - 2]
words += ' '
words += ones[ones_digit]
elif(tens_digit == 1):
words += twos[((tens_digit + ones_digit) % 10) - 1]
elif(tens_digit == 0):
words += ones[ones_digit]
if(words.endswith('Zero')):
words = words[:-len('Zero')]
else:
words += ' '
if len(words) != 0:
words += suffixes[index]
return words
def convert_to_words(number):
length = len(str(number))
if length > 12:
return 'This program supports a maximum of 12 digit numbers.'
count = length // 3 if length % 3 == 0 else length // 3 + 1
copy = count
words = []
for i in range(length - 1, -1, -3):
words.append(fetch_words(
str(number)[0 if i - 2 < 0 else i - 2 : i + 1], copy - count))
count -= 1
final_words = ''
for s in reversed(words):
final_words += (s + ' ')
return final_words
if __name__ == '__main__':
number = int(input('Enter any number: '))
print('%d in words is: %s' %(number, convert_to_words(number)))
Fibonacci Generator
The Fibonacci numbers may be some of the most important numbers in our lives as they appear so often in nature.
The Python code below generates the Fibonacci numbers up to a certain length using recursion (yes, more recursion!). To stop the computation times from getting out of hand, we’ve implemented memoization to cache values as we calculate them.
You’ll notice that for this recursive algorithm, the base case is set to check whether the given Fibonacci sequence value is already stored in the cache. If so, it returns this (which is a constant time complexity operation), which saves a tremendous amount of computation time.
Source Code:
'''
Fibonacci Sequence
-------------------------------------------------------------
'''
fib_cache = {}
def fib_memo(input_val):
if input_val in fib_cache:
return fib_cache[input_val]
if input_val == 0:
val = 0
elif input_val < 2:
val = 1
else:
val = fib_memo(input_val - 1) + fib_memo(input_val - 2)
fib_cache[input_val] = val
return val
if __name__ == '__main__':
print('======== Fibonacci Series ========')
for i in range(1, 11):
print(f'Fibonacci ({i}) : {fib_memo(i)}')
I recently made a new project based on a reader request. The novice programmer wanted to make an age calculator in Python, but he was having trouble. That's why I wrote this article.
Like my projects above, this one contains source code and an explanation about why I used the code I used.
Practical Tools & Utilities
Python Email Sender with Gmail and SMTP
A Python Gmail SMTP Email Sender is a practical automation project that allows you to send emails programmatically. Using Python’s smtplib module and Gmail’s SMTP service, you can automate notifications, reports, and alerts while securely managing credentials with dotenv.
Want to integrate email functionality into your Python projects? This project is a great way to learn how to set up Gmail SMTP, securely storing credentials, and creating a reusable email-sending function!
Password Generator
This is an interesting Python project that uses the secrets and string modules to generate a strong and secure password, much like you can with popular password managers.
The string module obtains all possible letters, digits, and special characters, while the secrets module allows us to obtain cryptographically secure passwords.
The code for this project is relatively simple as it uses a loop to continually generate passwords until it contains at least one special character and two digits. You can, of course, modify this to fit your own super-strong password rules!
Source Code:
'''
Password Generator
-------------------------------------------------------------
'''
import secrets
import string
def create_pw(pw_length=12):
letters = string.ascii_letters
digits = string.digits
special_chars = string.punctuation
alphabet = letters + digits + special_chars
pwd = ''
pw_strong = False
while not pw_strong:
pwd = ''
for i in range(pw_length):
pwd += ''.join(secrets.choice(alphabet))
if (any(char in special_chars for char in pwd) and
sum(char in digits for char in pwd) >= 2):
pw_strong = True
return pwd
if __name__ == '__main__':
print(create_pw())
Currency Converter
This is one of several Python project ideas that require us to install one of the most popular Python libraries, which in this case, is the requests module. This is not included with the Python standard library, so use the pip command shown in the source code to install it on your system.
With the requests module, we can make HTTP requests to the Fixer API, allowing us to convert one currency to another. You’ll likely notice that we’re using a 3rd party API, so you’ll need to sign up to get a free API key. You can then enter your API key into the field shown in the source code, and you’ll be ready to go!
This project allows you to gain some more practice with loops and user input, but it expands on this with HTTP requests to retrieve API data in JSON format.
If you’re unfamiliar with JSON, it’s very similar to a Python dictionary, meaning we can access key-value pairs to fetch the data we’re after. In this case, we are looking for the currency conversion result from the API call.
Look at the docs on the Fixer API site for more details on the different data you can retrieve.
Source Code:
'''
Currency Converter
-------------------------------------------------------------
pip install requests
'''
import requests
def convert_currency():
init_currency = input('Enter an initial currency: ')
target_currency = input('Enter a target currency: ')
while True:
try:
amount = float(input('Enter the amount: '))
except:
print('The amount must be a numeric value!')
continue
if not amount > 0:
print('The amount must be greater than 0')
continue
else:
break
url = ('https://api.apilayer.com/fixer/convert?to='
+ target_currency + '&from=' + init_currency +
'&amount=' + str(amount))
payload = {}
headers = {'apikey': 'YOUR API KEY'}
response = requests.request('GET', url, headers=headers, data=payload)
status_code = response.status_code
if status_code != 200:
print('Uh oh, there was a problem. Please try again later')
quit()
result = response.json()
print('Conversion result: ' + str(result['result']))
if __name__ == '__main__':
convert_currency()
Automatic Birthday Mail Sending
This Python project uses the standard smtplib, EmailMessage, and datetime modules, in addition to pandas and openpyxl (these need to be pip installed, as shown below) to send automated birthday emails.
This program reads from an Excel sheet that contains all of your friends’ details (see Excel sheet format in source code below). It then sends them an email if today is their big day before making a note in your spreadsheet to say they’ve received their email.
We’ve used the smtplib and EmailMessage modules to create an SSL connection to our email account and message. We’ve then used a pandas dataframe to store spreadsheet-style data within the Python program (an essential skill for data scientists). Finally, we used date formatting with the datetime module’s .strftime() function.
So, lots of new skills to get to grips with!
Important note: See my project on how to set up Gmail for Python before tackling this project.
Source Code:
'''
Birthday Email Sender
-------------------------------------------------------------
pip install pandas openpyxl
excel file cols:
Name, Email, Birthday (MM/DD/YYYY), Last Sent (YYYY)
'''
import pandas as pd
from datetime import datetime
import smtplib
from email.message import EmailMessage
def send_email(recipient, subject, msg):
GMAIL_ID = 'your_email_here'
GMAIL_PWD = 'your_password_here'
email = EmailMessage()
email['Subject'] = subject
email['From'] = GMAIL_ID
email['To'] = recipient
email.set_content(msg)
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as gmail_obj:
gmail_obj.ehlo()
gmail_obj.login(GMAIL_ID, GMAIL_PWD)
gmail_obj.send_message(email)
print('Email sent to ' + str(recipient) + ' with Subject: \''
+ str(subject) + '\' and Message: \'' + str(msg) + '\'')
def send_bday_emails(bday_file):
bdays_df = pd.read_excel(bday_file)
today = datetime.now().strftime('%m-%d')
year_now = datetime.now().strftime('%Y')
sent_index = []
for idx, item in bdays_df.iterrows():
bday = item['Birthday'].to_pydatetime().strftime('%m-%d')
if (today == bday) and year_now not in str(item['Last Sent']):
msg = 'Happy Birthday ' + str(item['Name'] + '!!')
send_email(item['Email'], 'Happy Birthday', msg)
sent_index.append(idx)
for idx in sent_index:
bdays_df.loc[bdays_df.index[idx], 'Last Sent'] = str(year_now)
bdays_df.to_excel(bday_file, index=False)
if __name__ == '__main__':
send_bday_emails(bday_file='your_bdays_list.xlsx')
Site Connectivity Checker
This Python project uses the urllib and tkinter modules to test website connectivity.
We’ve used the tkinter module to create a GUI allowing users to enter a web address. Much like our previous examples, this includes labels, buttons, and entry fields.
After we’ve collected the user’s web address, we pass this to our user-defined function to return an HTTP status code for the current website via the urllib module’s .getcode() function.
For this example, we simply determine whether the HTTP code is 200. If it is, we know the site is working; otherwise, we inform the user that it is unavailable.
You could expand this code to consider a more granular approach to handling the various HTTP response codes, so feel free to add this!
Source Code:
'''
Site Connectivity Checker
-------------------------------------------------------------
Enter websites as http(s)://www.yourwebsite.com
'''
import urllib.request
import tkinter as tk
def test_connectivity():
window = tk.Tk()
window.geometry('600x400')
head = tk.Label(window, text='Website Connectivity Checker',
font=('Calibri 15'))
head.pack(pady=20)
def check_url():
web = (url.get())
status_code = urllib.request.urlopen(web).getcode()
website_is_up = status_code == 200
if website_is_up:
tk.Label(window, text='Website Available',
font=('Calibri 15')).place(x=260, y=200)
else:
tk.Label(window, text='Website Not Available',
font=('Calibri 15')).place(x=260, y=200)
url = tk.StringVar()
tk.Entry(window, textvariable=url).place(x=200, y=80, height=30, width=280)
tk.Button(window, text='Check', command=check_url).place(x=285, y=150)
window.mainloop()
if __name__ == '__main__':
test_connectivity()
Language Detector
This Python project uses the langdetect module (see pip install instructions) to help us identify the language that has been entered. This can be really useful if you’re unsure which language you’re dealing with.
This is another example where we’ve used tkinter to create a simple GUI involving labels, buttons, and an entry field. We can then collect text from the entry field and process this with the langdetect to determine which language was entered. Finally, we print this result to the GUI to let the user know the result.
Note that the results returned by langdetect are abbreviated language codes. For example, if we enter English text, we will see ‘en’ as the return value.
Source Code:
'''
Language Detector
-------------------------------------------------------------
pip install langdetect
'''
from langdetect import detect
import tkinter as tk
def detect_lang():
window = tk.Tk()
window.geometry('600x400')
head = tk.Label(window, text='Language Detector', font=('Calibri 15'))
head.pack(pady=20)
def check_language():
new_text = text.get()
lang = detect(str(new_text))
tk.Label(window, text=lang, font=('Calibri 15')).place(x=260, y=200)
text = tk.StringVar()
tk.Entry(window, textvariable=text).place(
x=200, y=80, height=30, width=280)
tk.Button(window, text='Check Language',
command=check_language).place(x=285, y=150)
window.mainloop()
if __name__ == '__main__':
detect_lang()
Text to Speech
This Python project uses a range of new libraries to convert an existing article into a playable mp3 file. You’ll need to install nltk (natural language toolkit), newspaper3k, and gtts (see pip install instructions).
You’ll see that the program is simple, as we simply pass in a URL for an article to convert, then let the function we’ve defined handle the text-to-speech conversion with our newly installed modules.
So, consider trying this out the next time you fancy turning an article into a playable podcast as it’s definitely one of the cool Python codes to copy!
Source Code:
'''
Text To Speech
-------------------------------------------------------------
pip install nltk newspaper3k gtts
'''
import nltk
from newspaper import Article
from gtts import gTTS
def text_to_speech(url):
article = Article(url)
article.download()
article.parse()
nltk.download('punkt')
article.nlp()
article_text = article.text
language = 'en'
my_obj = gTTS(text=article_text, lang=language, slow=False)
my_obj.save("read_article.mp3")
if __name__ == '__main__':
text_to_speech(
url='https://hackr.io/blog/top-tech-companies-hiring-python-developers'
)
Text Editor
This fun Python project creates a GUI to simulate our very own text editor. This example also uses standard GUI components, including labels, buttons, and entry fields.
However, we’ve also added the ability to open and save files like a real text editor. If you’re new to file handling, this Python project is a great way to understand how to read-in and save files.
Experiment with the code below to solidify your understanding, and see if you can expand on this code to create other features you’re used to using with a text editor, like a ‘find word’ function.
Source Code:
'''
Text Editor
-------------------------------------------------------------
'''
import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
def text_editor():
def open_file():
filepath = askopenfilename(
filetypes=[('Text Files', '*.txt'), ('All Files', '*.*')]
)
if not filepath:
return
txt_edit.delete(1.0, tk.END)
with open(filepath, 'r') as input_file:
text = input_file.read()
txt_edit.insert(tk.END, text)
window.title(f'TextEditor - {filepath}')
def save_file():
filepath = asksaveasfilename(
defaultextension='txt',
filetypes=[('Text Files', '*.txt'), ('All Files', '*.*')],
)
if not filepath:
return
with open(filepath, 'w') as output_file:
text = txt_edit.get(1.0, tk.END)
output_file.write(text)
window.title(f'Text Editor - {filepath}')
window = tk.Tk()
window.title('Text Editor')
window.rowconfigure(0, minsize=800, weight=1)
window.columnconfigure(1, minsize=800, weight=1)
txt_edit = tk.Text(window)
fr_buttons = tk.Frame(window, relief=tk.RAISED, bd=2)
btn_open = tk.Button(fr_buttons, text='Open', command=open_file)
btn_save = tk.Button(fr_buttons, text='Save As...', command=save_file)
btn_open.grid(row=0, column=0, sticky='ew', padx=5, pady=5)
btn_save.grid(row=1, column=0, sticky='ew', padx=5)
fr_buttons.grid(row=0, column=0, sticky='ns')
txt_edit.grid(row=0, column=1, sticky='nsew')
window.mainloop()
if __name__ == '__main__':
text_editor()
Data Structures & Algorithms
Binary Search Algorithm
It’s a rite of passage for all aspiring coders to tackle Binary Search in one of their Python programming projects at some point! I know when I was starting out, some of my most common Python mistakes involved classic algorithms like this.
This Python project for binary search takes in a sorted list (array), then continually compares a search value with the middle of the array.
Depending on whether the search value is less than or greater than the middle value, the list is split (divide and conquer strategy) to reduce the search space, which hones in on the given search value. This continual division results in logarithmic time complexity.
If you look at the code below, you’ll see that we’ve implemented two solutions: conditional loops and recursion. Both approaches are elegant, so feel free to experiment with each.
If you’re new to recursion, this is a great introduction as it demonstrates how we ‘reduce’ the size of the problem with each recursive call, namely by splitting the list to one side of the current middle element.
We’ve also defined the recursive base case as the point when the middle element equals the search element. In this case, the recursion will stop and return the True value up through the call stack.
If this all sounds alien to you, consider using something like GitHub Copilot to make more sense of this classic algorithm.
Source Code:
'''
Binary Search
-------------------------------------------------------------
'''
def binary_search(a_list, an_item):
first = 0
last = len(a_list) - 1
while first <= last:
mid_point = (first + last) // 2
if a_list[mid_point] == an_item:
return True
else:
if an_item < a_list[mid_point]:
last = mid_point - 1
else:
first = mid_point + 1
return False
def binary_search_rec(a_list, first, last, an_item):
if len(a_list) == 0:
return False
else:
mid_point = (first + last) // 2
if a_list[mid_point] == an_item:
return True
else:
if an_item < a_list[mid_point]:
last = mid_point - 1
return binary_search_rec(a_list, first, last, an_item)
else:
first = mid_point + 1
return binary_search_rec(a_list, first, last, an_item)
if __name__ == '__main__':
a_list = [1, 4, 7, 10, 14, 19, 102, 2575, 10000]
print('Binary Search:', binary_search(a_list, 4))
print('Binary Search Recursive:',
binary_search_rec(a_list, 0, len(a_list) -1, 4))
Merge Sort Algorithm
Merge Sort is another popular coding challenge faced by aspiring coders when looking for things to do in Python.
This divide-and-conquer strategy uses division to separate a list of numbers into equal parts, and these are then recursively sorted before being recombined to generate a sorted list.
If you’ve just completed the Binary Search example, you might notice some similarities with division and reducing a problem’s size. You’d be right, which means you’ve likely realized we need to use recursion.
This Python implementation of Merge Sort uses recursion to handle the divide and conquer process. The continual reduction of the problem size allows the problem to be solved when the recursive base case is reached, namely when the problem size is one element or less.
In essence, this Python program continues to recursively divide the list until it reaches the base case. At this point it begins sorting the smaller parts of the problem, resulting in smaller sorted arrays that are recombined to eventually generate a fully sorted array. If you’re familiar with Big O notation, you’ll be curious to know that Merge Sort has a Big O of (n logn).
Source Code:
'''
Merge Sort
-------------------------------------------------------------
'''
def merge_sort(a_list):
print("Dividing ", a_list)
if len(a_list) > 1:
mid_point = len(a_list)//2
left_half = a_list[:mid_point]
right_half = a_list[mid_point:]
merge_sort(left_half)
merge_sort(right_half)
i=0
j=0
k=0
while i < len(left_half) and j < len(right_half):
if left_half[i] <= right_half[j]:
a_list[k] = left_half[i]
i += 1
else:
a_list[k] = right_half[j]
j += 1
k += 1
while i < len(left_half):
a_list[k] = left_half[i]
i += 1
k += 1
while j < len(right_half):
a_list[k] = right_half[j]
j += 1
k += 1
print("Merging ", a_list)
if __name__ == '__main__':
a_list = [45, 7, 85, 24, 60, 25, 38, 63, 1]
merge_sort(a_list)
print(a_list)
Queue
This Python project creates a new class to implement a Queue. This is a common data structure in computer science when you need to handle First-In-First-Out (FIFO) scenarios, such as message queues, CPU tasks, etc.
The code is straightforward and offers some more practice with object-oriented programming. Test out the queue to get your head around how it works, and then you’ll be ready to use this data structure in your other projects.
Source Code:
'''
Queue Data Structure
-------------------------------------------------------------
'''
class Queue:
def __init__(self):
self.items = []
def __repr__(self):
return f'Queue object: data={self.items}'
def is_empty(self):
return not self.items
def enqueue(self, item):
self.items.append(item)
def dequeue(self):
return self.items.pop(0)
def size(self):
return len(self.items)
def peek(self):
return self.items[0]
if __name__ == '__main__':
q = Queue()
print(q.is_empty())
q.enqueue('First')
q.enqueue('Second')
print(q)
print(q.dequeue())
print(q)
print(q.size())
print(q.peek())
Sudoku Solver
This Python project uses the pygame library (see pip install instructions) to implement a GUI for automatically solving sudoku puzzles. We use several user-defined functions to create the GUI, as shown below.
To solve a sudoku puzzle, this program uses a backtracking algorithm that incrementally checks for solutions, either adopting or abandoning the current solution if it’s not viable.
This step of abandoning a solution is the defining feature of a backtracking approach, as the program steps back to try a new solution until it finds a valid one. This process is incrementally carried out until the entire grid has been correctly filled.
Feel free to experiment with different sudoku problems, and even think about expanding the size of the problem grid (you’ll need a new base image if you do this).
Source Code:
'''
Sudoku Solver
-------------------------------------------------------------
pip install pygame
image link:
https://www.pngitem.com/pimgs/m/210-2106648_empty-sudoku-grid-grid-6x6-png-transparent-png.png
'''
import pygame
pygame.font.init()
screen = pygame.display.set_mode((600, 600))
pygame.display.set_caption('SUDOKU SOLVER USING BACKTRACKING')
img = pygame.image.load('icon.png')
pygame.display.set_icon(img)
font1 = pygame.font.SysFont('comicsans', 40)
font2 = pygame.font.SysFont('comicsans', 20)
x = 0
y = 0
dif = 500 / 9
val = 0
# Default Sudoku Board
grid = [
[7, 8, 0, 4, 0, 0, 1, 2, 0],
[6, 0, 0, 0, 7, 5, 0, 0, 9],
[0, 0, 0, 6, 0, 1, 0, 7, 8],
[0, 0, 7, 0, 4, 0, 2, 6, 0],
[0, 0, 1, 0, 5, 0, 9, 3, 0],
[9, 0, 4, 0, 6, 0, 0, 0, 5],
[0, 7, 0, 3, 0, 0, 0, 1, 2],
[1, 2, 0, 0, 0, 7, 4, 0, 0],
[0, 4, 9, 2, 0, 6, 0, 0, 7]
]
def get_coord(pos):
x = pos[0] // dif
y = pos[1] // dif
def draw_box():
for i in range(2):
pygame.draw.line(screen, (255, 0, 0), (x * dif-3, (y + i)
* dif), (x * dif + dif + 3, (y + i)*dif), 7)
pygame.draw.line(screen, (255, 0, 0), ((x + i) * dif,
y * dif), ((x + i) * dif, y * dif + dif), 7)
def draw():
for i in range(9):
for j in range(9):
if grid[i][j] != 0:
pygame.draw.rect(screen, (0, 153, 153),
(i * dif, j * dif, dif + 1, dif + 1))
text1 = font1.render(str(grid[i][j]), 1, (0, 0, 0))
screen.blit(text1, (i * dif + 15, j * dif + 15))
for i in range(10):
if i % 3 == 0:
thick = 7
else:
thick = 1
pygame.draw.line(screen, (0, 0, 0), (0, i * dif),
(500, i * dif), thick)
pygame.draw.line(screen, (0, 0, 0), (i * dif, 0),
(i * dif, 500), thick)
def draw_val(val):
text1 = font1.render(str(val), 1, (0, 0, 0))
screen.blit(text1, (x * dif + 15, y * dif + 15))
def raise_error_1():
text1 = font1.render('WRONG !!!', 1, (0, 0, 0))
screen.blit(text1, (20, 570))
def raise_error_2():
text1 = font1.render('Wrong !!! Not a valid Key', 1, (0, 0, 0))
screen.blit(text1, (20, 570))
def valid(m, i, j, val):
for it in range(9):
if m[i][it] == val:
return False
if m[it][j] == val:
return False
it = i // 3
jt = j // 3
for i in range(it * 3, it * 3 + 3):
for j in range(jt * 3, jt * 3 + 3):
if m[i][j] == val:
return False
return True
def solve(grid, i, j):
while grid[i][j] != 0:
if i < 8:
i += 1
elif i == 8 and j < 8:
i = 0
j += 1
elif i == 8 and j == 8:
return True
pygame.event.pump()
for it in range(1, 10):
if valid(grid, i, j, it) == True:
grid[i][j] = it
x = i
y = j
screen.fill((255, 255, 255))
draw()
draw_box()
pygame.display.update()
pygame.time.delay(20)
if solve(grid, i, j) == 1:
return True
else:
grid[i][j] = 0
screen.fill((255, 255, 255))
draw()
draw_box()
pygame.display.update()
pygame.time.delay(50)
return False
def instruction():
text1 = font2.render(
'PRESS D TO RESET TO DEFAULT / R TO EMPTY\n', 1, (0, 0, 0))
text2 = font2.render(
'ENTER VALUES AND PRESS ENTER TO VISUALIZE\n', 1, (0, 0, 0))
screen.blit(text1, (20, 520))
screen.blit(text2, (20, 540))
def result():
text1 = font1.render('FINISHED PRESS R or D\n', 1, (0, 0, 0))
screen.blit(text1, (20, 570))
run = True
flag_1 = 0
flag_2 = 0
rs = 0
error = 0
while run:
screen.fill((255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
flag_1 = 1
pos = pygame.mouse.get_pos()
get_coord(pos)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x -= 1
flag_1 = 1
if event.key == pygame.K_RIGHT:
x += 1
flag_1 = 1
if event.key == pygame.K_UP:
y -= 1
flag_1 = 1
if event.key == pygame.K_DOWN:
y += 1
flag_1 = 1
if event.key == pygame.K_1:
val = 1
if event.key == pygame.K_2:
val = 2
if event.key == pygame.K_3:
val = 3
if event.key == pygame.K_4:
val = 4
if event.key == pygame.K_5:
val = 5
if event.key == pygame.K_6:
val = 6
if event.key == pygame.K_7:
val = 7
if event.key == pygame.K_8:
val = 8
if event.key == pygame.K_9:
val = 9
if event.key == pygame.K_RETURN:
flag_2 = 1
# If R pressed clear sudoku board
if event.key == pygame.K_r:
rs = 0
error = 0
flag_2 = 0
grid = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
]
# If D pressed reset board to default
if event.key == pygame.K_d:
rs = 0
error = 0
flag_2 = 0
grid = [
[7, 8, 0, 4, 0, 0, 1, 2, 0],
[6, 0, 0, 0, 7, 5, 0, 0, 9],
[0, 0, 0, 6, 0, 1, 0, 7, 8],
[0, 0, 7, 0, 4, 0, 2, 6, 0],
[0, 0, 1, 0, 5, 0, 9, 3, 0],
[9, 0, 4, 0, 6, 0, 0, 0, 5],
[0, 7, 0, 3, 0, 0, 0, 1, 2],
[1, 2, 0, 0, 0, 7, 4, 0, 0],
[0, 4, 9, 2, 0, 6, 0, 0, 7]
]
if flag_2 == 1:
if solve(grid, 0, 0) == False:
error = 1
else:
rs = 1
flag_2 = 0
if val != 0:
draw_val(val)
if valid(grid, int(x), int(y), val) == True:
grid[int(x)][int(y)] = val
flag_1 = 0
else:
grid[int(x)][int(y)] = 0
raise_error_2()
val = 0
if error == 1:
raise_error_1()
if rs == 1:
result()
draw()
if flag_1 == 1:
draw_box()
instruction()
pygame.display.update()
Bot Projects
Reddit Bot
This Python project creates an automated Reddit bot with some new modules, namely praw and enchant (see the pip install commands).
This is a fairly simple concept as the program checks every comment in a selected subreddit and then replies to any comments that contain a predefined ‘trigger phrase’. To do this, we use the praw module to interact with Reddit, and enchant to generate similar words to the comment, allowing us to make an appropriate reply.
This idea is really useful if you’re looking for Python projects to learn how to answer questions in your own subreddit. You’d just need to expand this code to include automated responses for predefined questions (you’ve probably already noticed this being used by others on Reddit!).
Important note: You’ll need to check out these instructions to get hold of a client_id, client_secret, username, password, and user_agent. You’ll need this information to make comments to Reddit via the API interface.
Source Code:
'''
Reddit Reply Bot
-------------------------------------------------------------
pip install praw pyenchant
'''
import praw
import enchant
def reddit_bot(sub, trigger_phrase):
reddit = praw.Reddit(
client_id='your_client_id',
client_secret='your_client_secret',
username='your_username',
password='your_pw',
user_agent='your_user_agent'
)
subreddit = reddit.subreddit(sub)
dict_suggest = enchant.Dict('en_US')
for comment in subreddit.stream.comments():
if trigger_phrase in comment.body.lower():
word = comment.body.replace(trigger_phrase, '')
reply_text = ''
similar_words = dict_suggest.suggest(word)
for similar in similar_words:
reply_text += (similar + ' ')
comment.reply(reply_text)
if __name__ == '__main__':
reddit_bot(sub='Python', trigger_phrase='useful bot')
Chatbot
This Python project uses the chatterbot module (see pip install instructions below) to train an automated chatbot to answer any question you ask! I know; we’re now using AI!
You’ll see that the program is one of the relatively small Python projects in this list, but feel free to explore the ChatterBot documentation along with the broader field of AI chatbots if you’d like to learn more or expand the code’s features.
If this has whet your appetite for building AI bots, check out our 24-Hour Python Chatbot course to learn how to build an AI-powered chatbot with the same tools that power OpenAI’s ChatGPT.
And if you're hungry for even more AI goodness, check out OpenAI,'s latest feature that lets you build your own GPT.
Important note: ChatterBot is no longer being actively maintained. This means you need to make a small change to the tagging.py file located in the ‘Lib/site-packages/chatterbot’ directory of your Python installation folder.
Don’t worry; it’s straightforward to do, and we’ve included the exact source code you need to use, as shown below.
Source Code:
'''
Chat Bot
-------------------------------------------------------------
1) pip install ChatterBot chatterbot-corpus spacy
2) python3 -m spacy download en_core_web_sm
Or... choose the language you prefer
3) Navigate to your Python3 directory
4) Modify Lib/site-packages/chatterbot/tagging.py
to properly load 'en_core_web_sm'
'''
from chatterbot import ChatBot
from chatterbot.trainers import ChatterBotCorpusTrainer
def create_chat_bot():
chatbot = ChatBot('Chattering Bot')
trainer = ChatterBotCorpusTrainer(chatbot)
trainer.train('chatterbot.corpus.english')
while True:
try:
bot_input = chatbot.get_response(input())
print(bot_input)
except (KeyboardInterrupt, EOFError, SystemExit):
break
if __name__ == '__main__':
create_chat_bot()
Modify tagging.py:
Find the first code snippet, which is part of the __init__ method for the PosLemmaTagger class. Replace this with the if/else statement.
Note: this example is for the English library we used in our example, but feel free to switch this out to another language if you’d prefer.
# Replace this:
self.nlp = spacy.load(self.language.ISO_639_1.lower())
# With this:
if self.language.ISO_639_1.lower() == 'en':
self.nlp = spacy.load('en_core_web_sm')
else:
self.nlp = spacy.load(self.language.ISO_639_1.lower())
Advanced Python Projects
Library Management System
As one of the more advanced Python projects, this program uses object-oriented programming to simulate a library management system.
In this example, we create a Library and Student class, which we can use to create our library system and its users. We’ve then implemented a simple user interface that asks users to select from a range of standard library actions, like borrowing or returning books.
This is a simple yet powerful example of how you can build out real-world systems via Python and object-oriented programming. Feel free to expand the classes to include other useful features, like unique book IDs, multiple copies of the same book, return dates, fees for returning books late, or any other features you think a library should have!
Source Code:
'''
Library
-------------------------------------------------------------
'''
class Library:
def __init__(self, books):
self.books = books
def show_avail_books(self):
print('Our Library Can Offer You The Following Books:')
print('================================================')
for book, borrower in self.books.items():
if borrower == 'Free':
print(book)
def lend_book(self, requested_book, name):
if self.books[requested_book] == 'Free':
print(
f'{requested_book} has been marked'
f' as \'Borrowed\' by: {name}')
self.books[requested_book] = name
return True
else:
print(
f'Sorry, the {requested_book} is currently'
f' on loan to: {self.books[requested_book]}')
return False
def return_book(self, returned_book):
self.books[returned_book] = 'Free'
print(f'Thanks for returning {returned_book}')
class Student:
def __init__(self, name, library):
self.name = name
self.books = []
self.library = library
def view_borrowed(self):
if not self.books:
print('You haven\'t borrowed any books')
else:
for book in self.books:
print(book)
def request_book(self):
book = input(
'Enter the name of the book you\'d like to borrow >> ')
if self.library.lend_book(book, self.name):
self.books.append(book)
def return_book(self):
book = input(
'Enter the name of the book you\'d like to return >> ')
if book in self.books:
self.library.return_book(book)
else:
print('You haven\'t borrowed that book, try another...')
def create_lib():
books = {
'The Last Battle': 'Free',
'The Hunger Games': 'Free',
'Cracking the Coding Interview': 'Free'
}
library = Library(books)
student_example = Student('Your Name', library)
while True:
print('''
==========LIBRARY MENU===========
1. Display Available Books
2. Borrow a Book
3. Return a Book
4. View Your Books
5. Exit'''
)
choice = int(input('Enter Choice: '))
if choice == 1:
print()
library.show_avail_books()
elif choice == 2:
print()
student_example.request_book()
elif choice == 3:
print()
student_example.return_book()
elif choice == 4:
print()
student_example.view_borrowed()
elif choice == 5:
print('Goodbye')
exit()
if __name__ == '__main__':
create_lib()
Netflix Recommendation System
To cap it all off, we’ve saved a particularly exciting Python project for last! This is a Netflix recommendation system, ideal for aspiring data scientists. In fact, if you’re considering a machine learning course, this is a great project to reinforce your new skills.
To create this project, you’ll need to import a range of modules, including tkinter, re, nltk, pandas, and numpy (see pip install instructions for new modules). You’ll also need to download a Kaggle dataset containing Netflix movies and TV shows.
We’ll use tkinter to create our GUI, which will use labels, buttons, and entry fields. The user will then be able to enter a TV show or movie they enjoyed on Netflix to return recommendations based on their taste.
The recommendation engine uses cast, director, ratings, country, and genres as machine learning (ML) ‘features’. The code then uses the ‘cosine similarity’ approach to find similar results based on user input. This extensively uses pandas and numpy to clean the data and prepare it for processing.
There is a lot to unpack in this example, as it uses lots of Python concepts for data science.
The best approach is to slowly work through the code and then carry out further research on Machine Learning (ML), ‘features’, and ‘cosine similarity’.
You’ll then be able to understand how to use a dataset to derive recommendations based on similarities. If you’re an aspiring data scientist, this is a terrific project to get your feet wet!
Source Code:
'''
Netflix Recommendation Engine
-------------------------------------------------------------
pip install pandas numpy nltk
'''
from nltk.tokenize import word_tokenize
import numpy as np
import pandas as pd
import re
import nltk
import tkinter as tk
from nltk.corpus import stopwords
nltk.download('stopwords')
data = pd.read_csv('netflixData.csv')
data = data.dropna(subset=['Cast', 'Production Country', 'Rating'])
movies = data[data['Content Type'] == 'Movie'].reset_index()
movies = movies.drop(['index', 'Show Id', 'Content Type', 'Date Added',
'Release Date', 'Duration', 'Description'], axis=1)
movies.head()
tv = data[data['Content Type'] == 'TV Show'].reset_index()
tv = tv.drop(['index', 'Show Id', 'Content Type', 'Date Added',
'Release Date', 'Duration', 'Description'], axis=1)
tv.head()
actors = []
for i in movies['Cast']:
actor = re.split(r', \s*', i)
actors.append(actor)
flat_list = []
for sublist in actors:
for item in sublist:
flat_list.append(item)
actors_list = sorted(set(flat_list))
binary_actors = [[0] * 0 for i in range(len(set(flat_list)))]
for i in movies['Cast']:
k = 0
for j in actors_list:
if j in i:
binary_actors[k].append(1.0)
else:
binary_actors[k].append(0.0)
k += 1
binary_actors = pd.DataFrame(binary_actors).transpose()
directors = []
for i in movies['Director']:
if pd.notna(i):
director = re.split(r', \s*', i)
directors.append(director)
flat_list_2 = []
for sublist in directors:
for item in sublist:
flat_list_2.append(item)
directors_list = sorted(set(flat_list_2))
binary_directors = [[0] * 0 for i in range(len(set(flat_list_2)))]
for i in movies['Director']:
k = 0
for j in directors_list:
if pd.isna(i):
binary_directors[k].append(0.0)
elif j in i:
binary_directors[k].append(1.0)
else:
binary_directors[k].append(0.0)
k += 1
binary_directors = pd.DataFrame(binary_directors).transpose()
countries = []
for i in movies['Production Country']:
country = re.split(r', \s*', i)
countries.append(country)
flat_list_3 = []
for sublist in countries:
for item in sublist:
flat_list_3.append(item)
countries_list = sorted(set(flat_list_3))
binary_countries = [[0] * 0 for i in range(len(set(flat_list_3)))]
for i in movies['Production Country']:
k = 0
for j in countries_list:
if j in i:
binary_countries[k].append(1.0)
else:
binary_countries[k].append(0.0)
k += 1
binary_countries = pd.DataFrame(binary_countries).transpose()
genres = []
for i in movies['Genres']:
genre = re.split(r', \s*', i)
genres.append(genre)
flat_list_4 = []
for sublist in genres:
for item in sublist:
flat_list_4.append(item)
genres_list = sorted(set(flat_list_4))
binary_genres = [[0] * 0 for i in range(len(set(flat_list_4)))]
for i in movies['Genres']:
k = 0
for j in genres_list:
if j in i:
binary_genres[k].append(1.0)
else:
binary_genres[k].append(0.0)
k += 1
binary_genres = pd.DataFrame(binary_genres).transpose()
ratings = []
for i in movies['Rating']:
ratings.append(i)
ratings_list = sorted(set(ratings))
binary_ratings = [[0] * 0 for i in range(len(set(ratings_list)))]
for i in movies['Rating']:
k = 0
for j in ratings_list:
if j in i:
binary_ratings[k].append(1.0)
else:
binary_ratings[k].append(0.0)
k += 1
binary_ratings = pd.DataFrame(binary_ratings).transpose()
binary = pd.concat([binary_actors, binary_directors,
binary_countries, binary_genres], axis=1, ignore_index=True)
actors_2 = []
for i in tv['Cast']:
actor2 = re.split(r', \s*', i)
actors_2.append(actor2)
flat_list_5 = []
for sublist in actors_2:
for item in sublist:
flat_list_5.append(item)
actors_list_2 = sorted(set(flat_list_5))
binary_actors_2 = [[0] * 0 for i in range(len(set(flat_list_5)))]
for i in tv['Cast']:
k = 0
for j in actors_list_2:
if j in i:
binary_actors_2[k].append(1.0)
else:
binary_actors_2[k].append(0.0)
k += 1
binary_actors_2 = pd.DataFrame(binary_actors_2).transpose()
countries_2 = []
for i in tv['Production Country']:
country2 = re.split(r', \s*', i)
countries_2.append(country2)
flat_list_6 = []
for sublist in countries_2:
for item in sublist:
flat_list_6.append(item)
countries_list_2 = sorted(set(flat_list_6))
binary_countries_2 = [[0] * 0 for i in range(len(set(flat_list_6)))]
for i in tv['Production Country']:
k = 0
for j in countries_list_2:
if j in i:
binary_countries_2[k].append(1.0)
else:
binary_countries_2[k].append(0.0)
k += 1
binary_countries_2 = pd.DataFrame(binary_countries_2).transpose()
genres_2 = []
for i in tv['Genres']:
genre2 = re.split(r', \s*', i)
genres_2.append(genre2)
flat_list_7 = []
for sublist in genres_2:
for item in sublist:
flat_list_7.append(item)
genres_list_2 = sorted(set(flat_list_7))
binary_genres_2 = [[0] * 0 for i in range(len(set(flat_list_7)))]
for i in tv['Genres']:
k = 0
for j in genres_list_2:
if j in i:
binary_genres_2[k].append(1.0)
else:
binary_genres_2[k].append(0.0)
k += 1
binary_genres_2 = pd.DataFrame(binary_genres_2).transpose()
ratings_2 = []
for i in tv['Rating']:
ratings_2.append(i)
ratings_list_2 = sorted(set(ratings_2))
binary_ratings_2 = [[0] * 0 for i in range(len(set(ratings_list_2)))]
for i in tv['Rating']:
k = 0
for j in ratings_list_2:
if j in i:
binary_ratings_2[k].append(1.0)
else:
binary_ratings_2[k].append(0.0)
k += 1
binary_ratings_2 = pd.DataFrame(binary_ratings_2).transpose()
binary_2 = pd.concat([binary_actors_2, binary_countries_2,
binary_genres_2], axis=1, ignore_index=True)
window = tk.Tk()
window.geometry('600x600')
head = tk.Label(window, text='Enter Movie / TV Show on Netflix For Recommendations', font=('Calibri 15'))
head.pack(pady=20)
def netflix_recommender(search):
cs_list = []
binary_list = []
if search in movies['Title'].values:
idx = movies[movies['Title'] == search].index.item()
for i in binary.iloc[idx]:
binary_list.append(i)
point_1 = np.array(binary_list).reshape(1, -1)
point_1 = [val for sublist in point_1 for val in sublist]
for j in range(len(movies)):
binary_list_2 = []
for k in binary.iloc[j]:
binary_list_2.append(k)
point_2 = np.array(binary_list_2).reshape(1, -1)
point_2 = [val for sublist in point_2 for val in sublist]
dot_product = np.dot(point_1, point_2)
norm_1 = np.linalg.norm(point_1)
norm_2 = np.linalg.norm(point_2)
cos_sim = dot_product / (norm_1 * norm_2)
cs_list.append(cos_sim)
movies_copy = movies.copy()
movies_copy['cos_sim'] = cs_list
results = movies_copy.sort_values('cos_sim', ascending=False)
results = results[results['title'] != search]
top_results = results.head(5)
return (top_results)
elif search in tv['Title'].values:
idx = tv[tv['Title'] == search].index.item()
for i in binary_2.iloc[idx]:
binary_list.append(i)
point_1 = np.array(binary_list).reshape(1, -1)
point_1 = [val for sublist in point_1 for val in sublist]
for j in range(len(tv)):
binary_list_2 = []
for k in binary_2.iloc[j]:
binary_list_2.append(k)
point_2 = np.array(binary_list_2).reshape(1, -1)
point_2 = [val for sublist in point_2 for val in sublist]
dot_product = np.dot(point_1, point_2)
norm_1 = np.linalg.norm(point_1)
norm_2 = np.linalg.norm(point_2)
cos_sim = dot_product / (norm_1 * norm_2)
cs_list.append(cos_sim)
tv_copy = tv.copy()
tv_copy['cos_sim'] = cs_list
results = tv_copy.sort_values('cos_sim', ascending=False)
results = results[results['Title'] != search]
top_results = results.head(5)
return (top_results)
else:
return ('Title not in dataset. Please check spelling.')
def call_recommender():
subject = text.get()
recommendation = netflix_recommender(subject)
txt = ''
for i in recommendation.iterrows():
txt += 'Title: ' + str(i[1][0]) + '\n'
tk.Label(window, text=txt, font=('Calibri 15')).place(x=195, y=150)
text = tk.StringVar()
tk.Entry(window, textvariable=text).place(x=200, y=80, height=30, width=280)
tk.Button(window, text='Find Recommendations',
command=call_recommender).place(x=285, y=150)
window.mainloop()
Where To Start With Python
Today, we’re experiencing an ever-growing adoption of Artificial Intelligence (AI), Machine Learning (ML), and data science across the vast majority of business sectors. One of the main things these fields have in common is that they use the Python programming language in one way or another.
When it comes to learning Python in 2025, you have so many choices. Plus, if you'd prefer an in-depth and interactive learning experience, we’d also recommend our new Python course.
What Should I Build Using Python?
This is a great question, especially if you’re brand new to coding in Python.
Well, first things first, you should know that there are so many Python applications in various disciplines, so you have lots of options.
Of course, Python has developed a solid reputation for data science, data analysis, machine learning, and AI, but it doesn’t end there.
It’s also really good when it comes to web development, thanks to popular web application frameworks like Django and Flask.
Equally, it’s also ideal for automating repetitive tasks, hence its origin as a scripting language.
To put it simply, you can build a lot with Python, but if you’re looking for inspiration, you’re in the right place!
That's why I put together these Python projects for you to get stuck into.
Wrapping Up
Building projects is the fastest way to learn—and now you have a list of real-world, portfolio-worthy ideas to work on.
Pick a project, start coding, and watch your Python skills grow. And remember, I’m always adding new projects, so bookmark this page and check back for more!
Happy coding!
Enjoyed tackling these Python projects and are ready to dive deeper into Python? Check out:
Our Python Masterclass - Python with Dr. Johns
References
1. Bureau of Labor Statistics, U.S. Department of Labor. Occupational Outlook Handbook, Software Developers [Internet]. [updated 2021 Sep 8; cited 2024 Jan 15]. Available from: https://www.bls.gov/ooh/computer-and-information-technology/software-developers.htm
2. apilayer. FIXER API - Pricing [Internet]. apilayer; [date unknown; cited 2024 Jan 15]. Available from: https://apilayer.com/marketplace/fixer-api#pricing
3. [no author]. OAuth2 Quick Start Example [Internet]. GitHub; [updated 2016 Apr 26; cited 2024 Jan 15]. Available from: https://github.com/reddit-archive/reddit/wiki/OAuth2-Quick-Start-Example#first-steps
4. Makhija, S. Netflix Movies and TV Shows 2021 [dataset]. Kaggle; 2021. Available from: https://www.kaggle.com/datasets/satpreetmakhija/netflix-movies-and-tv-shows-2021?resource=download