Presentation app with Claude and Python part III

Welcome to the final part of this tutorial with some experimenting about Claude and Python. I am very intrigued of the ability of Claude with coding, so, without further ado, let’s see this final part.

This is the code of the standalone version. I will add the link to the repository asap.

import pygame
import sys
import os

# Initialize Pygame
pygame.init()

# Set up the display
width, height = 1000, 700
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Sliding Image GUI")

# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (200, 200, 200)

# Button dimensions
BUTTON_WIDTH = 50
BUTTON_HEIGHT = 50
BUTTON_MARGIN = 10

# Text area dimensions
TEXT_HEIGHT = 50

def load(img):
    try:
        image = pygame.image.load(img)
        aspect_ratio = image.get_width() / image.get_height()
        new_height = height - BUTTON_HEIGHT - 2*BUTTON_MARGIN - TEXT_HEIGHT
        new_width = int(new_height * aspect_ratio)
        if new_width > width:
            new_width = width
            new_height = int(new_width / aspect_ratio)
        scaled = pygame.transform.smoothscale(image, (new_width, new_height))
        target_x = (width - new_width) // 2
        target_y = (height - BUTTON_HEIGHT - 2*BUTTON_MARGIN - TEXT_HEIGHT - new_height) // 2
    except pygame.error as e:
        print(f"Unable to load image: {img}. Error: {e}")
        pygame.quit()
        sys.exit()
    return scaled, (target_x, target_y)

# Get the current script's directory
current_dir = os.path.dirname(os.path.abspath(__file__))
print(current_dir)
# Go up one level to the project root
project_root = os.path.dirname(current_dir)
# Construct the path to the images folder
images_path = os.path.join(project_root, "images")

# Predefined slides and texts
slides_data = [{'image': 'image.png', 'texts': []}, {'image': 'image02.png', 'texts': []}, {'image': 'image03.png', 'texts': []}, {'image': 'image04.png', 'texts': []}, {'image': 'image05.png', 'texts': []}]

# Load images and prepare texts
images = [load(os.path.join(images_path, slide['image'])) for slide in slides_data]
texts = [slide['texts'][0].split("//") if slide['texts'] else [""] for slide in slides_data]

current_slide = 0
current_text_index = 0

