Typing Speed

Hope you are doing well. In the Twin Cities of Minneapolis and St. Paul things appear to have gone back to normal. As far as I know looting and riots have stopped. There are talks about disbanding the Minneapolis police department. Not sure what liberals are thinking. No matter where you live, social rules and laws have to be enforced so people will follow them. The approach may vary, but force needs to be present. Hopefully it is there just as a deterrent.

Talks about the terrible things happening in many police departments in different liberal cities are being blamed on the current conservative federal government. Please note that in the past 50 years the USA has been under conservative and liberal leaders. If there is blame on what triggered the last wave of looting and riots in several cities in the USA, it needs to be done using established laws. First, the involved police officers should have been put in administrative leave (not fired). Second there should be a trial in which all evidence is presented and discussed. Then the jury should come up with a verdict. If the process is fouled, then the issue should be elevated to the next court. Eventually, if not resolved to the satisfaction of all parties involved, it would reach the Supreme Court. After a decision is made at the highest legal level, people responsible at all levels (i.e., judges, lawyers, union members, politicians, and police officers) should be held accountable and sent to prison if they have done something considered unlawful. Accountability will induce changes which will make groups like “Black Lives Matter” obsolete. Looting and riots do not help the cause of black people. It only aggravates it. Not only that, but the people that lives in the areas that were looted and burned down, now will experience higher prices in stores and shops and will have to travel longer distances to get their shopping done. Thanks looters and rioters!

The governor on Minnesota did not call on the armed National Guard immediately to help contain looting and riots. It took him four days to decide on a course of action while several cities were burning. Finally, when the National Guard was called, they were not authorized to use live ammo. Not much changed until the FBI informed the governor of MN that there was a “credible threat” to the safety of the National Guard that they switched to live ammo. Looting and riots stopped that day. I guess force does work!

Lately Nancy Pelosi and Joe Biden have been attending liberal events to show their support for the person that died while under police custody which started looting and riots, and the movement “Black Lives Matter”. Allegedly those two liberals are innocent bystanders calling for change. What is completely wrong with this picture??? Both liberals have been in politics and power for at least the past forty (40) years and have not done a thing for black minorities. If there is people to blame for police brutality, people needs to first look at career politicians (I would suggest politicians at large) and held them accountable. Whoops word accountable continues to show up as something voters must consider when casting their votes (a friendly reminder to liberals that only one vote per person from legal voters is allowed) during the next presidential elections.

Sorry about spending so much time on a different subject on this post. I will try to avoid this from happening again. Things have been going great for the USA and most countries in the world, until the Chinese pandemic. We all need to work together to prevent this from ever repeating. Regardless of skin color, race, religion, and country of origin, we all need to pick up where we left before the pandemic started, and work to make all our lives greater than before. Governments need to pass legislation to all companies to completely disengage production in China. The communist government in China plays with a set different of rules and do not care for their own people most of whom are treated as brain washed slaves working in most cases six days a week twelve hours a day (72 hours a week).

OK, enough is enough. The subject of this post is to cover some experimenting I did with code here included during a LinkedIn course in JavaScript that I am taking. I should be done with the course by the end of this week. I wish I could spend more time on it but work comes first!

I used the Atom editor on this code. Of interest to me was JavaScript and less HTML and CSS.

For starters I created a repository on GitHub. I added a short README.md file.

# **** ****
C:\Users\johnc>dir
05/29/2020  03:46 PM    <DIR>          .
05/29/2020  03:46 PM    <DIR>          ..
05/13/2020  03:07 PM                57 .angular-config.json
06/08/2020  10:24 AM    <DIR>          .atom
05/13/2020  03:03 PM    <DIR>          .config
09/22/2019  08:00 AM    <DIR>          .eclipse
03/15/2020  08:38 AM                59 .gitconfig
04/23/2020  11:11 AM    <DIR>          .p2
05/07/2020  08:11 AM         1,005,502 .pipwin
04/21/2020  08:07 AM    <DIR>          .pylint.d
09/22/2019  08:00 AM    <DIR>          .tooling
03/10/2020  03:53 PM    <DIR>          .vscode
06/09/2020  01:42 PM    <DIR>          3D Objects
06/09/2020  01:42 PM    <DIR>          Contacts
04/08/2020  07:59 AM    <DIR>          ContainsCloseNums
02/17/2020  03:52 PM    <DIR>          Documents
06/09/2020  01:42 PM    <DIR>          Downloads
09/22/2019  07:57 AM    <DIR>          eclipse
09/22/2019  07:59 AM    <DIR>          eclipse-workspace_0
06/09/2020  01:42 PM    <DIR>          Favorites
06/09/2020  01:42 PM    <DIR>          Links
06/09/2020  01:42 PM    <DIR>          Music
05/13/2020  03:49 PM    <DIR>          my-app
09/12/2019  04:36 PM    <DIR>          NCH Software Suite
06/10/2020  07:24 AM    <DIR>          OneDrive
05/04/2020  03:42 PM    <DIR>          pipwin
06/09/2020  01:42 PM    <DIR>          Saved Games
06/09/2020  01:42 PM    <DIR>          Searches
05/11/2020  03:04 PM    <DIR>          source
06/09/2020  01:42 PM    <DIR>          Videos
05/05/2020  01:30 PM    <DIR>          vimfiles
06/07/2020  08:06 AM    <DIR>          workspace0
05/05/2020  01:51 PM             3,281 _viminfo

