|
| 1 | +import tkinter as tk |
| 2 | +import time |
| 3 | +import random |
| 4 | + |
| 5 | +# Sentences pool |
| 6 | +sentences = [ |
| 7 | + "Python is powerful and easy to learn.", |
| 8 | + "Typing fast helps improve productivity.", |
| 9 | + "Keep practicing to increase your speed.", |
| 10 | + "Focus on accuracy before speed.", |
| 11 | + "Consistency is the key to mastery.", |
| 12 | + "Coding improves logical thinking.", |
| 13 | +] |
| 14 | + |
| 15 | +class TypingSpeedGame: |
| 16 | + def __init__(self, root): |
| 17 | + self.root = root |
| 18 | + self.root.title("Typing Speed Challenge (30 Seconds)") |
| 19 | + self.root.geometry("600x350") |
| 20 | + self.root.config(bg="#f7f7f7") |
| 21 | + self.root.resizable(False, False) |
| 22 | + |
| 23 | + self.text = random.choice(sentences) |
| 24 | + self.time_left = 30 |
| 25 | + self.start_time = None |
| 26 | + self.running = False |
| 27 | + |
| 28 | + # Title |
| 29 | + tk.Label(root, text="⌨️ Typing Speed Challenge", font=("Arial", 18, "bold"), bg="#f7f7f7", fg="#222").pack(pady=10) |
| 30 | + |
| 31 | + # Instruction |
| 32 | + tk.Label(root, text="You have 30 seconds! Type the sentence below and press [Enter] to finish early.", |
| 33 | + font=("Arial", 10), bg="#f7f7f7", fg="#555").pack() |
| 34 | + |
| 35 | + # Sentence to type |
| 36 | + self.label = tk.Label(root, text=self.text, wraplength=500, font=("Arial", 14), bg="#f7f7f7", fg="#333") |
| 37 | + self.label.pack(pady=15) |
| 38 | + |
| 39 | + # Typing box |
| 40 | + self.entry = tk.Entry(root, width=60, font=("Arial", 14), bd=2, relief="solid", justify="center") |
| 41 | + self.entry.pack(pady=10) |
| 42 | + self.entry.bind("<KeyPress>", self.start_timer) |
| 43 | + self.entry.bind("<Return>", self.finish) |
| 44 | + |
| 45 | + # Timer display |
| 46 | + self.timer_label = tk.Label(root, text="Time Left: 30s", font=("Arial", 12, "bold"), bg="#f7f7f7", fg="#cc0000") |
| 47 | + self.timer_label.pack(pady=5) |
| 48 | + |
| 49 | + # Result display |
| 50 | + self.result = tk.Label(root, text="", font=("Arial", 13, "bold"), bg="#f7f7f7", fg="#007700") |
| 51 | + self.result.pack(pady=10) |
| 52 | + |
| 53 | + # Restart button |
| 54 | + self.restart_btn = tk.Button(root, text="Restart", font=("Arial", 12), bg="#007bff", fg="white", command=self.restart) |
| 55 | + self.restart_btn.pack(pady=10) |
| 56 | + |
| 57 | + self.entry.focus_set() |
| 58 | + |
| 59 | + def start_timer(self, event): |
| 60 | + if not self.running: |
| 61 | + self.running = True |
| 62 | + self.start_time = time.time() |
| 63 | + self.countdown() |
| 64 | + |
| 65 | + def countdown(self): |
| 66 | + if self.time_left > 0 and self.running: |
| 67 | + self.time_left -= 1 |
| 68 | + self.timer_label.config(text=f"Time Left: {self.time_left}s") |
| 69 | + self.root.after(1000, self.countdown) |
| 70 | + else: |
| 71 | + self.finish(None) |
| 72 | + |
| 73 | + def finish(self, event): |
| 74 | + if not self.running: |
| 75 | + return |
| 76 | + self.running = False |
| 77 | + |
| 78 | + typed = self.entry.get().strip() |
| 79 | + end_time = time.time() |
| 80 | + elapsed = end_time - self.start_time if self.start_time else 0.1 |
| 81 | + |
| 82 | + # Calculate results |
| 83 | + words_typed = len(typed.split()) |
| 84 | + words_per_minute = (words_typed / elapsed) * 60 |
| 85 | + correct_chars = sum(a == b for a, b in zip(self.text, typed)) |
| 86 | + accuracy = (correct_chars / len(self.text)) * 100 |
| 87 | + |
| 88 | + # Display results |
| 89 | + self.result.config(text=f"⏱️ Time's up!\nSpeed: {words_per_minute:.0f} WPM | Accuracy: {accuracy:.0f}%") |
| 90 | + |
| 91 | + def restart(self): |
| 92 | + self.text = random.choice(sentences) |
| 93 | + self.label.config(text=self.text) |
| 94 | + self.entry.delete(0, tk.END) |
| 95 | + self.result.config(text="") |
| 96 | + self.time_left = 30 |
| 97 | + self.timer_label.config(text="Time Left: 30s") |
| 98 | + self.running = False |
| 99 | + self.start_time = None |
| 100 | + self.entry.focus_set() |
| 101 | + |
| 102 | +# Run the app |
| 103 | +root = tk.Tk() |
| 104 | +app = TypingSpeedGame(root) |
| 105 | +root.mainloop() |
0 commit comments