I’m creating a simple web app that tests a user’s typing speed. I have a start button in the html which starts a timer, an input text field for the user to type something, and a stop button that stops the time, extracts what the user typed, and records results.
Eventually, I want to be able to load up a sample text for the user to type to record both speed and accuracy. But I cannot seem to get what the user types into the form input field.
Here is my python code:
from flask import Flask, request, render_template, redirect, url_for
import time
app = Flask(__name__)
test_text = "Hello. The year is 2024."
speed = 0
accuracy = 0
user_text = " "
@app.route('/', methods =["GET", "POST"])
def home():
global t0, speed, accuracy, user_text
if request.method == "POST":
if request.form['button'] == 'Start_Button':
t0 = time.time()
elif request.form['button'] == 'Stop_Button':
t = time.time() - t0
user_text = request.form.get('users_text')
word_count = len(user_text.split(" "))
if word_count > 0:
speed = word_count / t
correct_chars = 0
for i in range(len(user_text)):
if test_text[i] == user_text[i]:
correct_chars += 1
accuracy = 100 * (correct_chars/len(user_text))
return render_template('index.html', speed=speed, accuracy=accuracy)
if __name__ == "__main__":
app.run(debug=True)
And here is the associated HTML.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../static/style.css">
</head>
<body>
<h1>Test Out Your Typing Speed</h1>
<div class="box">
<h3 id="instructions">Press the Start Button and then type in the field below. Then, press the Stop Button.
</h3>
</div>
<div class="box">
<form method="post" action="/">
<button type="submit" id="Start_Button" name="button" value="Start_Button">Start</button>
</form>
</div>
<div class="box">
<form method="post">
<input type="text" id="user_type_box" name="users_text" placeholder="Type here">
</form>
</div>
<div class="box">
<form method="post" action="/">
<button type="submit" id="Stop_Button" name="button" value="Stop_Button">Stop</button>
</form>
</div>
<h3>Typing Speed: {{speed}}</h3>
<h3>Accuracy: {{accuracy}}</h3>
</html>
I looked online at geeks for geeks article which said to use request.form.get method for input form field. I can’t get it to work right. The flask error message I get is that python cannot execute split on variable of type NoneType, which tells me that the python code is not assigning anything to variable to store the user text.
>Solution :
When you click on a submit button, it only sends the input fields that are in the same form. By default these are the fields that are within the same <form> and </form>, although other inputs can be associated with the form using the form="formID" attribute.
Since you have the text input in a different form from the stop button, the input text isn’t submitted when you click the button. Wrap the form around both inputs.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../static/style.css">
</head>
<body>
<h1>Test Out Your Typing Speed</h1>
<div class="box">
<h3 id="instructions">Press the Start Button and then type in the field below. Then, press the Stop Button.
</h3>
</div>
<div class="box">
<form method="post" action="/">
<button type="submit" id="Start_Button" name="button" value="Start_Button">Start</button>
</form>
</div>
<form method="post" action="/">
<div class="box">
<input type="text" id="user_type_box" name="users_text" placeholder="Type here">
</div>
<div class="box">
<button type="submit" id="Stop_Button" name="button" value="Stop_Button">Stop</button>
</div>
</form>
<h3>Typing Speed: {{speed}}</h3>
<h3>Accuracy: {{accuracy}}</h3>
</html>