Need a discount on popular programming courses? Find them here. View offers


Disclosure: Hackr.io is supported by its audience. When you purchase through links on our site, we may earn an affiliate commission.



30 Cool, Easy & Fun Python Projects with Source Code [2023]

Posted in Python
Python Projects

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.

Becoming a master in Python can open many doors in your career, allowing you to land some of the best job opportunities on the planet. Regardless of your current Python capabilities, knowing how to build Python projects is a surefire way to boost your skills and build your portfolio.

And while Python books and Python tutorials are hugely helpful, nothing beats getting your hands dirty with some actual coding and trying out Python project ideas!

In this article, we’ve listed 30 interesting Python projects, ranging from simple Python projects for beginners to intermediate and advanced Python project ideas, which you can use to challenge yourself or improve your Python programming skills.

Python Projects for Beginners

1. Mad Libs Generator 

This is one of the most fun beginner Python projects, not to mention it lets you practice how to use strings, variables, and concatenation.

The Mad Libs Generator gathers and manipulates user input data as an adjective, a pronoun, and a verb. The program takes this data and arranges it to build a story.

Source Code:

'''
Mad Libs Generator
-------------------------------------------------------------
'''

# Questions for the user to answer

noun = input('Choose a noun: ')

p_noun = input('Choose a plural noun: ')

noun2 = input('Choose a noun: ')

place = input('Name a place: ')

adjective = input('Choose an adjective (Describing word): ')

noun3 = input('Choose a noun: ')

# Print a story from the user input

print('------------------------------------------')

print('Be kind to your', noun, '- footed', p_noun)

print('For a duck may be somebody\'s', noun2, ',')

print('Be kind to your', p_noun, 'in', place)

print('Where the weather is always', adjective, '. \n')

print('You may think that is this the', noun3, ',')

print('Well it is.')

print('------------------------------------------')

2. Number Guessing 

This beginner Python project is a fun game that generates a random number (in a certain range) that the user must guess after receiving hints. For each wrong guess the user makes, they receive extra hints, but at the cost of reducing their final score.

This program is a great way to experiment with the Python standard library, as it uses the Python random module to generate random numbers. You can also get some hands-on practice with conditional statements, print formatting, and user-defined functions.

Source Code:

'''
Number Guessing Game
-------------------------------------------------------------
'''

import random

attempts_list = []


def show_score():
  if not attempts_list:
      print('There is currently no high score, it\'s yours for the taking!')

  else:
      print(f'The current high score is {min(attempts_list)} attempts')


def start_game():
   attempts = 0
   rand_num = random.randint(1, 10)
   print('Hello traveler! Welcome to the game of guesses!')
   player_name = input('What is your name? ')
   wanna_play = input(
       f'Hi, {player_name}, would you like to play the guessing game?'
       '(Enter Yes/No): ')

   if wanna_play.lower() != 'yes':
      print('That\'s cool, Thanks!')
      exit()
   else:
       show_score()

   while wanna_play.lower() == 'yes':
       try:
           guess = int(input('Pick a number between 1 and 10: '))
           if guess < 1 or guess > 10:
               raise ValueError(
                   'Please guess a number within the given range')

           attempts += 1
           attempts_list.append(attempts)

           if guess == rand_num:
               print('Nice! You got it!')
               print(f'It took you {attempts} attempts')
               wanna_play = input(
                   'Would you like to play again? (Enter Yes/No): ')
               if wanna_play.lower() != 'yes':
                   print('That\'s cool, have a good one!')
                   break
               else:
                   attempts = 0
                   rand_num = random.randint(1, 10)
                   show_score()
                   continue
           else:
               if guess > rand_num:
                   print('It\'s lower')
               elif guess < rand_num:
                   print('It\'s higher')

       except ValueError as err:
           print('Oh no!, that is not a valid value. Try again...')
           print(err)


if __name__ == '__main__':
   start_game()

3. Rock Paper Scissors

This Rock Paper Scissors program simulates the universally popular game with functions and conditional statements. So, what better way to get these critical concepts under your belt? 

As one of many Python coding projects that imports additional libraries, this program uses the standard library’s random, os, and re modules.

Take a look at the code below, and you’ll see that this Python project idea asks the user to make the first move by passing in a character to represent rock, paper, or scissors. After evaluating the input string, the conditional logic checks for a winner.

Source Code:

'''
Rock Paper Scissors
-------------------------------------------------------------
'''


import random
import os
import re


def check_play_status():
  valid_responses = ['yes', 'no']
  while True:
      try:
          response = input('Do you wish to play again? (Yes or No): ')
          if response.lower() not in valid_responses:
              raise ValueError('Yes or No only')

          if response.lower() == 'yes':
              return True
          else:
              os.system('cls' if os.name == 'nt' else 'clear')
              print('Thanks for playing!')
              exit()

      except ValueError as err:
          print(err)