# **** ****
C:\Users\johnc>cd workspace0

# **** clone the repo ****
C:\Users\johnc\workspace0>git clone https://github.com/JohnCanessa/TypingSpeed.git
Cloning into 'TypingSpeed'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 921 bytes | 7.00 KiB/s, done.

# **** ****
C:\Users\johnc\workspace0>cd TypingSpeed

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>dir
06/10/2020  10:50 AM    <DIR>          .
06/10/2020  10:50 AM    <DIR>          ..
06/10/2020  10:50 AM               560 README.md

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>type README.md
# TypingSpeed
Exercise from the JavaScript Essential Training course from LinkedIn by Morten Rand-Hendriksen.

The code for this repository is based on an exercise from the course.
As usual I like to try different things to make sure I understand the concepts being explained.
At this time I just needed a refresher on JavaScript for a different project.
I did not expand the exercise with some of the suggestions made by the instructor.

For additional information please visit the associated post at th efollowing URI:

<T.B.D.>

Enjoy;

John

Once the repo was created I cloned it to one of my Windows 10 machines. I have not experienced any problems with JavaScript or Atom on my computer.

<!DOCTYPE html>
<html lang="en-US">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>JS Typing Speed Test</title>
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22script.js%22%20async%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,700,700i,900,900i" type="text/css" media="all">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    



<header class="masthead">
        



<h1>Test Your Typing Speed</h1>




    </header>




    <main class="main">
        



<article class="intro">
            

This is a typing test. Your goal is to duplicate the provided text, EXACTLY, in the field below. The timer starts when you start typing, and only stops when you match this text exactly. Good Luck!

        </article>




<!-- .intro -->
        



<section class="test-area">

            



<div id="origin-text">
                

Type this text.

            </div>




<!-- #origin-text -->

            



<div class="test-wrapper">
                <textarea id="test-area" name="textarea" rows="6" placeholder="The clock starts when you start typing."></textarea>
            </div>




<!-- .test-wrapper -->

            



<div class="meta">
                



<section id="clock">
                    



<div class="timer">00:00:00</div>




                </section>





                <button id="reset">Start over</button>
            </div>




<!-- .meta -->
        </section>




<!-- .test-area -->
    </main>

</body>

</html>

The HTML is short and simple. The code displays an area in which the user should type in the text that is presented. In our case the text is static. It was discussed that we could modify the software to present different text.

We also have the time that is taking for the user to enter the text. As soon as the user starts typing, the counter displays the time in “minutes:seconds:tenths of a second” it takes to enter the specified text without typos. Finally we have a reset button that clears the process and allows the user to start all over.

The frame of the area in which the user enters text is initially presented with a grey frame. The border changes color to indicate that the user is entering the proper text (blue frame) made a typo (red frame) and is done typing (green frame).

/*--------------------------------------------------------------
Typography
--------------------------------------------------------------*/

body,
button,
input,
select,
textarea {
	font-family: 'Source Sans Pro', 'Helvetica', Arial, sans-serif;
	font-size: 18px;
	line-height: 1.5;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	clear: both;
}

p {
	margin-bottom: 1.5em;
}

b,
strong {
	font-weight: bold;
}

dfn,
cite,
em,
i {
	font-style: italic;
}

blockquote {
	margin: 0 1.5em;
}

address {
	margin: 0 0 1.5em;
}

pre {
	background: #eee;
	font-family: "Courier 10 Pitch", Courier, monospace;
	font-size: 15px;
	font-size: 1.5rem;
	line-height: 1.6;
	margin-bottom: 1.6em;
	max-width: 100%;
	overflow: auto;
	padding: 1.6em;
}

code,
kbd,
tt,
var {
	font: 15px Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
}

abbr,
acronym {
	border-bottom: 1px dotted #666;
	cursor: help;
}

mark,
ins {
	background: #fff9c0;
	text-decoration: none;
}

sup,
sub {
	font-size: 75%;
	height: 0;
	line-height: 0;
	position: relative;
	vertical-align: baseline;
}

sup {
	bottom: 1ex;
}

sub {
	top: .5ex;
}

small {
	font-size: 75%;
}

big {
	font-size: 125%;
}

/*--------------------------------------------------------------
Layout
--------------------------------------------------------------*/
body {
    margin: 0;
    padding: 0;
}

.masthead {
    padding: 1em 2em;
    background-color: #0D1B2E;
    color: white;
}

.masthead h1 {
    text-align: center;
}

.intro {
    padding: 2em 2em;
    color: #ffffff;
    background: #429890;
}


.intro p,
.test-area {
    margin: 0 auto;
    max-width: 550px;
}

.test-area {
    margin-bottom: 4em;
    padding: 0 2em;
}

.test-wrapper {
    border: 10px solid grey;
    border-radius: 10px;
}

#origin-text {
    margin: 1em 0;
    padding: 1em 1em 0;
    background-color: #ededed;
}

#origin-text p {
    margin: 0;
    padding-bottom: 1em;
}

.test-wrapper {
    height: 200%;
    display: flex;
}

.test-wrapper textarea {
    flex: 1;
}

.meta {
    margin-top: 1em;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
}

.timer {
    font-size: 3em;
    font-weight: bold;
}

#reset {
    padding: .5em 1em;
    font-size: 1.2em;
    font-weight: bold;
    color: #E95D0F;
    background: white ;
    border: 10px solid #E95D0F;
}

#reset:hover {
    color: white;
    background-color: #E95D0F;
}

The CSS code is longer than the actual HTML. At this time I am more interested in JavaScript than CSS and HTML.

// **** ****
const testWrapper = document.querySelector(".test-wrapper");
const testArea = document.querySelector("#test-area");
const originText = document.querySelector("#origin-text p").innerHTML;
const resetButton = document.querySelector("#reset");
const theTimer = document.querySelector(".timer");

// **** ****
// var timer = [0,0,0,0];
var timer = [0,0,0];

var intervalID = null;
var timerRunning = false;

// **** add leading zero to numbers 9 or below (purely for aesthetics) ****
function leadingZero(time) {
    if (time <= 9) { time = "0" + time; } return time; } // **** run a standard minute/second/hundredths timer **** function runTimer() { // **** **** let currentTime = leadingZero(timer[0]) + ":" + leadingZero(timer[1]) + ":" + leadingZero(timer[2]); theTimer.innerHTML = currentTime; // **** increment the timer by 1/100 second **** // timer[3]++; timer[2]++; // timer[0] = Math.floor((timer[3] / 100) / 60); // timer[1] = Math.floor((timer[3] / 100) - (timer[0] * 60)); // timer[2] = Math.floor(timer[3] - (timer[1] * 100) - (timer[0] * 6000)); // **** update the milliseconds and seconds **** if (timer[2] >= 100) {
    timer[2] -= 100;
    timer[1]++;
  }

  // **** update seconds and minutes ****
  if (timer[1] == 60) {
    timer[1] -= 60;
    timer[0]++;
  }
}

// **** match the text entered with the provided text on the page ****
function spellCheck() {

  // **** ****
  let textEntered = testArea.value;
  let originTextMatch = originText.substring(0, textEntered.length);

  // **** ****
  if (textEntered == originText) {
      clearInterval(intervalID);
      testWrapper.style.borderColor = "green";      // "#429890";
  } else {
      if (textEntered == originTextMatch) {
          testWrapper.style.borderColor = "blue";   // "#65CCf3";
      } else {
          testWrapper.style.borderColor = "red";    // "#E95D0F";
      }
  }
}

// **** start the timer ****
function start() {

  // **** get the number of characters in the test area ****
  let textEnterdLength = testArea.value.length;

  // **** start the timer ****
  if ((textEnterdLength === 0) && !timerRunning) {
      timerRunning = true;
      intervalID = setInterval(runTimer, 10);
  }

  // ???? ????
  // console.log(textEnterdLength);
}

// **** reset everything ****
function reset() {

  // ???? ????
  // console.log("reset button has been pressed!!!");

  // **** stop the timer (if needed) ****
  clearInterval(intervalID);

  // **** should not be needed because we cleared the interval; but it is good to reset all elements ****
  intervalID = null;

  // **** clear the timer ****
  // timer = [0,0,0,0];
  timer = [0,0,0];

  // **** flag the timer is not running ****
  timerRunning = false;

  // **** clear entered text ****
  testArea.value = "";

  // **** reset the time on the screen ****
  theTimer.innerHTML = "00:00:00";

  // **** rest the border color ****
  testWrapper.style.borderColor = "gray";
}

