Skip to content

Commit 8d87a46

Browse files
committed
Add website typing test
1 parent f4e97ce commit 8d87a46

5 files changed

Lines changed: 177 additions & 0 deletions

File tree

code/website-typing-test/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# README
2+
3+
## ChatGPT prompts to build this website:
4+
5+
----
6+
7+
Create a website with provided text prominently displayed in black color with a highly visible and legible font. The visitor to the website must type the provided text, but is not permitted to hit the backspace, return, tab, or arrow keys or correct any mistakes -- the visitor can only keep typing. As the visitor types each character (corresponding to a letter, number, space, symbol, or punctuation mark) in the provided text, the character on the screen changes color. If the visitor types the correct key, the character changes color to green. If the visitor types an incorrect key, the character changes color to red. The website logs the timing of each keystroke with millisecond precision. The website displays the following information as a table below the text, formatted as follows. Each row corresponds to a character and the following are filled in for the columns: (1) character from the provided text, (2) character the visitor typed, (3) the number 1 if these two match each other and 0 if they don't, (4) a time stamp when the key is pressed, (5) a time stamp when the key is released. Please create the necessary documents for such a website with as few dependencies and in the simplest way possible.
8+
9+
The resulting website displays the text and the column headers for the table, but when I start typing, it searches the page rather than change the colors of the text. Also, the text is legible, but the table text is too bold and prominent.
10+
11+
At the top of the page display the text "Please touch type the following text as you would usually type -- at your usual typing speed on a keyboard of your choice. Each correctly typed character will turn green and each incorrectly typed character will turn red. You will not be able to go back or correct any mistakes. Just keep typing until you have finished."
12+
13+
----
14+
15+
## Input text for website visitor
16+
17+
At an average typing speed of 40 words per minute where a word is on average 5 characters, a person can type approximately 1,000 characters in 5 minutes.
18+
19+
ChatGPT prompt: "Generate a random text string containing 1,000 characters with only lowercase letters and the following punctuation marks , . / ; ' and include a space after every 5 characters."
20+
21+
Resulting code is in generate_string.py
22+
23+
Resulting random string:
24+
25+
p'uco wnqum i/min crj'i gt;pl pwvd. pxlxm 'smdq g[cgo ivat; jh[ud vdizb bskts nnotb dw';, u,ko. ocm/z hld.p h/cur cenvd vj/sn h/,y. gz;an mlrgm dt,.n wajf/ /r'xi /h'pp qiwvt hcb/u 'gcg[ 'yqra khbdq tfdf; sojp, zm[wj ;sj[y pczzo ktji; iegid xjkk/ ;vm.i l''n/ h'cyx sk.'f iutza 'ydf, gtqga fvuie gyqy. v[h,; ebj[/ mkzwt icw[x txliv px.c[ wurbg ./krh o.hli a;cqv nntp; rix[. wrxhq 'lmni hwhza urg[' fs[v/ qeldu eol'f ugqgu y'hbk wuqr; gd'xf c,'im l.;hs [qyt' c/yhf w'lj/ tttbg '[qp. vkvb/ .qspv .nfg' mohw. t[ntx c.qlf /o'qb b;ygs defu. y;gnv ghiz' yly.. z;mm[ cgj/w qkei, xo;uf qqjmk zqp;k cgko; .dkbn rpihv pb;[s wbiem u,lsz vabzy ,obqm tmtoj p/;[u rz;[o c/k,[ ;/;vy qsxmr c.xrd ybtm[ e'[/h amfq/ [yxnc z'prc mox'a thvnn gofxr e.tfm i.pyb xrauq kv,vs nnyed sd[hs miwfp cknsf jvxxm qeba, dquls myprm ;'qpc ;;c,. .a.[p r/qvc jo'mg ahhet ,jk'u wo.c. qtzlr ;'i., hjp/n ztpkc j;qxw l;vl, tc;lr ;qwx. utq,' rlack ddcwu i;u/j jaskd ixeye r;[s' bhpdv pulbw qcyp/ pahls yirfi xl[oz ss;xx ,gt'u ,avqm pemkd rpdk
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import string
2+
import random
3+
4+
def generate_random_string_with_specific_chars(length):
5+
# Characters that can be typed without the Shift key, only lowercase and specified punctuation
6+
chars = string.ascii_lowercase + ",./;'["
7+
8+
# Initialize the string and count for spaces
9+
random_string = ''
10+
space_count = 0
11+
12+
for _ in range(length):
13+
# Add a space after every 5 characters on average
14+
if space_count >= 5:
15+
random_string += ' '
16+
space_count = 0
17+
else:
18+
random_string += random.choice(chars)
19+
space_count += 1
20+
21+
return random_string
22+
23+
# Generate a new string with the specified characters
24+
random_text_specific = generate_random_string_with_specific_chars(1000)
25+
print(random_text_specific)
26+
len(random_text_specific) # Check the length of the generated string including spaces
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Typing Test</title>
7+
<link rel="stylesheet" href="styles.css">
8+
</head>
9+
<body>
10+
<div id="instructions">
11+
<p>Please touch type the following text as you would usually type -- at your usual typing speed on a keyboard of your choice. Each correctly typed character will turn green and each incorrectly typed character will turn red. You will not be able to go back or correct any mistakes. Just keep typing until you have finished.</p>
12+
</div>
13+
<div id="text-container"></div>
14+
<table id="keystroke-data">
15+
<thead>
16+
<tr>
17+
<th>Expected Char</th>
18+
<th>Typed Char</th>
19+
<th>Match</th>
20+
<th>Timestamp (Press)</th>
21+
<th>Timestamp (Release)</th>
22+
</tr>
23+
</thead>
24+
<tbody></tbody>
25+
</table>
26+
<script src="script.js"></script>
27+
</body>
28+
</html>

code/website-typing-test/script.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
const textToType = "p'uco wnqum i/min crj'i gt;pl pwvd. pxlxm 'smdq g[cgo ivat; jh[ud vdizb bskts nnotb dw';, u,ko. ocm/z hld.p h/cur cenvd vj/sn h/,y. gz;an mlrgm dt,.n wajf/ /r'xi /h'pp qiwvt hcb/u 'gcg[ 'yqra khbdq tfdf; sojp, zm[wj ;sj[y pczzo ktji; iegid xjkk/ ;vm.i l''n/ h'cyx sk.'f iutza 'ydf, gtqga fvuie gyqy. v[h,; ebj[/ mkzwt icw[x txliv px.c[ wurbg ./krh o.hli a;cqv nntp; rix[. wrxhq 'lmni hwhza urg[' fs[v/ qeldu eol'f ugqgu y'hbk wuqr; gd'xf c,'im l.;hs [qyt' c/yhf w'lj/ tttbg '[qp. vkvb/ .qspv .nfg' mohw. t[ntx c.qlf /o'qb b;ygs defu. y;gnv ghiz' yly.. z;mm[ cgj/w qkei, xo;uf qqjmk zqp;k cgko; .dkbn rpihv pb;[s wbiem u,lsz vabzy ,obqm tmtoj p/;[u rz;[o c/k,[ ;/;vy qsxmr c.xrd ybtm[ e'[/h amfq/ [yxnc z'prc mox'a thvnn gofxr e.tfm i.pyb xrauq kv,vs nnyed sd[hs miwfp cknsf jvxxm qeba, dquls myprm ;'qpc ;;c,. .a.[p r/qvc jo'mg ahhet ,jk'u wo.c. qtzlr ;'i., hjp/n ztpkc j;qxw l;vl, tc;lr ;qwx. utq,' rlack ddcwu i;u/j jaskd ixeye r;[s' bhpdv pulbw qcyp/ pahls yirfi xl[oz ss;xx ,gt'u ,avqm pemkd rpdk"; // Replace with your text
3+
const container = document.getElementById('text-container');
4+
container.innerHTML = textToType.split('').map(char => `<span>${char}</span>`).join('');
5+
6+
let currentIndex = 0;
7+
const keystrokeData = [];
8+
9+
document.addEventListener('keydown', (e) => {
10+
e.preventDefault(); // Prevent default browser actions
11+
if (['Backspace', 'Tab', 'ArrowLeft', 'ArrowRight', 'Enter'].includes(e.key)) {
12+
return; // Still prevent the use of these keys
13+
}
14+
15+
const keyPressTime = new Date().getTime();
16+
const currentChar = textToType[currentIndex];
17+
const span = container.getElementsByTagName('span')[currentIndex];
18+
const isCorrect = e.key === currentChar;
19+
20+
span.className = isCorrect ? 'correct' : 'incorrect';
21+
22+
keystrokeData.push({
23+
expected: currentChar,
24+
typed: e.key,
25+
match: isCorrect ? 1 : 0,
26+
pressTime: keyPressTime,
27+
releaseTime: null // This will be filled on keyup
28+
});
29+
30+
currentIndex++;
31+
updateTable();
32+
});
33+
34+
document.addEventListener('keyup', (e) => {
35+
const keyReleaseTime = new Date().getTime();
36+
if (keystrokeData[currentIndex - 1]) {
37+
keystrokeData[currentIndex - 1].releaseTime = keyReleaseTime;
38+
updateTable();
39+
}
40+
});
41+
42+
function updateTable() {
43+
const tbody = document.getElementById('keystroke-data').getElementsByTagName('tbody')[0];
44+
tbody.innerHTML = '';
45+
keystrokeData.forEach(data => {
46+
const row = tbody.insertRow();
47+
Object.values(data).forEach(text => {
48+
const cell = row.insertCell();
49+
cell.appendChild(document.createTextNode(text));
50+
});
51+
});
52+
}
53+
});
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
body {
2+
font-family: Arial, sans-serif;
3+
display: flex;
4+
flex-direction: column;
5+
align-items: center;
6+
margin: 0;
7+
padding: 0;
8+
}
9+
10+
#instructions {
11+
margin: 20px;
12+
padding: 10px;
13+
text-align: left; /* Left-justify the instructions */
14+
width: 80%; /* Adjust width as needed */
15+
}
16+
17+
#text-container {
18+
color: black;
19+
border: 1px solid #ddd;
20+
padding: 20px;
21+
margin: 20px 0;
22+
font-size: 1.5em; /* Increase the size of the provided text */
23+
width: 80%; /* Adjust width as needed */
24+
}
25+
26+
.correct {
27+
color: green;
28+
}
29+
30+
.incorrect {
31+
color: red;
32+
}
33+
34+
table {
35+
border-collapse: collapse;
36+
width: 60%; /* Make table smaller */
37+
font-size: 0.8em; /* Decrease font size in the table */
38+
margin-top: 500px; /* Push the table far down the page */
39+
}
40+
41+
th, td {
42+
border: 1px solid black;
43+
text-align: left;
44+
padding: 8px;
45+
}

0 commit comments

Comments
 (0)