def play_rps():
   play = True
   while play:
       os.system('cls' if os.name == 'nt' else 'clear')
       print('')
       print('Rock, Paper, Scissors - Shoot!')

       user_choice = input('Choose your weapon'
                           ' [R]ock], [P]aper, or [S]cissors: ')

       if not re.match("[SsRrPp]", user_choice):
           print('Please choose a letter:')
           print('[R]ock, [P]aper, or [S]cissors')
           continue

       print(f'You chose: {user_choice}')

       choices = ['R', 'P', 'S']
       opp_choice = random.choice(choices)

       print(f'I chose: {opp_choice}')

       if opp_choice == user_choice.upper():
           print('Tie!')
           play = check_play_status()
       elif opp_choice == 'R' and user_choice.upper() == 'S':
           print('Rock beats scissors, I win!')
           play = check_play_status()
       elif opp_choice == 'S' and user_choice.upper() == 'P':
           print('Scissors beats paper! I win!')
           play = check_play_status()
       elif opp_choice == 'P' and user_choice.upper() == 'R':
           print('Paper beats rock, I win!')
           play = check_play_status()
       else:
           print('You win!\n')
           play = check_play_status()


if __name__ == '__main__':
   play_rps()

4. Dice Roll Generator

As one of the most relatable Python projects for beginners with code, this program simulates rolling one or two dice. It’s also a great way to solidify your understanding of user-defined functions, loops, and conditional statements.

As one of the Python easy projects, it’s a fairly simple program that uses the Python random module to replicate the random nature of rolling dice. You’ll also notice that we use the os module to clear the screen after you’ve rolled the dice.

Note that you can change the maximum dice value to any number, allowing you to simulate polyhedral dice often used in many board and roleplaying games.

Source Code:

'''
Dice Roll Generator
-------------------------------------------------------------
'''


import random
import os


def num_die():
  while True:
      try:
          num_dice = input('Number of dice: ')
          valid_responses = ['1', 'one', 'two', '2']
          if num_dice not in valid_responses:
              raise ValueError('1 or 2 only')
          else:
              return num_dice
      except ValueError as err:
          print(err)


def roll_dice():
   min_val = 1
   max_val = 6
   roll_again = 'y'

   while roll_again.lower() == 'yes' or roll_again.lower() == 'y':
       os.system('cls' if os.name == 'nt' else 'clear')
       amount = num_die()

       if amount == '2' or amount == 'two':
           print('Rolling the dice...')
           dice_1 = random.randint(min_val, max_val)
           dice_2 = random.randint(min_val, max_val)

           print('The values are:')
           print('Dice One: ', dice_1)
           print('Dice Two: ', dice_2)
           print('Total: ', dice_1 + dice_2)

           roll_again = input('Roll Again? ')
       else:
           print('Rolling the die...')
           dice_1 = random.randint(min_val, max_val)
           print(f'The value is: {dice_1}')

           roll_again = input('Roll Again? ')


if __name__ == '__main__':
   roll_dice()

5. Hangman Game

This is an enjoyable Python project idea to emulate the word-guessing game, Hangman. We’ve used a predefined list of words for the guessing aspect, but feel free to improve this by using a third-party dictionary API.

This Python project uses loops, functions, and string formatting to print the hangman’s progress. It also lets you experiment with the standard library's random, time, and os modules.

Specifically, we’ve used the random module to select the word to guess, the os module to clear the screen, and the time module’s .sleep() function to introduce pauses to enhance the game flow.

Source Code:

'''
Hangman Game
-------------------------------------------------------------
'''


import random
import time
import os


def play_again():
  question = 'Do You want to play again? y = yes, n = no \n'
  play_game = input(question)
  while play_game.lower() not in ['y', 'n']:
      play_game = input(question)

  if play_game.lower() == 'y':
      return True
  else:
      return False


def hangman(word):
  display = '_' * len(word)
  count = 0
  limit = 5
  letters = list(word)
  guessed = []
  while count < limit:
      guess = input(f'Hangman Word: {display} Enter your guess: \n').strip()
      while len(guess) == 0 or len(guess) > 1:
          print('Invalid input. Enter a single letter\n')
          guess = input(
              f'Hangman Word: {display} Enter your guess: \n').strip()

      if guess in guessed:
          print('Oops! You already tried that guess, try again!\n')
          continue

      if guess in letters:
          letters.remove(guess)
          index = word.find(guess)
          display = display[:index] + guess + display[index + 1:]

      else:
          guessed.append(guess)
          count += 1
          if count == 1:
              time.sleep(1)
              print('   _____ \n'
                    '  |      \n'
                    '  |      \n'
                    '  |      \n'
                    '  |      \n'
                    '  |      \n'
                    '  |      \n'
                    '__|__\n')
              print(f'Wrong guess: {limit - count} guesses remaining\n')

          elif count == 2:
              time.sleep(1)
              print('   _____ \n'
                    '  |     | \n'
                    '  |     | \n'
                    '  |      \n'
                    '  |      \n'
                    '  |      \n'
                    '  |      \n'
                    '__|__\n')
              print(f'Wrong guess: {limit - count} guesses remaining\n')

          elif count == 3:
              time.sleep(1)
              print('   _____ \n'
                    '  |     | \n'
                    '  |     | \n'
                    '  |     | \n'
                    '  |      \n'
                    '  |      \n'
                    '  |      \n'
                    '__|__\n')
              print(f'Wrong guess: {limit - count} guesses remaining\n')

          elif count == 4:
              time.sleep(1)
              print('   _____ \n'
                    '  |     | \n'
                    '  |     | \n'
                    '  |     | \n'
                    '  |     O \n'
                    '  |      \n'
                    '  |      \n'
                    '__|__\n')
              print(f'Wrong guess: {limit - count} guesses remaining\n')

          elif count == 5:
              time.sleep(1)
              print('   _____ \n'
                    '  |     | \n'
                    '  |     | \n'
                    '  |     | \n'
                    '  |     O \n'
                    '  |    /|\ \n'
                    '  |    / \ \n'
                    '__|__\n')
              print('Wrong guess. You\'ve been hanged!!!\n')
              print(f'The word was: {word}')

      if display == word:
          print(f'Congrats! You have guessed the word \'{word}\' correctly!')
          break


