Golang_tutorial_zero_to_hero

Loops

Now we move on to continue our discussion with control flow. Let’s start with a problem.

Problem You and your friends are getting together for a Harry Potter marathon, and you need to know how long it will take to finish them all. Using your Go skills, you already coompiled a list of all the movies. Now you can define a function to calculate the total run time.

package main

import "fmt"

var HarryPotter = []Movie{
	{
		Name:          "Harry Potter and the Sorcerer's Stone",
		Rating:        "PG",
		TimeInMinutes: 152,
	},
	{
		Name:          "Harry Potter and the Chamber of Secrets",
		Rating:        "PG",
		TimeInMinutes: 161,
	},
	{
		Name:          "Harry Potter and the Prisoner of Azkaban",
		Rating:        "PG",
		TimeInMinutes: 142,
	},
	{
		Name:          "Harry Potter and the Goblet of Fire",
		Rating:        "PG-13",
		TimeInMinutes: 157,
	},
	{
		Name:          "Harry Potter and the Order of the Phoenix",
		Rating:        "PG-13",
		TimeInMinutes: 129,
	},
	{
		Name:          "Harry Potter and the Half-Blood Prince",
		Rating:        "PG-13",
		TimeInMinutes: 153,
	},
	{
		Name:          "Harry Potter and the Deathly Hallows: Part 1",
		Rating:        "PG-13",
		TimeInMinutes: 146,
	},
	{
		Name:          "Harry Potter and the Deathly Hallows: Part 2",
		Rating:        "PG-13",
		TimeInMinutes: 130,
	},
}

func CalculateWatchTime(movies []Movie) int {
	// add you code here
}

func main (){
	time := CalculateWatchTime(HarryPotter)
	fmt.Println("The total run time is %d minutes")

A first-time approach might have a CalculateWatchTime() that looks like this.

func CaculateWatchTime(movies []Movie) int {
	movie1time := movies[0].TimeInMinutes
	movie2time := movies[1].TimeInMinutes
	movie3time := movies[2].TimeInMinutes
	movie4time := movies[3].TimeInMinutes
	movie5time := movies[4].TimeInMinutes
	movie6time := movies[5].TimeInMinutes
	movie7time := movies[6].TimeInMinutes
	movie8time := movies[7].TimeInMinutes
	totalTime := movie1Time + movie2Time + movie3Time + movie4Time + movie5Time + movie6Time + movie7Time + movie8Time
	return totalTime
}

It would almost be faster to do the math for this code by hand. The good news is we can make this a lot simpler.

For Loop

We can use the for loop function to simplifiy the above code. A for loop is defined as: control flow statement for specifying iteration, which allows code to be executed repeatedly.wiki In simple terms, we can loop a bit of code over and over again to save us from extra typing, excessive copying and pasting, and superfluous code. It also empowers you as a programmer to do complex algorithms with just a few lines of code.

C++ Style

Let’s take the above problem and implement the code with a traditional c++ style for loop. This style of for loop traditionally takes this form:

for i := 0; i < 10; i++ {}

This code starts by defining what we call an index, which is used to keep track of what iteration of the code we are on and how many have already been run. Our index is i and will start at 0. We see that this index is defined right after the for loop is declared by using the keyword for. The next part of the declaration contains the number of iterations that will take place. The line i < 10 is used to say we want this code to run 10 times. The last part defines how big our step size will be. Step size means at what interval you will count at (by 1, 2, 5, etc.). We want the code to step through every number, so our step size is 1.

Here are some code examples. For practice, try changing what the index starts, the number of iterations, and the step size.

package main

import "fmt"

func main(){
	// base example
	for i := 0; i < 10; i++ {
		fmt.Printf("My favorite number is: %d", i)
	}
	
	// starts at 1
	for i := i; i <= 10; i++ {
		fmt.Printf("My favorite number is: %d", i)
	}

	// change step size
	for i := 0; i < 10; i = i + 2 {
		fmt.Printf("My favorite number is: %d", i)
	}
	}

slices

Many programming languages have a code syntax that allows you to write a for loop that iterates over the values in a (slice)[part_1/1.3_types.md]. This is very helpful when you don’t necesarily know how long the slice is or you don’t how many iterations will need to take place.

Practice: Re-write the code from the practice example using one of the for loop styles.

Pro-Tip We can get a number value for the length of a slice by using the len() expression. So if we don’t know the length of a slice when you are ready to run the program, we can use the len() expression to handle this in the code. For example, the length of movies can be written as len(movies). For the Harry Potter example, the length should equal 8.

package main

import "fmt"

var HarryPotter = []Movie{
	{
		Name:          "Harry Potter and the Sorcerer's Stone",
		Rating:        "PG",
		TimeInMinutes: 152,
	},
	{
		Name:          "Harry Potter and the Chamber of Secrets",
		Rating:        "PG",
		TimeInMinutes: 161,
	},
	{
		Name:          "Harry Potter and the Prisoner of Azkaban",
		Rating:        "PG",
		TimeInMinutes: 142,
	},
	{
		Name:          "Harry Potter and the Goblet of Fire",
		Rating:        "PG-13",
		TimeInMinutes: 157,
	},
	{
		Name:          "Harry Potter and the Order of the Phoenix",
		Rating:        "PG-13",
		TimeInMinutes: 129,
	},
	{
		Name:          "Harry Potter and the Half-Blood Prince",
		Rating:        "PG-13",
		TimeInMinutes: 153,
	},
	{
		Name:          "Harry Potter and the Deathly Hallows: Part 1",
		Rating:        "PG-13",
		TimeInMinutes: 146,
	},
	{
		Name:          "Harry Potter and the Deathly Hallows: Part 2",
		Rating:        "PG-13",
		TimeInMinutes: 130,
	},
}

func CalculateWatchTime(movies []Movie) int {
	// add you code here
}

func main (){
	time := CalculateWatchTime(HarryPotter)
	fmt.Println("The total run time is %d minutes")

Using Condition (While Loop)

Sometimes we want a bit of code to run until a certain boolean condition is met. This specific construct is called a while loop. In Go, the while loop follows the for loop syntax. It is constructed by starting with the key word for followed by our condition, then a set of curly braces.

for _condition {
	// code here
}

Below is an example of a while loop that you can run.

Example We want to build an app that calculates the number of days left until school is out.

package main

import (
	"fmt"
	"time"
)

func GetDaysLeftOfSchool(startMonth, endMonth, endDay int, isFullYear bool) int {
	// the the current year
	year, month, _ := time.Now().UTC().Date()
	endYear := year

	// check if we need to add a year to the end day
	if isFullYear && startMonth >= 7 && month >= 7 {
		endYear++
		fmt.Println(endYear)
	}

	// start counter
	dateTracker := time.Now().UTC()
	var daysLeftOfSchool int

	// this continues to run until the endDay and the endMonth match the days we are adding .to
	for dateTracker.Day() != endDay || dateTracker.Month() != time.Month(endMonth) {

		// add one day to dateTracker
		dateTracker = dateTracker.AddDate(0, 0, 1)

		// add one daty to days left
		daysLeftOfSchool++
	}

	// return days left
	return daysLeftOfSchool
}

func main(){
	daysLeft := GetDaysLeftOfSchool(8, 5, 25, true)
	fmt.Printf("There are %d days left of school", daysLeft)
}


NOTE: Forever Loop

A forever loop is a loop in which the Boolean condition is not met. This can result in conditions when certain parts of your code do not run. I would recommend that you avoid this kind of loop until you have more experience writing code. Here is some more information Your Basic Golang: Loops.

Additional Practice

Tour Of Go

Continue