Manage Energy not Time

OK. So now you have time. But you are tired, exhausted, or even worse sick. What do you do? How do you feel?

You are running off our energy. Nothing matters anymore, IMO. In the worst case, when the energy is out, time is up.

I used to try to optimize time, manage time, find a way to have more time. None of them succeeded. I got frustrated when there were so many things but the clock says "Hey man, time’s up!". Sometimes, I was lucky to find some blocks of time. Unfortunately, I could not do any useful with them. I was exhausted. The body, the brain simply refused to work. Stress accumulated!

Recall the days when I felt good, waked up with full energy, I got so many things done and still felt good at the end of the day. Unfortunately, those days were just a few.

I managed the wrong factor! I should have focused on managing my energy not time.

Time is a lost battle

24 hours a day is what you get and so everybody. No exception. "Free time" does not exist. The mind is always searching for somethings to fill in the void. Some are good and some are bad.

Energy is in your hands

Not everyone is healthy or feeling good or was born with good health. Regardless of the current status, you can always do something to improve your health tomorrow, next week, next month or even next year. It is a factor that I can control.

Sound easy huh? Hmm, Hell No. It is easier said that done. But, very important, but I can make progress.

Here are some things that I can start building habit, integrate into my life schedule

  1. Exercise properly
  2. Eat less sugar
  3. Eat variety of fruits, vegetations
  4. Enough sleep
  5. Educate myself how to live healthier

Just name a few. I do not have to do them all at once. Just get started. I own my outcome, my life.

It is a mindset shift. It also helps me deal with outside factors. When a thing happens, I simply ask

  1. How does it impact my energy?
  2. Will it consume my energy too much?

If the answer is yes, then I better consider saying No. I have a list of important things in my life that needs lot of energy.

When writing this post, I feel very energized. I have enough energy to rock the day.

Have a good day = Have a full of energy day!

Learning How To Learn from Coursera

It was kind of funny that I took this course—Learn How To Learn. Graduated from the university, being a professional programmer for 15 years, and what? I have to learn How To Learn? I am glad I took the course.

I knew about the course why listening to Time Ferris Show podcast in a morning run session, by the way it is a wonderful thing. The guess mentioned the course. That he was taking the course at night. It is free. Cool! why not me? So I did.

Below are notes, key takeaways from the course.

Focused and Diffuse Modes

When come to learning, solving problems, the brain has 2 modes: Focused and Diffuse.

Focused mode helps us solves known problems. There are patterns. We kind of know how to approach the problem.

Diffuse mode is where all the creativity comes from. There are problems that we have no idea. Problems that require complete new ways of thinking. In my words, it means that I should not focus on the problem. Instead, input the problem and let my brain figuring it out without my awareness. Banging my head into the wall will not create anything except a broken, bleeding head.

The key point is that I have to trust these 2 modes and decide when to use what mode. However, do not mistake that it will work. The diffuse mode only works if the brain has a variety of input, sources, data, knowledge of different fields. If you do not study anything, nothing will work. Cross learning is powerful. Knowledge in one area will help solving problems in others, by the diffuse mode.

Chunks/Chunking

Chunks are group of knowledge, collected and stayed in your brain. I remember that I read materials and then thought I understood it. They’ve all gone away after a day or more. Now, I know that I have not created chunks. There are many practices, steps to form chunks. Understanding is not enough. There are understanding, practicing, and context.

I have to do my homework. I have to stay around with the concepts. I have to get myself familiar with the subjects. Chunks are fundamentals. I skipped it a lot.

Recall NOT Reread

This is the mistake I made a lot. When learning materials, I re-read them. Reread is a passive action. It does not invoke any brain activity. When I re-read, the brain will simply override the existing data or store the duplicated data somewhere.

However, recall is an active action. It triggers the process of retrieving information, trying to reasoning that they are, how they are connected to each other or existing data.

There is a 30 seconds rule: After a meeting, conversation, … spend 30 seconds to jot down things that matter most to you.

Spaced Repetition

Another mistake I made. Speaking of recall, I was recalling continuously through the day. Actually, I was afraid that I would forget them. Spaced repetition is that you recall them by days. For example, I learn something on Monday. I should recall them on Tuesday or Wednesday, and later another time on Friday.