def play_hangman():
   print('\nWelcome to Hangman\n')
   name = input('Enter your name: ')
   print(f'Hello {name}! Best of Luck!')
   time.sleep(1)
   print('The game is about to start!\nLet\'s play Hangman!')
   time.sleep(1)
   os.system('cls' if os.name == 'nt' else 'clear')

   words_to_guess = [
       'january', 'border', 'image', 'film', 'promise', 'kids',
       'lungs', 'doll', 'rhyme', 'damage', 'plants', 'hello', 'world'
   ]
   play = True
   while play:
       word = random.choice(words_to_guess)
       hangman(word)
       play = play_again()

   print('Thanks For Playing! We expect you back again!')
   exit()


if __name__ == '__main__':
  play_hangman()

6. Password Strength Checker

This Python project lets you check whether your password is strong enough.

It does this by checking the number of letters, numbers, special characters, and whitespace characters within a given password and generating a score based on these results. So, it’s another great way to learn about conditional statements, functions, and string formatting.

We also use the string and getpass modules from the Python standard library. This allows us to access the full range of string characters to compare with our password’s character composition, while the .getpass() function lets us hide our password when we enter it.

Source Code:

'''
Password Strength Checker
-------------------------------------------------------------
'''


import string
import getpass


def check_password_strength():
   password = getpass.getpass('Enter the password: ')
   strength = 0
   remarks = ''
   lower_count = upper_count = num_count = wspace_count = special_count = 0

   for char in list(password):
       if char in string.ascii_lowercase:
           lower_count += 1
       elif char in string.ascii_uppercase:
           upper_count += 1
       elif char in string.digits:
           num_count += 1
       elif char == ' ':
           wspace_count += 1
       else:
           special_count += 1

   if lower_count >= 1:
       strength += 1
   if upper_count >= 1:
       strength += 1
   if num_count >= 1:
       strength += 1
   if wspace_count >= 1:
       strength += 1
   if special_count >= 1:
       strength += 1

   if strength == 1:
       remarks = ('That\'s a very bad password.'
           ' Change it as soon as possible.')
   elif strength == 2:
       remarks = ('That\'s a weak password.'
           ' You should consider using a tougher password.')
   elif strength == 3:
       remarks = 'Your password is okay, but it can be improved.'
   elif strength == 4:
       remarks = ('Your password is hard to guess.'
           ' But you could make it even more secure.')
   elif strength == 5:
       remarks = ('Now that\'s one hell of a strong password!!!'
           ' Hackers don\'t have a chance guessing that password!')

   print('Your password has:-')
   print(f'{lower_count} lowercase letters')
   print(f'{upper_count} uppercase letters')
   print(f'{num_count} digits')
   print(f'{wspace_count} whitespaces')
   print(f'{special_count} special characters')
   print(f'Password Score: {strength / 5}')
   print(f'Remarks: {remarks}')


def check_pwd(another_pw=False):
   valid = False
   if another_pw:
       choice = input(
           'Do you want to check another password\'s strength (y/n) : ')
   else:
       choice = input(
           'Do you want to check your password\'s strength (y/n) : ')

   while not valid:
       if choice.lower() == 'y':
           return True
       elif choice.lower() == 'n':
           print('Exiting...')
           return False
       else:
           print('Invalid input...please try again. \n')


if __name__ == '__main__':
   print('===== Welcome to Password Strength Checker =====')
   check_pw = check_pwd()
   while check_pw:
       check_password_strength()
       check_pw = check_pwd(True)

7. 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.

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)))

8. Tic-Tac-Toe

Tic-Tac-Toe is a classic two-player game that involves a nine-square grid. Each player alternately marks their space with an O or an X, and whichever player manages to mark three Os or Xs diagonally, horizontally, or vertically wins. Each player must also block their opponent while attempting to make their chain.

This is one of the most fun Python projects that is also unique for beginners as it uses object-oriented programming to create a new class called TicTacToe. We use this to represent the game's features via the class attributes and methods.

Carefully study these methods to see how we can use object-oriented programming to neatly package the various behaviors needed to simulate this game.

Some new aspects of this Python project idea for beginners include nested loops to check the grid's columns, rows, and diagonals for a winning state, along with the Python set data type, which is used to contain unique values. This program also uses the Python random module to select a random player to start the game, but this is more familiar to you now.

Source Code:

 

'''
Tic Tac Toe
-------------------------------------------------------------
'''


import random


