Created
January 15, 2023 11:13
-
-
Save codepediair/e58398a583740e29710f8ebc0cdc61b9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from tkinter import * | |
import ctypes | |
import random | |
import tkinter | |
# For a sharper window | |
# ctypes.windll.shcore.SetProcessDpiAwareness(1) | |
# Setup | |
root = Tk() | |
root.title('Type Speed Test') | |
# Setting the starting window dimensions | |
root.geometry('700x700') | |
# Setting the Font for all Labels and Buttons | |
root.option_add("*Label.Font", "consolas 30") | |
root.option_add("*Button.Font", "consolas 30") | |
# functions | |
def keyPress(event=None): | |
try: | |
if event.char.lower() == labelRight.cget('text')[0].lower(): | |
# Deleting one from the right side. | |
labelRight.configure(text=labelRight.cget('text')[1:]) | |
# Deleting one from the right side. | |
labelLeft.configure(text=labelLeft.cget('text') + event.char.lower()) | |
#set the next Letter Lavbel | |
currentLetterLabel.configure(text=labelRight.cget('text')[0]) | |
except tkinter.TclError: | |
pass | |
def resetWritingLabels(): | |
# Text List | |
possibleTexts = [ | |
'For writers, a random sentence can help them get their creative juices flowing. Since the topic of the sentence is completely unknown, it forces the writer to be creative when the sentence appears. There are a number of different ways a writer can use the random sentence for creativity. The most common way to use the sentence is to begin a story. Another option is to include it somewhere in the story. A much more difficult challenge is to use it to end a story. In any of these cases, it forces the writer to think creatively since they have no idea what sentence will appear from the tool.', | |
'The goal of Python Code is to provide Python tutorials, recipes, problem fixes and articles to beginner and intermediate Python programmers, as well as sharing knowledge to the world. Python Code aims for making everyone in the world be able to learn how to code for free. Python is a high-level, interpreted, general-purpose programming language. Its design philosophy emphasizes code readability with the use of significant indentation. Python is dynamically-typed and garbage-collected. It supports multiple programming paradigms, including structured (particularly procedural), object-oriented and functional programming. It is often described as a "batteries included" language due to its comprehensive standard library.', | |
'As always, we start with the imports. Because we make the UI with tkinter, we need to import it. We also import the font module from tkinter to change the fonts on our elements later. We continue by getting the partial function from functools, it is a genius function that excepts another function as a first argument and some args and kwargs and it will return a reference to this function with those arguments. This is especially useful when we want to insert one of our functions to a command argument of a button or a key binding.' | |
] | |
# Chosing one of the texts randomly with the choice function | |
text = random.choice(possibleTexts).lower() | |
# defining where the text is split | |
splitPoint = 0 | |
# This is where the text is that is already written | |
global labelLeft | |
labelLeft = Label(root, text=text[0:splitPoint], fg='grey') | |
labelLeft.place(relx=0.5, rely=0.5, anchor=E) | |
# Here is the text which will be written | |
global labelRight | |
labelRight = Label(root, text=text[splitPoint:]) | |
labelRight.place(relx=0.5, rely=0.5, anchor=W) | |
# This label shows the user which letter he now has to press | |
global currentLetterLabel | |
currentLetterLabel = Label(root, text=text[splitPoint], fg='grey') | |
currentLetterLabel.place(relx=0.5, rely=0.6, anchor=N) | |
# this label shows the user how much time has gone by | |
global timeleftLabel | |
timeleftLabel = Label(root, text=f'0 Seconds', fg='grey') | |
timeleftLabel.place(relx=0.5, rely=0.4, anchor=S) | |
global writeAble | |
writeAble = True | |
root.bind('<Key>', keyPress) | |
global passedSeconds | |
passedSeconds = 0 | |
# Binding callbacks to functions after a certain amount of time. | |
root.after(60000, stopTest) | |
root.after(1000, addSecond) | |
def stopTest(): | |
global writeAble | |
writeAble = False | |
# Calculating the amount of words | |
amountWords = len(labelLeft.cget('text').split(' ')) | |
# Destroy all unwanted widgets. | |
timeleftLabel.destroy() | |
currentLetterLabel.destroy() | |
labelRight.destroy() | |
labelLeft.destroy() | |
# Display the test results with a formatted string | |
global ResultLabel | |
ResultLabel = Label(root, text=f'Words per Minute: {amountWords}', fg='black') | |
ResultLabel.place(relx=0.5, rely=0.4, anchor=CENTER) | |
# Display a button to restart the game | |
global ResultButton | |
ResultButton = Button(root, text=f'Retry', command=restart) | |
ResultButton.place(relx=0.5, rely=0.6, anchor=CENTER) | |
def restart(): | |
# Destry result widgets | |
ResultLabel.destroy() | |
ResultButton.destroy() | |
# re-setup writing labels. | |
resetWritingLabels() | |
def addSecond(): | |
# Add a second to the counter. | |
global passedSeconds | |
passedSeconds += 1 | |
timeleftLabel.configure(text=f'{passedSeconds} Seconds') | |
# call this function again after one second if the time is not over. | |
if writeAble: | |
root.after(1000, addSecond) | |
# This will start the Test | |
resetWritingLabels() | |
# Start the mainloop | |
root.mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment