Writing a Typing Speed Test CLI Application in Golang

Had to think long and hard about that title 🙄… now that we’ve gotten that out of the way, let’s write some darn code 🙂

Pumps brake 🚗 screechhhhh…. Let’s do a bit of introduction into what we will be attempting to build today. Incase the title was…


This content originally appeared on DEV Community and was authored by IamKhan

Had to think long and hard about that title 🙄... now that we've gotten that out of the way, let's write some darn code :)

Pumps brake 🚗 screechhhhh.... Let's do a bit of introduction into what we will be attempting to build today. Incase the title wasn't obvious, we will be building a CLI application that calculates your typing speed in golang - although you can literally build the same application, following the same techniques in any programming language of your choice.

Now, let's code 😎

package main

import (
    "bufio"
    "fmt"
    "log"
    "math/rand"
    "os"
    "strings"
    "time"
)

var sentences = []string{
    "There are 60 minutes in an hour, 24 hours in a day and 7 days in a week",
    "Nelson Mandela is one of the most renowned freedom fighters Africa has ever produced",
    "Nigeria is the most populous black nation in the world",
    "Peter Jackson's Lord of the rings is the greatest film of all time",
}

In our main.go file, we import the packages we will need to write our logic. We also create a slice of sentences. Feel free to add a bunch more.

// A generic helper function that randomly selects an item from a slice
func Choice[T any](ts []T) T {
    return ts[rand.Intn(len(ts))]
}

// Prompts and collects user input from the terminal
func Input(prompt string) (string, error) {
    fmt.Print(prompt)
    r := bufio.NewReader(os.Stdin)

    line, err := r.ReadString('\n')
    if err != nil {
        return "", err
    }

    return strings.Trim(line, "\n\r\t"), nil
}

// Compares two strings and keeps track of the characters  
// that match and those that don't
func CompareChars(target, source string) (int, int) {
    var valid, invalid int

    // typed some of the words
        // resize target to length of source
    if len(target) > len(source) {
        diff := len(target) - len(source)
        invalid += diff
        target = target[:len(source)]
    }

    // typed more words than required
        // resize source to length of target
    if len(target) < len(source) {
        invalid++
        source = source[:len(target)]
    }

    for i := 0; i < len(target); i++ {
        if target[i] == source[i] {
            valid++
        }
        if target[i] != source[i] {
            invalid++
        }
    }

    return valid, invalid
}

// Calculates the degree of correctness
func precision(pos, fal int) int {
    return pos / (pos + fal) * 100
}

// Self explanatory - don't stress me 😑
func timeElapsed(start, end time.Time) float64 {
    return end.Sub(start).Seconds()
}

// Refer to the last comment
func accuracy(correct, total int) int {
    return (correct / total) * 100
}

// 😕
func Speed(chars int, secs float64) float64 {
    return (float64(chars) / secs) * 12
}


We then go on to create a couple of function that will come in handy when we write our application logic.

func main() {
    fmt.Println("Welcome to Go-Speed")
    fmt.Println("-------------------")

    for {
        fmt.Printf("\nWould you like to continue? (y/N)\n\n")
        choice, err := Input(">> ")
        if err != nil {
            log.Fatalf("could not read value: %v", err)
        }

        if choice == "y" {
            fmt.Println("Starting Game...")
            timer := time.NewTimer(time.Second)
            fmt.Print("\nBEGIN TYPING NOW!!!\n\n")
            _ = <-timer.C

            sentence := Choice(sentences)
            fmt.Printf("%s\n", sentence)

            start := time.Now()
            response, err := Input(">> ")
            if err != nil {
                log.Fatalf("could not read value: %v", err)
            }

            elasped := timeElapsed(start, time.Now())
            valid, invalid := CompareChars(sentence, response)
            fmt.Print("\nResult!\n")
            fmt.Println("-------")
            fmt.Printf("Correct Characters: %d\nIncorrect Characters: %d\n", valid, invalid)
            fmt.Printf("Accuracy: %d%%\n", accuracy(valid, len(sentence)))
            fmt.Printf("Precision: %d%%\n", precision(valid, invalid))
            fmt.Printf("Speed: %.1fwpm\n", Speed(len(sentence), elasped))
            fmt.Printf("Time Elasped: %.2fsec\n", elasped)
        }

        if choice == "N" {
            fmt.Println("Quiting Game...")
            break
        }

        if choice != "N" && choice != "y" {
            fmt.Println("Invalid Option")
        }
    }
}

In our main function, we write a welcome message to the terminal and create an infinite loop to run our program. We then print a confirmation message to stdout - terminal - with an option to quit the program. If you choose to continue, a sentence is selected from the slice of sentences previously written and displayed in the terminal just after the start time is recorded. We collect the user input and calculate the time, speed, precision and accuracy then display the results back to the terminal. The infinite loop resets and the application runs again until you opt out of the program.

Voila!!! We just wrote our first program in golang.


This content originally appeared on DEV Community and was authored by IamKhan


Print Share Comment Cite Upload Translate Updates
APA

IamKhan | Sciencx (2024-10-18T01:09:27+00:00) Writing a Typing Speed Test CLI Application in Golang. Retrieved from https://www.scien.cx/2024/10/18/writing-a-typing-speed-test-cli-application-in-golang/

MLA
" » Writing a Typing Speed Test CLI Application in Golang." IamKhan | Sciencx - Friday October 18, 2024, https://www.scien.cx/2024/10/18/writing-a-typing-speed-test-cli-application-in-golang/
HARVARD
IamKhan | Sciencx Friday October 18, 2024 » Writing a Typing Speed Test CLI Application in Golang., viewed ,<https://www.scien.cx/2024/10/18/writing-a-typing-speed-test-cli-application-in-golang/>
VANCOUVER
IamKhan | Sciencx - » Writing a Typing Speed Test CLI Application in Golang. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/10/18/writing-a-typing-speed-test-cli-application-in-golang/
CHICAGO
" » Writing a Typing Speed Test CLI Application in Golang." IamKhan | Sciencx - Accessed . https://www.scien.cx/2024/10/18/writing-a-typing-speed-test-cli-application-in-golang/
IEEE
" » Writing a Typing Speed Test CLI Application in Golang." IamKhan | Sciencx [Online]. Available: https://www.scien.cx/2024/10/18/writing-a-typing-speed-test-cli-application-in-golang/. [Accessed: ]
rf:citation
» Writing a Typing Speed Test CLI Application in Golang | IamKhan | Sciencx | https://www.scien.cx/2024/10/18/writing-a-typing-speed-test-cli-application-in-golang/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.