class TicTacToe:

   def __init__(self):
       self.board = []

   def create_board(self):
       for i in range(3):
           row = []
           for j in range(3):
               row.append('-')
           self.board.append(row)

   def get_random_first_player(self):
       return random.randint(0, 1)

   def fix_spot(self, row, col, player):
       self.board[row][col] = player

   def has_player_won(self, player):
       n = len(self.board)
       board_values = set()

       # check rows
       for i in range(n):
           for j in range(n):
               board_values.add(self.board[i][j])

           if board_values == {player}:
               return True
           else:
               board_values.clear()

       # check cols
       for i in range(n):
           for j in range(n):
               board_values.add(self.board[j][i])

           if board_values == {player}:
               return True
           else:
               board_values.clear()

       # check diagonals
       for i in range(n):
           board_values.add(self.board[i][i])
       if board_values == {player}:
           return True
       else:
           board_values.clear()
      
       board_values.add(self.board[0][2])
       board_values.add(self.board[1][1])
       board_values.add(self.board[2][0])
       if board_values == {player}:
           return True
       else:
           return False

   def is_board_filled(self):
       for row in self.board:
           for item in row:
               if item == '-':
                   return False
       return True

   def swap_player_turn(self, player):
       return 'X' if player == 'O' else 'O'

   def show_board(self):
       for row in self.board:
           for item in row:
               print(item, end=' ')
           print()

   def start(self):
       self.create_board()
       player = 'X' if self.get_random_first_player() == 1 else 'O'
       game_over = False

       while not game_over:
           try:
               self.show_board()
               print(f'\nPlayer {player} turn')

               row, col = list(
                   map(int, input(
                       'Enter row & column numbers to fix spot: ').split()))
               print()

               if col is None:
                   raise ValueError(
                       'not enough values to unpack (expected 2, got 1)')

               self.fix_spot(row - 1, col - 1, player)

               game_over = self.has_player_won(player)
               if game_over:
                   print(f'Player {player} wins the game!')
                   continue

               game_over = self.is_board_filled()
               if game_over:
                   print('Match Draw!')
                   continue

               player = self.swap_player_turn(player)

           except ValueError as err:
               print(err)

       print()
       self.show_board()


if __name__ == '__main__':
  tic_tac_toe = TicTacToe()
  tic_tac_toe.start()

9. Calculator

As one of the easy Python projects, this program creates a basic calculator application with addition, subtraction, multiplication, and division functions.

This is one of the Python practice projects that are great for learning how to use loops, functions, conditional statements, user input, and string formatting. We’ve also used the Python os module to clear the screen after the user completes their calculation actions.

Sample Code:

'''
Calculator
-------------------------------------------------------------
'''


import os


def addition():
   os.system('cls' if os.name == 'nt' else 'clear')
   print('Addition')

   continue_calc = 'y'

   num_1 = float(input('Enter a number: '))
   num_2 = float(input('Enter another number: '))
   ans = num_1 + num_2
   values_entered = 2
   print(f'Current result: {ans}')

   while continue_calc.lower() == 'y':
       continue_calc = (input('Enter more (y/n): '))
       while continue_calc.lower() not in ['y', 'n']:
           print('Please enter \'y\' or \'n\'')
           continue_calc = (input('Enter more (y/n): '))

       if continue_calc.lower() == 'n':
           break
       num = float(input('Enter another number: '))
       ans += num
       print(f'Current result: {ans}')
       values_entered += 1
   return [ans, values_entered]


def subtraction():
   os.system('cls' if os.name == 'nt' else 'clear')
   print('Subtraction')

   continue_calc = 'y'

   num_1 = float(input('Enter a number: '))
   num_2 = float(input('Enter another number: '))
   ans = num_1 - num_2
   values_entered = 2
   print(f'Current result: {ans}')

   while continue_calc.lower() == 'y':
       continue_calc = (input('Enter more (y/n): '))
       while continue_calc.lower() not in ['y', 'n']:
           print('Please enter \'y\' or \'n\'')
           continue_calc = (input('Enter more (y/n): '))

       if continue_calc.lower() == 'n':
           break
       num = float(input('Enter another number: '))
       ans -= num
       print(f'Current result: {ans}')
       values_entered += 1
   return [ans, values_entered]


def multiplication():
   os.system('cls' if os.name == 'nt' else 'clear')
   print('Multiplication')

   continue_calc = 'y'

   num_1 = float(input('Enter a number: '))
   num_2 = float(input('Enter another number: '))
   ans = num_1 * num_2
   values_entered = 2
   print(f'Current result: {ans}')

   while continue_calc.lower() == 'y':
       continue_calc = (input('Enter more (y/n): '))
       while continue_calc.lower() not in ['y', 'n']:
           print('Please enter \'y\' or \'n\'')
           continue_calc = (input('Enter more (y/n): '))

       if continue_calc.lower() == 'n':
           break
       num = float(input('Enter another number: '))
       ans *= num
       print(f'Current result: {ans}')
       values_entered += 1
   return [ans, values_entered]


