Gowhere – Read CSV file

Continue my Gowhere journey. I need to read data from a CSV file—a common task in programming, dealing with file.

A sample content with 3 columns ID, Effort, and Title.

ID,Effort,Title
"94503","4","Bug: The line was not aligned correctly"
"97018","12","Implement a cool feature"
"97595","1","Document an incident"

The file size is small so I do not have to worry too much about the performance at this point. Let’s see what requires to perform the task in Go.

In general, here are steps to read and parse a CSV file

  1. Open the file
  2. Read everything or line by line
  3. Parse the text into desired outcome format
  4. Close the file. When to close depends on how you read the file

Open a file

Go supplies a built-in package "os" to work with the file system. Opening a file will return a pointer to the file—if no error, otherwise an error, a normal pattern in Go.

There are 3 required steps

  1. Open the file by os.Open(file)
  2. Check for error before usage
  3. Close the file by using a defer function. This is important otherwise the file is locked
    // Need the os package to read open a file
    // f is a pointer to File object (*File)
    f, err := os.Open(file)
    // Check for error before usage
    if err != nil {
        writeLog(err)
        return nil
    }
    // Close file by a defer function
    defer func() {
        er := f.Close()
        if er != nil {
            writeLog(er)
        }
    }()

Read file

Depending on the file size and the type of applications, developers can choose either read all contents at once or line by line. I always prefer line by line.

    // This is a cool concept. Given that we have a pointer to the file opened by the os.
    // A scanner is created and scan line by line
    b := bufio.NewScanner(f)

    stats := make(map[string]int64)
    for b.Scan() {
        line := b.Text()
        parts := strings.Split(line, ",")
        effortText := strings.Trim(parts[1], "\"")
        if effortText == "" {
            continue
        }

        effort, err := strconv.ParseInt(effortText, 0, 0)
        if err != nil {
            writeLog(err)
            continue
        }
        id := strings.Trim(parts[0], "\"")
        stats[id] = effort
        fmt.Printf("%s - %d\n", id, effort)
    }

Go supplies bufio package to help manipulating IO (file). The first time I heard about the Scanner concept. It hits my mind immediately, kind of "wow that makes sense and cool".

After holding a point to a Scanner:

  1. Call Scan() to loop throw the buffer data
  2. Call Text() to access the current line. If the file is opened in binary mode, use a different method
  3. Parse the line to meet your logic

Proceed data

For common operations on a string, strings package is there. For conversion from a string to various data types—int, float, …—strconv package is there. They are all built-in packages.

Close the file

Handle by the defer function, which is called when the caller function exists.

    // Close file by a defer function
    defer func() {
        er := f.Close()
        if er != nil {
            writeLog(er)
        }
    }()

Routine not Goal

Having goals is good. Many advice that people should have clear goals. I do have some at the beginning of each year. Things like "I wish, I will, …". I promised to myself to do this, do that. But soon enough, I forgot most of them. Time goes by very fast. At the end of the year, I realized that nothing had changed. Another cycle starts with the next year.

Of course, I accomplished some. And I still set goals for every year. It is a good practice. However, I realized some problems with setting goals—the emotion. I felt excited, determined at that moment. That excitement faded quickly—end of January at max. And the mind started to do his best job—finds good excuses for not doing anything related to your goal, it keeps you where you are. Sometimes regrets came at the end of the year.

It is an endless loop—promise – regret – promise. I realized there is another way—routine, habit. Developing good routines/habits is the key.

What I want does not matter much. What I’ve done matters most. I had goals, but I still kept the same routines—did the same thing everyday. How could I expect different outcome? Maybe that is the definition of stupid.

People are afraid of changing. They just do not realize that.

This year, 2020, I decided to build new routines/habits. They must be

  1. Small and easy
  2. The good ones that support my bigger goals
  3. Supporting me to become a better of me

I’ve started some since October 2019. Here is my list

Instead of wishing healthier

I commit to do 100 push-ups everyday. Some day I missed, but that was ok. I do not have to do it at once. I do 50 after I get up in the morning. The rest is in the afternoon.

I commit to do 50 sit-ups every morning—after 50 push-ups. While resting between 2 exercises, I prepare my coffee.

Push-up, sit-up, and making coffee cost me just 15 minutes. A very good use of my time!

I commit to run on treadmill for 1 hour, 3 times a week. It was hard at first. But after a month, I felt comfortable, sometimes not, with the time on the treadmill—It was hard to discipline in a boring treadmill for 1 hour. Some weeks I missed 1 or 2 sessions. That was ok. I did not consider a failure or breaking the rule. As far as I do not quit, it is going to be fine.

Instead of wishing well-organized

I commit to plan my day early in the morning—after the exercises. I simply write down what I want to do in that day—use Microsoft To-Do app. I like the My Day feature—allows me to jot down what I want to do without thinking too much about categorization, prioritization. After 2 months of practice, I started to feel it as part of my daily routine. It is a small routine, cost me 5 minutes.

Instead of saying I will focus

I apply the Pomodoro technique—working in a block of 25 minutes uninterrupted. I did not believe at first when I knew it 5 years ago. However, I decided to commit to it since last month. I am glad I did try it. Over the time, It gives me the confident that I can deliver something if I focus on it for 25 minutes. After that period I can stretch my body, take a breathe and then start another 25 minutes. If you want to make a change, try it. Do not question whether it works or not. Just do it.

 

Those are just a few that I have started. After 2 months, I can sense changes—in a good way.