Recently, I recall (spaced repetition) while I run in the morning. It is the perfect time.

Metaphor and Visualization

This is about the learning technique. We should create metaphors, visual analogies, connections when learning new concepts. The more you do the better you will remember them.

Take the Hard Stuff

I used to learn the easiest stuff first. This advice changes my approach. Learn from the easy parts but also challenge the hard stuff. This gives my diffuse brain chances to figure things out.

Sleep and Schedule Before Sleep

I recently learnt how crucial the sleep is. Staying up late and waking up early to learn is a big mistake. If you want to do something tomorrow, plan it before going to bed, the brain (the diffuse mode, remember) will help you figure out.

If you want to know more, visit this link Learning how to learn, Coursera. I am sure you will not regret.

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.

Gowhere – array, hash table, regular expression, and foreach loop

Gowhere? Some steps further—append arrays, hash table, regular expression, and for each loop.

After playing around with HTTP, I got the JSON data from the API. I wanted to analyze the data—to display the total hours spent on each work item.

A typical record has this structure

type WorkItem struct {
    FromDateTime time.Time
    ToDateTime   time.Time
    Detail       string
}

And an actual work item looks like

{
    "FromDateTime" : "2019-11-29 02:05:00 +0000 UTC",
    "ToDateTime": "2019-11-29 03:19:00 +0000 UTC",
    "Detail" : "Work Item 12345: Implement a cool feature"
}

The "Work Item 12345" has many records. The detail field are not the same except they contain the number 12345 as the work item ID. I want to display the sum of time spent for Work Item 12345. So the algorithm is pretty simple

  1. For each record, extract the work item id from the detail field
  2. Calculate the difference in hours between FromDateTime and ToDateTime
  3. Sum the difference with the existing value—if not exist, create a new one with the time spent zero

Note: If I am writing in C#, I can finish the implementation quickly with Linq support.

The expected result of a work item is below

{
    "WorkItemId" : "12345",
    "WorkItemName" : "Work Item 12345: Implement a cool feature",
    "TimeSpent" : time_spent_in_hours
}

Stats structure to hold the analysis result of a work item

// Stats ...
type Stats struct {
    WorkItemId    string
    WorkItemName  string
    TimeSpent float64
}

Let’s write some code and explore

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "regexp"
    "time"
)

func main() {
    // Assuming that I have a list of IDs for a team.
    // The getWorkItemRecords will an array of WorkItem of a member.
    var records = make([]WorkItem, 0)
    for _, id := range team {
        r := getWorkItemRecords(id)
        // Discussion about appending 2 slices: https://stackoverflow.com/questions/16248241/concatenate-two-slices-in-go

        // This is how to append 2 arrays
        records = append(records, r...)
    }

    // A dictionary (hash table) with
    // key: WorkItemID (or name if cannot find the ID) - simply a string
    // value: total time spent
    // More detail about map here: https://blog.golang.org/go-maps-in-action
    statsMap := make(map[string]Stats)

    // Regular expression to extract ID (all numeric characters)
    workItemIdExp := regexp.MustCompile("[\\d]+")

    var id string

    for _, r := range records {
        timeSpent := r.ToDateTime.Sub(r.FromDateTime).Hours()
        if timeSpent < 0 {
            // The record does not have an end time
            continue
        }

        id = workItemIdExp.FindString(r.Detail)

        if id == "" {
            id = r.Detail
        }

        ts, exist := statsMap[id]

        if !exist {
            ts = Stats{id, r.Detail, 0}
        }
        ts.TimeSpent += timeSpent
        statsMap[id] = ts
    }

    var workingHours float64 = 0
    for key, value := range statsMap {
        workingHours += value.TimeSpent
        fmt.Printf("%s (%s) %f\n", key, value.WorkItemName, value.TimeSpent)
    }

    fmt.Printf("Working hours: %f\n", workingHours)
}

What are my further steps from this exercise?

  1. Append 2 arrays (slices) with "…" syntax—append(records, r...)
  2. Hash table (dictionary like) with mapmap[string]int means a dictionary with key is a string and value is an integer
  3. Regular expression with regexp package—regexp.MustCompile("[\\d]+")
  4. For each loop with the rangefor _, r := range records

A happy weekend!