def division():
   os.system('cls' if os.name == 'nt' else 'clear')
   print('Division')

   continue_calc = 'y'

   num_1 = float(input('Enter a number: '))
   num_2 = float(input('Enter another number: '))
   while num_2 == 0.0:
       print('Please enter a second number > 0')
       num_2 = float(input('Enter another number: '))

   ans = num_1 / num_2
   values_entered = 2
   print(f'Current result: {ans}')

   while continue_calc.lower() == 'y':
       continue_calc = (input('Enter more (y/n): '))
       while continue_calc.lower() not in ['y', 'n']:
           print('Please enter \'y\' or \'n\'')
           continue_calc = (input('Enter more (y/n): '))

       if continue_calc.lower() == 'n':
           break
       num = float(input('Enter another number: '))
       while num == 0.0:
           print('Please enter a number > 0')
           num = float(input('Enter another number: '))
       ans /= num
       print(f'Current result: {ans}')
       values_entered += 1
   return [ans, values_entered]


def calculator():
   quit = False
   while not quit:
       results = []
       print('Simple Calculator in Python!')
       print('Enter \'a\' for addition')
       print('Enter \'s\' for substraction')
       print('Enter \'m\' for multiplication')
       print('Enter \'d\' for division')
       print('Enter \'q\' to quit')

       choice = input('Selection: ')

       if choice == 'q':
           quit = True
           continue

       if choice == 'a':
           results = addition()
           print('Ans = ', results[0], ' total inputs: ', results[1])
       elif choice == 's':
           results = subtraction()
           print('Ans = ', results[0], ' total inputs: ', results[1])
       elif choice == 'm':
           results = multiplication()
           print('Ans = ', results[0], ' total inputs: ', results[1])
       elif choice == 'd':
           results = division()
           print('Ans = ', results[0], ' total inputs: ', results[1])
       else:
           print('Sorry, invalid character')


if __name__ == '__main__':
   calculator()

10. 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)

Intermediate Python Projects With Source Code

11. 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!

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 is equal to the search element. In this case, the recursion will stop and return the True value up through the call stack.

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))

12. 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)

13. 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())

14. Currency Converter

This is one of several Python project ideas that require us to install a new Python library, in this case, 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 here. 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()

15. 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: since May 2022, Google has tightened its restrictions on ‘less secure apps’ accessing Gmail. You’ll need to follow some extra steps to use this code with your Gmail account. But don’t worry, they’re easy to do, and we’ve listed them for you.

  • Go to the ‘manage account’ page for your google account
  • Click on Security
  • Enable 2FA (use whichever method you prefer)
  • Click on ‘App Passwords’
  • Click on ‘Select App’ and select ‘Mail’
  • Click on ‘Select Device’ & select ‘Other (custom name)’, enter ‘Python Birthday App’
  • Click on ‘Generate’ then save this password

You can now use this app password in the code below to access your Gmail account with no trouble!

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')

16. 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())

17. Pascal’s Triangle

This Python project prints out Pascal’s Triangle by utilizing conditional statements and loops. It also uses the standard library’s math module and factorial function to evaluate the ‘number of combinations’ equation used to generate the values in the triangle.

Experiment with the seed number for the triangle to examine how the ‘combinations’ equation is used to generate successive values in the triangle. 

Source Code:

'''
Pascal's Triangle
-------------------------------------------------------------
Number of combinations via "n choose k" or nCk = n! / [k! * (n-k)!]
'''


from math import factorial