def draw_buttons():
    buttons = [
        ("<<", BUTTON_MARGIN, height - BUTTON_HEIGHT - BUTTON_MARGIN),
        ("<", BUTTON_MARGIN * 2 + BUTTON_WIDTH, height - BUTTON_HEIGHT - BUTTON_MARGIN),
        (">", width - BUTTON_MARGIN * 2 - BUTTON_WIDTH * 2, height - BUTTON_HEIGHT - BUTTON_MARGIN),
        (">>", width - BUTTON_MARGIN - BUTTON_WIDTH, height - BUTTON_HEIGHT - BUTTON_MARGIN)
    ]
    
    for text, x, y in buttons:
        pygame.draw.rect(screen, GRAY, (x, y, BUTTON_WIDTH, BUTTON_HEIGHT))
        font = pygame.font.Font(None, 36)
        text_surface = font.render(text, True, BLACK)
        text_rect = text_surface.get_rect(center=(x + BUTTON_WIDTH/2, y + BUTTON_HEIGHT/2))
        screen.blit(text_surface, text_rect)

    # Add ">>>" button if there are multiple sentences
    if len(texts[current_slide]) > 1:
        pygame.draw.rect(screen, GRAY, (width // 2 - BUTTON_WIDTH // 2, height - BUTTON_HEIGHT // 2 - BUTTON_MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT // 2))
        font = pygame.font.Font(None, 36)
        text_surface = font.render(">>>", True, BLACK)
        text_rect = text_surface.get_rect(center=(width // 2, height - BUTTON_HEIGHT // 4 - BUTTON_MARGIN))
        screen.blit(text_surface, text_rect)

def animate_text(text):
    font = pygame.font.Font(None, 36)
    text_surface = font.render(text, True, BLACK)
    text_rect = text_surface.get_rect(center=(width // 2, height - BUTTON_HEIGHT - BUTTON_MARGIN - TEXT_HEIGHT // 2))
    
    for i in range(TEXT_HEIGHT + 1):
        screen.fill(WHITE, (0, height - BUTTON_HEIGHT - BUTTON_MARGIN - TEXT_HEIGHT, width, TEXT_HEIGHT))
        screen.blit(text_surface, (text_rect.x, height - BUTTON_HEIGHT - BUTTON_MARGIN - i))
        draw_buttons()
        pygame.display.flip()
        pygame.time.wait(10)  # Adjust for faster/slower animation

def show(numimage, text_index=0, direction="left", speed=15):
    screen.fill(WHITE)
    if numimage < len(images):
        image, pos = images[numimage]
        screen.blit(image, pos)
    draw_buttons()
    if numimage < len(texts) and text_index < len(texts[numimage]):
        animate_text(texts[numimage][text_index].strip())
    else:
        animate_text("")
    pygame.display.flip()

def main():
    global current_slide, current_text_index
    running = True
    show(current_slide, current_text_index)  # Show the first slide immediately
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    if current_text_index < len(texts[current_slide]) - 1:
                        current_text_index += 1
                    elif current_slide < len(images) - 1:
                        current_slide += 1
                        current_text_index = 0
                    show(current_slide, current_text_index, direction="left")
                elif event.key == pygame.K_LEFT:
                    if current_text_index > 0:
                        current_text_index -= 1
                    elif current_slide > 0:
                        current_slide -= 1
                        current_text_index = 0
                    show(current_slide, current_text_index, direction="right")
                elif event.key == pygame.K_UP:
                    current_slide = 0
                    current_text_index = 0
                    show(current_slide, current_text_index)
                elif event.key == pygame.K_DOWN:
                    current_slide = len(images) - 1
                    current_text_index = 0
                    show(current_slide, current_text_index)
            
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # Left mouse button
                    mouse_x, mouse_y = pygame.mouse.get_pos()
                    if mouse_y > height - BUTTON_HEIGHT - BUTTON_MARGIN:
                        if BUTTON_MARGIN < mouse_x < BUTTON_MARGIN + BUTTON_WIDTH:
                            current_slide = 0  # First slide
                            current_text_index = 0
                        elif BUTTON_MARGIN * 2 + BUTTON_WIDTH < mouse_x < BUTTON_MARGIN * 2 + BUTTON_WIDTH * 2:
                            if current_text_index > 0:
                                current_text_index -= 1
                            elif current_slide > 0:
                                current_slide -= 1
                                current_text_index = 0
                        elif width - BUTTON_MARGIN * 2 - BUTTON_WIDTH * 2 < mouse_x < width - BUTTON_MARGIN * 2 - BUTTON_WIDTH:
                            if current_text_index < len(texts[current_slide]) - 1:
                                current_text_index += 1
                            elif current_slide < len(images) - 1:
                                current_slide += 1
                                current_text_index = 0
                        elif width - BUTTON_MARGIN - BUTTON_WIDTH < mouse_x < width - BUTTON_MARGIN:
                            current_slide = len(images) - 1  # Last slide
                            current_text_index = 0
                        elif width // 2 - BUTTON_WIDTH // 2 < mouse_x < width // 2 + BUTTON_WIDTH // 2 and mouse_y > height - BUTTON_HEIGHT // 2 - BUTTON_MARGIN:
                            if current_text_index < len(texts[current_slide]) - 1:
                                current_text_index += 1
                            else:
                                current_text_index = 0
                        show(current_slide, current_text_index)
                    elif mouse_y < height - BUTTON_HEIGHT - BUTTON_MARGIN - TEXT_HEIGHT:
                        if mouse_x < width // 2:  # Left half of the screen (above buttons and text)
                            if current_text_index > 0:
                                current_text_index -= 1
                            elif current_slide > 0:
                                current_slide -= 1
                                current_text_index = 0
                            show(current_slide, current_text_index, direction="right")
                        else:  # Right half of the screen (above buttons and text)
                            if current_text_index < len(texts[current_slide]) - 1:
                                current_text_index += 1
                            elif current_slide < len(images) - 1:
                                current_slide += 1
                                current_text_index = 0
                            show(current_slide, current_text_index, direction="left")

    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()

This, instead, is the code of the editor of the presentation (always the standalone version).

import pygame
import sys
import os

# Initialize Pygame
pygame.init()

# Set up the display
width, height = 1000, 700
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Sliding Image GUI")

# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (200, 200, 200)

# Button dimensions
BUTTON_WIDTH = 50
BUTTON_HEIGHT = 50
BUTTON_MARGIN = 10

# Text area dimensions
TEXT_HEIGHT = 50

def load(img):
    try:
        image = pygame.image.load(img)
        aspect_ratio = image.get_width() / image.get_height()
        new_height = height - BUTTON_HEIGHT - 2*BUTTON_MARGIN - TEXT_HEIGHT
        new_width = int(new_height * aspect_ratio)
        if new_width > width:
            new_width = width
            new_height = int(new_width / aspect_ratio)
        scaled = pygame.transform.smoothscale(image, (new_width, new_height))
        target_x = (width - new_width) // 2
        target_y = (height - BUTTON_HEIGHT - 2*BUTTON_MARGIN - TEXT_HEIGHT - new_height) // 2
    except pygame.error as e:
        print(f"Unable to load image: {img}. Error: {e}")
        pygame.quit()
        sys.exit()
    return scaled, (target_x, target_y)

# Get the current script's directory
current_dir = os.path.dirname(os.path.abspath(__file__))
print(current_dir)
# Go up one level to the project root
project_root = os.path.dirname(current_dir)
# Construct the path to the images folder
images_path = os.path.join(project_root, "images")

# Predefined slides and texts
slides_data = [{'image': 'image.png', 'texts': []}, {'image': 'image02.png', 'texts': []}, {'image': 'image03.png', 'texts': []}, {'image': 'image04.png', 'texts': []}, {'image': 'image05.png', 'texts': []}]

# Load images and prepare texts
images = [load(os.path.join(images_path, slide['image'])) for slide in slides_data]
texts = [slide['texts'][0].split("//") if slide['texts'] else [""] for slide in slides_data]

current_slide = 0
current_text_index = 0

def draw_buttons():
    buttons = [
        ("<<", BUTTON_MARGIN, height - BUTTON_HEIGHT - BUTTON_MARGIN),
        ("<", BUTTON_MARGIN * 2 + BUTTON_WIDTH, height - BUTTON_HEIGHT - BUTTON_MARGIN),
        (">", width - BUTTON_MARGIN * 2 - BUTTON_WIDTH * 2, height - BUTTON_HEIGHT - BUTTON_MARGIN),
        (">>", width - BUTTON_MARGIN - BUTTON_WIDTH, height - BUTTON_HEIGHT - BUTTON_MARGIN)
    ]
    
    for text, x, y in buttons:
        pygame.draw.rect(screen, GRAY, (x, y, BUTTON_WIDTH, BUTTON_HEIGHT))
        font = pygame.font.Font(None, 36)
        text_surface = font.render(text, True, BLACK)
        text_rect = text_surface.get_rect(center=(x + BUTTON_WIDTH/2, y + BUTTON_HEIGHT/2))
        screen.blit(text_surface, text_rect)

    # Add ">>>" button if there are multiple sentences
    if len(texts[current_slide]) > 1:
        pygame.draw.rect(screen, GRAY, (width // 2 - BUTTON_WIDTH // 2, height - BUTTON_HEIGHT // 2 - BUTTON_MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT // 2))
        font = pygame.font.Font(None, 36)
        text_surface = font.render(">>>", True, BLACK)
        text_rect = text_surface.get_rect(center=(width // 2, height - BUTTON_HEIGHT // 4 - BUTTON_MARGIN))
        screen.blit(text_surface, text_rect)

def animate_text(text):
    font = pygame.font.Font(None, 36)
    text_surface = font.render(text, True, BLACK)
    text_rect = text_surface.get_rect(center=(width // 2, height - BUTTON_HEIGHT - BUTTON_MARGIN - TEXT_HEIGHT // 2))
    
    for i in range(TEXT_HEIGHT + 1):
        screen.fill(WHITE, (0, height - BUTTON_HEIGHT - BUTTON_MARGIN - TEXT_HEIGHT, width, TEXT_HEIGHT))
        screen.blit(text_surface, (text_rect.x, height - BUTTON_HEIGHT - BUTTON_MARGIN - i))
        draw_buttons()
        pygame.display.flip()
        pygame.time.wait(10)  # Adjust for faster/slower animation

def show(numimage, text_index=0, direction="left", speed=15):
    screen.fill(WHITE)
    if numimage < len(images):
        image, pos = images[numimage]
        screen.blit(image, pos)
    draw_buttons()
    if numimage < len(texts) and text_index < len(texts[numimage]):
        animate_text(texts[numimage][text_index].strip())
    else:
        animate_text("")
    pygame.display.flip()

def main():
    global current_slide, current_text_index
    running = True
    show(current_slide, current_text_index)  # Show the first slide immediately
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    if current_text_index < len(texts[current_slide]) - 1:
                        current_text_index += 1
                    elif current_slide < len(images) - 1:
                        current_slide += 1
                        current_text_index = 0
                    show(current_slide, current_text_index, direction="left")
                elif event.key == pygame.K_LEFT:
                    if current_text_index > 0:
                        current_text_index -= 1
                    elif current_slide > 0:
                        current_slide -= 1
                        current_text_index = 0
                    show(current_slide, current_text_index, direction="right")
                elif event.key == pygame.K_UP:
                    current_slide = 0
                    current_text_index = 0
                    show(current_slide, current_text_index)
                elif event.key == pygame.K_DOWN:
                    current_slide = len(images) - 1
                    current_text_index = 0
                    show(current_slide, current_text_index)
            
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # Left mouse button
                    mouse_x, mouse_y = pygame.mouse.get_pos()
                    if mouse_y > height - BUTTON_HEIGHT - BUTTON_MARGIN:
                        if BUTTON_MARGIN < mouse_x < BUTTON_MARGIN + BUTTON_WIDTH:
                            current_slide = 0  # First slide
                            current_text_index = 0
                        elif BUTTON_MARGIN * 2 + BUTTON_WIDTH < mouse_x < BUTTON_MARGIN * 2 + BUTTON_WIDTH * 2:
                            if current_text_index > 0:
                                current_text_index -= 1
                            elif current_slide > 0:
                                current_slide -= 1
                                current_text_index = 0
                        elif width - BUTTON_MARGIN * 2 - BUTTON_WIDTH * 2 < mouse_x < width - BUTTON_MARGIN * 2 - BUTTON_WIDTH:
                            if current_text_index < len(texts[current_slide]) - 1:
                                current_text_index += 1
                            elif current_slide < len(images) - 1:
                                current_slide += 1
                                current_text_index = 0
                        elif width - BUTTON_MARGIN - BUTTON_WIDTH < mouse_x < width - BUTTON_MARGIN:
                            current_slide = len(images) - 1  # Last slide
                            current_text_index = 0
                        elif width // 2 - BUTTON_WIDTH // 2 < mouse_x < width // 2 + BUTTON_WIDTH // 2 and mouse_y > height - BUTTON_HEIGHT // 2 - BUTTON_MARGIN:
                            if current_text_index < len(texts[current_slide]) - 1:
                                current_text_index += 1
                            else:
                                current_text_index = 0
                        show(current_slide, current_text_index)
                    elif mouse_y < height - BUTTON_HEIGHT - BUTTON_MARGIN - TEXT_HEIGHT:
                        if mouse_x < width // 2:  # Left half of the screen (above buttons and text)
                            if current_text_index > 0:
                                current_text_index -= 1
                            elif current_slide > 0:
                                current_slide -= 1
                                current_text_index = 0
                            show(current_slide, current_text_index, direction="right")
                        else:  # Right half of the screen (above buttons and text)
                            if current_text_index < len(texts[current_slide]) - 1:
                                current_text_index += 1
                            elif current_slide < len(images) - 1:
                                current_slide += 1
                                current_text_index = 0
                            show(current_slide, current_text_index, direction="left")

    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()

Explanation of the Code

This Python code demonstrates how to create an educational presentation with a graphical user interface (GUI) using the pygame library. The application allows users to navigate through slides with images and accompanying text, using both keyboard and mouse inputs. Here’s a detailed explanation of what the code does:

Initialization and Setup

  1. Initialize Pygame: The code begins by initializing the Pygame library with pygame.init().
  2. Set up the Display: It sets the display window size to 1000×700 pixels and titles it “Sliding Image GUI”.
  3. Define Colors: Colors like BLACK, WHITE, and GRAY are defined for use in the GUI.
  4. Button and Text Dimensions: Dimensions for navigation buttons and the text area are specified.

Load and Scale Images

  1. Load Images: The load(img) function loads an image, scales it to fit within the defined window, and maintains its aspect ratio.
  2. Directories for Images: The script gets the current directory, goes up one level to the project root, and constructs the path to the images folder.

Slides Data

  1. Slides Data: A list of slides is defined with image filenames and empty text arrays. The images list loads these images using the load() function, and texts prepares the texts for each slide.

Button Drawing

  1. Draw Buttons: The draw_buttons() function draws navigation buttons (<<, <, >, >>) at the bottom of the screen.

Animate Text

  1. Animate Text: The animate_text(text) function displays text with a simple animation effect, sliding it into view from the bottom.

Show Slide

  1. Show Slide: The show(numimage, text_index=0, direction="left", speed=15) function displays a specific slide image and animates the corresponding text.

Main Function

  1. Main Function: The main() function handles the main loop of the application, processing events such as keyboard and mouse inputs to navigate through the slides.

Using AI to Create Apps with Python

Artificial intelligence (AI) can greatly enhance the development of educational applications in Python by automating repetitive tasks, providing intelligent suggestions, and enabling advanced functionalities. Here are some examples of how AI can be leveraged:

  1. Automated Content Generation: AI can generate quiz questions, explanations, and educational content based on a given topic or dataset.
  2. Personalized Learning: AI can adapt the learning content and pace according to the student’s performance and preferences, making the learning experience more personalized.
  3. Interactive Tutorials: AI can create interactive tutorials that guide students through coding exercises, offering hints and correcting mistakes in real-time.
  4. Natural Language Processing: AI can understand and respond to students’ natural language queries, providing explanations, resources, or answers to their questions.

Example: Using Claude to Code in Python for Educational Purposes

Claude, an AI assistant, can assist in various aspects of coding in Python. Here’s an example of how Claude can help create an interactive quiz application for students:

Scenario: Interactive Quiz App

  1. Generating Quiz Questions: Claude can generate multiple-choice questions on Python programming topics, ensuring they cover a range of difficulty levels.
   questions = Claude.generate_quiz_questions(topic="Python Basics", num_questions=10)
  1. Creating the User Interface: Claude can suggest and generate code for a graphical user interface (GUI) using libraries like tkinter.
   import tkinter as tk

   def create_quiz_app():
       window = tk.Tk()
       window.title("Python Quiz")

       question_label = tk.Label(window, text="")
       question_label.pack()

       def next_question():
           # Logic to display the next question
           pass

       next_button = tk.Button(window, text="Next", command=next_question)
       next_button.pack()

       window.mainloop()

   create_quiz_app()
  1. Evaluating Answers: Claude can help write the logic to evaluate student responses and provide instant feedback.
   def evaluate_answer(selected_option, correct_option):
       if selected_option == correct_option:
           return "Correct!"
       else:
           return "Incorrect, try again."

   feedback = evaluate_answer(user_selected_option, correct_answer)
  1. Improving User Experience: Claude can suggest features to enhance the app, such as adding hints for difficult questions or tracking the student’s progress over time.
   def provide_hint(question):
       hint = Claude.generate_hint(question)
       return hint

   hint_button = tk.Button(window, text="Hint", command=lambda: provide_hint(current_question))
   hint_button.pack()

By leveraging AI tools like Claude, educators can develop more engaging and effective learning applications, making the process of teaching and learning programming more interactive and enjoyable.

Python Quiz

Python Quiz

A) def functionName[]:
B) functionName()
C) def functionName():
D) functionName{}
A) class MyClass:
B) MyClass()
C) create class MyClass
D) class MyClass()
A) A function that takes another function and extends its behavior
B) A class that wraps functions
C) A module that imports functions
D) A library for styling functions
A) for i in range(10)
B) for i to 10:
C) for(i=0; i<10; i++):
D) for i in 1 to 10:
A) Indentation is used to define the start and end of a block of code
B) Indentation is optional and only for readability
C) Indentation is used to define classes only
D) Indentation is used for comments


Subscribe to the newsletter for updates
Tkinter templates

Avatar My youtube channel

Twitter: @pythonprogrammi - python_pygame

Claude's Games

Arkanoid
Platform 2d

1. Memory game

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts

Advertisement