
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
- Initialize Pygame: The code begins by initializing the Pygame library with
pygame.init(). - Set up the Display: It sets the display window size to 1000×700 pixels and titles it “Sliding Image GUI”.
- Define Colors: Colors like BLACK, WHITE, and GRAY are defined for use in the GUI.
- Button and Text Dimensions: Dimensions for navigation buttons and the text area are specified.
Load and Scale Images
- Load Images: The
load(img)function loads an image, scales it to fit within the defined window, and maintains its aspect ratio. - 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
- Slides Data: A list of slides is defined with image filenames and empty text arrays. The
imageslist loads these images using theload()function, andtextsprepares the texts for each slide.
Button Drawing
- Draw Buttons: The
draw_buttons()function draws navigation buttons (<<, <, >, >>) at the bottom of the screen.
Animate Text
- Animate Text: The
animate_text(text)function displays text with a simple animation effect, sliding it into view from the bottom.
Show Slide
- 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
- 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:
- Automated Content Generation: AI can generate quiz questions, explanations, and educational content based on a given topic or dataset.
- Personalized Learning: AI can adapt the learning content and pace according to the student’s performance and preferences, making the learning experience more personalized.
- Interactive Tutorials: AI can create interactive tutorials that guide students through coding exercises, offering hints and correcting mistakes in real-time.
- 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
- 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)
- 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()
- 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)
- 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
Subscribe to the newsletter for updates
Tkinter templatesTwitter: @pythonprogrammi - python_pygame
Claude's Games
1. Memory gameVideos
Speech recognition gamePygame's Platform Game