def pascal_triangle(n):
   for i in range(n):
       for j in range(n-i+1):
           print(end=' ')

       for j in range(i+1):
          
           print(factorial(i)//(factorial(j)*factorial(i-j)), end=' ')

       print()


if __name__ == '__main__':
   pascal_triangle(5)

18. Blackjack

As one of the most cool Python projects, this will appeal to anyone who enjoys card games, as we will emulate Blackjack. This is a super popular card game with relatively simple rules: the most important being you need 21 to win, or you need a higher score than the dealer without going bust!

This is the largest project in the list so far. It combines most of the skills we’ve already covered in previous projects, including creating classes, loops, conditional statements, importing modules, accepting user input, and string formatting.

Take your time to work through the different sections of this code, and relate it to the earlier projects to see how the different techniques work together. There’s nothing you haven’t seen before; it’s just been packaged slightly differently and combined to create a fully functional game emulator.

And we should say, try not to spend all day playing with it! But we totally understand if you do!

Source Code:

'''
Blackjack
-------------------------------------------------------------
'''


import random
import os


class Card:

   def __init__(self, card_face, value, symbol):
       self.card_face = card_face
       self.value = value
       self.symbol = symbol


def show_cards(cards, hidden):
   s = ''
   for card in cards:
       s = s + '\t ________________'
   if hidden:
       s += '\t ________________'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|                |'
   if hidden:
       s += '\t|                |'
   print(s)

   s = ''
   for card in cards:
       if card.card_face in ['J', 'Q', 'K', 'A']:
           s = s + '\t|  {}             |'.format(card.card_face)
       elif card.value == 10:
           s = s + '\t|  {}            |'.format(card.value)
       else:
           s = s + '\t|  {}             |'.format(card.value)

   if hidden:
       s += '\t|                |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|                |'
   if hidden:
       s += '\t|      * *       |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|                |'
   if hidden:
       s += '\t|    *     *     |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|                |'
   if hidden:
       s += '\t|   *       *    |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|                |'
   if hidden:
       s += '\t|   *       *    |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|       {}        |'.format(card.symbol)
   if hidden:
       s += '\t|          *     |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|                |'
   if hidden:
       s += '\t|         *      |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|                |'
   if hidden:
       s += '\t|        *       |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|                |'
   if hidden:
       s += '\t|                |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|                |'
   if hidden:
       s += '\t|                |'
   print(s)

   s = ''
   for card in cards:
       if card.card_face in ['J', 'Q', 'K', 'A']:
           s = s + '\t|            {}   |'.format(card.card_face)
       elif card.value == 10:
           s = s + '\t|           {}   |'.format(card.value)
       else:
           s = s + '\t|            {}   |'.format(card.value)
   if hidden:
       s += '\t|        *       |'
   print(s)

   s = ''
   for card in cards:
       s = s + '\t|________________|'
   if hidden:
       s += '\t|________________|'
   print(s)
   print()


def deal_card(deck):
   card = random.choice(deck)
   deck.remove(card)
   return card, deck


def play_blackjack(deck):
   player_cards = []
   dealer_cards = []
   player_score = 0
   dealer_score = 0
   os.system('clear')

   while len(player_cards) < 2:
       player_card, deck = deal_card(deck)
       player_cards.append(player_card)
       player_score += player_card.value

       # If dealt a second Ace, adjust player score
       if len(player_cards) == 2:
           if player_cards[0].value == 11 and player_cards[1].value == 11:
               player_cards[0].value = 1
               player_score -= 10

       print('PLAYER CARDS: ')
       show_cards(player_cards, False)
       print('PLAYER SCORE = ', player_score)

       input('Continue...')

       dealer_card, deck = deal_card(deck)
       dealer_cards.append(dealer_card)
       dealer_score += dealer_card.value

       # If dealt a second Ace, adjust dealer score
       # Note: adjusts 2nd card to hide that the dealer has an Ace
       if len(dealer_cards) == 2:
           if dealer_cards[0].value == 11 and dealer_cards[1].value == 11:
               dealer_cards[1].value = 1
               dealer_score -= 10

       print('DEALER CARDS: ')
       if len(dealer_cards) == 1:
           show_cards(dealer_cards, False)
           print('DEALER SCORE = ', dealer_score)
       else:
           show_cards(dealer_cards[:-1], True)
           print('DEALER SCORE = ', dealer_score - dealer_cards[-1].value)

       input('Continue...')

   if player_score == 21:
       print('PLAYER HAS A BLACKJACK!!!!')
       print('PLAYER WINS!!!!')
       quit()
   os.system('clear')

   print('DEALER CARDS: ')
   show_cards(dealer_cards[:-1], True)
   print('DEALER SCORE = ', dealer_score - dealer_cards[-1].value)
   print()
   print('PLAYER CARDS: ')
   show_cards(player_cards, False)
   print('PLAYER SCORE = ', player_score)

   while player_score < 21:
       choice = input('Enter H to Hit or S to Stand: ').upper()
       if len(choice) != 1 or (choice not in ['H', 'S']):
           os.system('clear')
           print('Invalid choice!! Try Again...')
           continue

       if choice.upper() == 'S':
           break
       else:
           player_card, deck = deal_card(deck)
           player_cards.append(player_card)
           player_score += player_card.value
           card_pos = 0

           # If dealt an Ace, adjust score for each existing Ace in hand
           while player_score > 21 and card_pos < len(player_cards):
               if player_cards[card_pos].value == 11:
                   player_cards[card_pos].value = 1
                   player_score -= 10
                   card_pos += 1
               else:
                   card_pos += 1
          
           if player_score > 21:
               break

           os.system('clear')
           print('DEALER CARDS: ')
           show_cards(dealer_cards[:-1], True)
           print('DEALER SCORE = ', dealer_score - dealer_cards[-1].value)
           print()
           print('PLAYER CARDS: ')
           show_cards(player_cards, False)
           print('PLAYER SCORE = ', player_score)

   os.system('clear')
   print('PLAYER CARDS: ')
   show_cards(player_cards, False)
   print('PLAYER SCORE = ', player_score)
   print()
   print('DEALER IS REVEALING THEIR CARDS....')
   print('DEALER CARDS: ')
   show_cards(dealer_cards, False)
   print('DEALER SCORE = ', dealer_score)

   if player_score == 21:
       print('PLAYER HAS A BLACKJACK, PLAYER WINS!!!')
       quit()

   if player_score > 21:
       print('PLAYER BUSTED!!! GAME OVER!!!')
       quit()

   input('Continue...')
   while dealer_score < 17:
       os.system('clear')
       print('DEALER DECIDES TO HIT.....')
       dealer_card, deck = deal_card(deck)
       dealer_cards.append(dealer_card)
       dealer_score += dealer_card.value

       # If dealt an Ace, adjust score for each existing Ace in hand
       card_pos = 0
       while dealer_score > 21 and card_pos < len(dealer_cards):
           if dealer_cards[card_pos].value == 11:
               dealer_cards[card_pos].value = 1
               dealer_score -= 10
               card_pos += 1
           else:
               card_pos += 1

       print('PLAYER CARDS: ')
       show_cards(player_cards, False)
       print('PLAYER SCORE = ', player_score)
       print()
       print('DEALER CARDS: ')
       show_cards(dealer_cards, False)
       print('DEALER SCORE = ', dealer_score)
       if dealer_score > 21:
           break
       input('Continue...')

   if dealer_score > 21:
       print('DEALER BUSTED!!! YOU WIN!!!')
       quit()
   elif dealer_score == 21:
       print('DEALER HAS A BLACKJACK!!! PLAYER LOSES!!!')
       quit()
   elif dealer_score == player_score:
       print('TIE GAME!!!!')
   elif player_score > dealer_score:
       print('PLAYER WINS!!!')
   else:
       print('DEALER WINS!!!')


def init_deck():
   suits = ['Spades', 'Hearts', 'Clubs', 'Diamonds']
   # UNICODE values for card symbol images
   suit_symbols = {'Hearts': '\u2661', 'Diamonds': '\u2662',
                   'Spades': '\u2664', 'Clubs': '\u2667'}
   cards = {'A': 11, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6,
            '7': 7, '8': 8, '9': 9, '10': 10, 'J': 10, 'Q': 10, 'K': 10}
   deck = []
   for suit in suits:
       for card, value in cards.items():
           deck.append(Card(card, value, suit_symbols[suit]))
   return deck


if __name__ == '__main__':
   deck = init_deck()
   play_blackjack(deck)

19. 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 reddits 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')

20. 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)}')