// **** event listeners for keyboard input and the reset ****
testArea.addEventListener("keypress", start, false);
testArea.addEventListener("keyup", spellCheck, false);
resetButton.addEventListener("click", reset, false);

We start by defining a set of variables that will allow us to access some components defined in the HTML code. I suggest looking at the HTML to make sure we are accessing the proper elements.

The original code used the timer array with four elements. When I was at the time of figuring out how to keep time, I decided to try using only three.

The following two variables are used to access the interval to stop it and a flag to let us know that the timer is running. I tried not using the timerRunning flag by just checking the intervalID. It seems to work fine.

The leadingZero function is for convenience. The timer displays using the 00:00:00 format, so we need to add leading zeros by hand or relying on a convenience function. In this case we went with the latter approach.

The runTimer function is called every time the timer ticks. In our case is each 10 milliseconds. We start by displaying time stored in the timer array. The first value is for minutes, the second for seconds and the third for tenths of milliseconds.

The commented out lines were specified to generate the digits for the minutes, seconds and tenths of milliseconds. These three lines have a few computations and function calls. You need some time to understand what is going on. I like to make things as simple as possible (KISS rule). Simple things tend to be more efficient and easier to understand and maintain.

The following block updates the milliseconds if needed. Note than 1000 milliseconds is equivalent to one second. After removing one second from the milliseconds we need to add it to the seconds.

The next block updates the seconds when a minute has been reached. It removes a minute from the seconds and add one minute to the minute counter. These two sets of operations seem to me to be simpler and easier to follow.

The spellCheck function gets the text so far entered by the user. We then make a substring of the same size to be able to match character by character what is expected and what the user entered.

The final set of lines check if the user is done and displays a green frame around the entered text. Otherwise it checks if the entered text matches the sample text. If it does it colors the frame blue indicating all is well so far. If we find a mismatch (user entered at least one wrong character), the frame turns orange. Of course you can use any color you wish to indicate different states.

The start function is called each time a key on the keyboard is pressed. We extract the number of characters in the area used to type in characters. If the length is zero and the times is not running, we flag that we have started a times with a 10 milliseconds period which will call the runTimer function each time the period expires.

The reset function is called when the user clicks on the button to reset. As you can see we need to stop and reset all values so we can start timing as soon as the user enters the first character on the following attempt.

The last three calls are used to start event listeners for different types of events. Each event is specified in the call followed by the function to be called to process the event.

I had a good time experimenting with this exercise. Hope you enjoy it. If you do, go and take the course in LinkedIn.

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        index.html
        script.js
        style.css

nothing added to commit but untracked files present (use "git add" to track)

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>git add index.html
warning: LF will be replaced by CRLF in index.html.
The file will have its original line endings in your working directory

C:\Users\johnc\workspace0\TypingSpeed>git add script.js
warning: LF will be replaced by CRLF in script.js.
The file will have its original line endings in your working directory

C:\Users\johnc\workspace0\TypingSpeed>git add style.css
warning: LF will be replaced by CRLF in style.css.
The file will have its original line endings in your working directory

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   index.html
        new file:   script.js
        new file:   style.css

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>git commit -m "base set of files"
[master 099ae70] base set of files
 3 files changed, 351 insertions(+)
 create mode 100644 index.html
 create mode 100644 script.js
 create mode 100644 style.css

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>git push origin master
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 12 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 2.96 KiB | 2.96 MiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://github.com/JohnCanessa/TypingSpeed.git
   917fb56..099ae70  master -> master

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

# **** ****
C:\Users\johnc\workspace0\TypingSpeed>git log
commit 099ae702c45354213034b00dc156eed002800f85 (HEAD -> master, origin/master, origin/HEAD)
Author: JohnCanessa <john.canessa@gmail.com>
Date:   Wed Jun 10 10:55:39 2020 -0500

    base set of files

commit 917fb567634fe8eea32436f789ab031089c7acd6
Author: John Canessa <8019504+JohnCanessa@users.noreply.github.com>
Date:   Wed Jun 10 10:49:13 2020 -0500

    Create README.md

The last set of commands, were used to update the GitHub repository with the three files we have reviewed.

The entire code for this project can be found in my GitHub repository.

If you have comments or questions regarding this, or any other post in this blog, or if you would like for me to serve of assistance with any phase in the SDLC (Software Development Life Cycle) of a project associated with a product or service, please do not hesitate and leave me a note below. If you prefer, send me a private message using the following address:  john.canessa@gmail.com. I will reply as soon as possible.

Keep on reading and experimenting. It is the best way to learn, refresh your knowledge and enhance your developer toolset!

One last thing, many thanks to all 1,126 subscribers to my blog!!!

Keep safe during the COVID-19 pandemic and help restart the world economy.

John

Twitter:  @john_canessa

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.