Advanced Python Project Ideas

21. 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.

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())

22. 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'
   )

23. 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 the user 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()

24. Pong Arcade Game

This is a really fun and interesting project as we’ve used the Python turtle module to emulate the classic arcade game Pong!

We’ve used various methods from the turtle module to create our game components and detect ball collisions with the player paddles. We’ve also defined a range of keybindings to set the user controls for the left and right player paddles. Feel free to experiment with the game’s settings to better understand how each setting works and affects the overall game.

Outside of these newly introduced turtle graphics functions, we’ve used string formatting to output the current scoreboard and user-defined functions to keep our code tidy. These are concepts you should be familiar with at this stage.

Source Code:

'''
Pong Arcade Game
-------------------------------------------------------------
'''


import turtle


def update_score(l_score, r_score, player, score_board):
   if player == 'l':
       l_score += 1
   else:
       r_score += 1

   score_board.clear()
   score_board.write('Left Player: {} -- Right Player: {}'.format(
       l_score, r_score), align='center',
       font=('Arial', 24, 'normal'))
   return l_score, r_score, score_board


def setup_game():
   screen = turtle.Screen()
   screen.title('Pong Arcade Game')
   screen.bgcolor('white')
   screen.setup(width=1000, height=600)

   l_paddle = turtle.Turtle()
   l_paddle.speed(0)
   l_paddle.shape('square')
   l_paddle.color('red')
   l_paddle.shapesize(stretch_wid=6, stretch_len=2)
   l_paddle.penup()
   l_paddle.goto(-400, 0)

   r_paddle = turtle.Turtle()
   r_paddle.speed(0)
   r_paddle.shape('square')
   r_paddle.color('black')
   r_paddle.shapesize(stretch_wid=6, stretch_len=2)
   r_paddle.penup()
   r_paddle.goto(400, 0)

   ball = turtle.Turtle()
   ball.speed(40)
   ball.shape('circle')
   ball.color('blue')
   ball.penup()
   ball.goto(0, 0)
   ball.dx = 5
   ball.dy = -5

   score_board = turtle.Turtle()
   score_board.speed(0)
   score_board.color('blue')
   score_board.penup()
   score_board.hideturtle()
   score_board.goto(0, 260)
   score_board.write('Left Player: 0 -- Right Player: 0',
                     align='center', font=('Arial', 24, 'normal'))

   return screen, ball, l_paddle, r_paddle, score_board


def pong_game():
   game_components = setup_game()
   screen = game_components[0]
   ball = game_components[1]
   l_paddle = game_components[2]
   r_paddle = game_components[3]
   score_board = game_components[4]
   l_score = 0
   r_score = 0

   def l_paddle_up():
       l_paddle.sety(l_paddle.ycor() + 20)

   def l_paddle_down():
       l_paddle.sety(l_paddle.ycor() - 20)

   def r_paddle_up():
       r_paddle.sety(r_paddle.ycor() + 20)

   def r_paddle_down():
       r_paddle.sety(r_paddle.ycor() - 20)

   screen.listen()
   screen.onkeypress(l_paddle_up, 'e')
   screen.onkeypress(l_paddle_down, 'x')
   screen.onkeypress(r_paddle_up, 'Up')
   screen.onkeypress(r_paddle_down, 'Down')

   while True:
       screen.update()
       ball.setx(ball.xcor()+ball.dx)
       ball.sety(ball.ycor()+ball.dy)

       if ball.ycor() > 280:
           ball.sety(280)
           ball.dy *= -1

       if ball.ycor() < -280:
           ball.sety(-280)
           ball.dy *= -1

       if ball.xcor() > 500:
           ball.goto(0, 0)
           ball.dy *= -1
           l_score, r_score, score_board = update_score(
               l_score, r_score, 'l', score_board)
           continue

       elif ball.xcor() < -500:
           ball.goto(0, 0)
           ball.dy *= -1
           l_score, r_score, score_board = update_score(
               l_score, r_score, 'r', score_board)
           continue

       if ((ball.xcor() > 360) and
           (ball.xcor() < 370) and
           (ball.ycor() < r_paddle.ycor()+40) and
               (ball.ycor() > r_paddle.ycor()-40)):
           ball.setx(360)
           ball.dx *= -1

       if ((ball.xcor() < -360) and
               (ball.xcor() > -370) and
               (ball.ycor() < l_paddle.ycor()+40) and
               (ball.ycor() > l_paddle.ycor()-40)):
           ball.setx(-360)
           ball.dx *= -1


if __name__ == '__main__':
   pong_game()

25. Speed Typing Test

This is an interesting Python project that tests how quickly you can accurately type out a sentence.

This program requires us to create a graphical user interface (GUI) via the tkinter module. If you’re new to GUIs, this example is a nice introduction as we use a range of simple labels, buttons, and entry fields to create a window. We’ve also used the Python timeit module to handle the timing aspect of our typing test, and the random module to randomly select a test phrase.

We’ve only added two test phrases to this example, but feel free to experiment with more or even integrate a 3rd party dictionary for a wider array of examples.

Source Code:

'''
Speed Typing Test
-------------------------------------------------------------
'''


import tkinter
from timeit import default_timer as timer
import random


def speed_test():
   speed_test_sentences = [
       'This is a random sentence to check speed.',
       'Speed, I am lightning mcqueen.'
   ]

   sentence = random.choice(speed_test_sentences)
   start = timer()
   main_window = tkinter.Tk()
   main_window.geometry('600x400')

   label_1 = tkinter.Label(main_window, text=sentence, font='times 20')
   label_1.place(x=150, y=10)

   label_2 = tkinter.Label(main_window, text='Start Typing', font='times 20')
   label_2.place(x=10, y=50)

   entry = tkinter.Entry(main_window)
   entry.place(x=280, y=55)

   def check_result():
       if entry.get() == sentence:
           end = timer()
           label_3.configure(text=f'Time: {round((end-start), 4)}s')
       else:
           label_3.configure(text='Wrong Input')

   button_1 = tkinter.Button(main_window, text='Done',
                             command=check_result, width=12, bg='grey')
   button_1.place(x=150, y=100)

   button_2 = tkinter.Button(main_window, text='Try Again',
                             command=speed_test, width=12, bg='grey')
   button_2.place(x=250, y=100)

   label_3 = tkinter.Label(main_window, text='', font='times 20')
   label_3.place(x=10, y=300)

   main_window.mainloop()


if __name__ == '__main__':
   speed_test()

26. Text Editor

Building on our last tkinter example, 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()

27. 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()

28. 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 a 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()

29. 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()

30. 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 or machine learning enthusiasts.

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 dataset containing Netflix movies and TV shows from here

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. 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()

Conclusion 

And there you have it. We’ve covered 30 cool, fun, and exciting Python projects with source code, ranging from simple to advanced. These included games, object-oriented programming, GUIs, artificial intelligence (AI), machine learning (ML), APIs, bots, standard library modules, and several 3rd party libraries.

The one thing that each of these Python project ideas has in common is that they require you to put your theoretical Python learning into practice. By doing this, you can test yourself and improve your Python skills as you take steps to become a better practical programmer. 

Looking to build even more projects with Python? Check out the Python Mega Course to Build 10 Real-World Applications

Frequently Asked Questions

1. Is Python Suitable for Large Projects?

Although there is the argument that Python is slower than other popular languages like C and C++, Python is still widely used by many top tech companies because it is super versatile, easily maintainable, and it offers a ton of libraries and support from the community.

2. What Should My First Python Project Be?

Check out any of the Python beginner projects we’ve covered above, including Mad Libs, Rock Paper Scissors, Hangman, or Tic-Tac-Toe!

People are also reading:

Simran Kaur Arora

Simran Kaur Arora

Simran works at Hackr as a technical writer. The graduate in MS Computer Science from the well known CS hub, aka Silicon Valley, is also an editor of the website. She enjoys writing about any tech topic, including programming, algorithms, cloud, data science, and AI. Traveling, sketching, and gardening are the hobbies that interest her. View all posts by the Author

Leave a comment

Your email will not be published
Cancel
Fahad Khan
Fahad Khan

Unable to compile Tic- Tac- Toe.

Sneha Sawant
Sneha Sawant

i want explanation of Calculator program... can we have dry run for calculator program... not getting it

VIVEK
VIVEK

programs arent running, many syntax error are there....

Akib Dewan
Akib Dewan 10 Points

all codes has so many mistakes

Nikhil
Nikhil

When I was running my music player it shows error :

File "/data/user/0/ru.iiec.pydroid3/files/temp_iiec_codefile.py", line 15
root.get_themes() // Returns a list of all themes that can be set
^
SyntaxError: invalid syntax

Please tell me how i can fix it

Dnyaneshwar Borole
Dnyaneshwar Borole

Download all the libraries first