After reading lesson 2, you’ll be able to
Computer programs are capable of a great many things. In this lesson you’ll write programs to solve mathematical problems.
Why write a program when you could just use a calculator?
Well, have you memorized the speed of light or how long it takes Mars to orbit the sun? Code can be saved and read later, serving as both a calculator and a reference. A program is an executable document that can be shared and modified.
There are days when we think it would be nice to be younger and weigh a little less. In this regard, Mars has a lot to offer. Mars takes 687 Earth days to travel around the sun, and its weaker gravitational force means everything weighs approximately 38% of what it does on Earth.
To calculate how young and light Nathan would be on Mars, we wrote a small program, shown in listing 2.1. Go provides the same arithmetic operators as other programming languages: +, -, *, /, and % for addition, subtraction, multiplication, division, and modulus respectively.
The modulus operator (%) obtains the remainder of dividing two whole numbers (for example, 42 % 10 is 2).
// My weight loss program. 1 package main import "fmt" // main is the function where it all begins. 1 func main() { fmt.Print("My weight on the surface of Mars is ") fmt.Print(149.0 * 0.3783) 2 fmt.Print(" lbs, and I would be ") fmt.Print(41 * 365 / 687) 3 fmt.Print(" years old.") }
Though listing 2.1 displays weight in pounds, the chosen unit of measurement doesn’t impact the weight calculation. Whichever unit you choose, the weight on Mars is 37.83% of the weight on Earth.
The code in the preceding listing begins with a comment. When Go sees a double slash //, it ignores everything until the end of the line. Computer programming is all about communication. Code communicates your instructions to a computer, and when written well, it communicates your intentions to other people. Comments are just for us. They don’t affect how a program runs.
The preceding listing calls the Print function several times to display a sentence on a single line. Alternatively, you can pass a list of arguments separated by commas. An argument to Println can be text, a number, or a mathematical expression:
fmt.Println("My weight on the surface of Mars is", 149.0*0.3783, "lbs, and I would be", 41*365.2425/687, "years old.") 1
Type and run listing 2.1 in the Go Playground at play.golang.org. How much would you weigh on Mars? How old would you be? Replace Nathan’s age (41) and weight (149.0) with your own.
After modifying your code, click the Format button in the Go Playground. It will automatically reformat the indentation and spacing of your code without changing what it does.
The Print and Println functions have a sibling that gives more control over output. By using Printf, shown in the following listing, you can insert values anywhere in the text.
fmt.Printf("My weight on the surface of Mars is %v lbs,", 149.0*0.3783) 1 fmt.Printf(" and I would be %v years old. ", 41*365/687) 2
Unlike Print and Println, the first argument to Printf is always text. The text contains the format verb %v, which is substituted for the value of the expression provided by the second argument.
We’ll introduce more format verbs (other than %v) as needed in upcoming lessons. For a complete reference, see the online documentation at golang.org/pkg/fmt/.
The Println function automatically moves to the next line, but Printf and Print don’t. Whenever you want to move to a new line, place in the text.
If multiple format verbs are specified, the Printf function will substitute multiple values in order:
fmt.Printf("My weight on the surface of %v is %v lbs. ", "Earth", 149.0) 1
In addition to substituting values anywhere in a sentence, Printf can help you align text. Specify a width as part of the format verb, such as %4v to pad a value to a width of 4 characters. A positive number pads with spaces to the left, and a negative number pads with spaces to the right:
fmt.Printf("%-15v $%4v ", "SpaceX", 94) fmt.Printf("%-15v $%4v ", "Virgin Galactic", 100)
The preceding code displays the following output:
SpaceX $ 94 Virgin Galactic $ 100
How do you print a new line?
What does Printf do when it encounters the %v format verb?
Use anywhere in the text you’re printing to insert a new line or use fmt.Println().
The %v is substituted for a value from the following arguments.
The calculations in listing 2.1 are performed on literal numbers. It isn’t clear what the numbers mean, particularly values like 0.3783. Programmers sometimes refer to unclear literal numbers as magic numbers. Constants and variables can help by providing descriptive names.
After seeing the benefits of living on Mars, our next question is how long the trip will take. Traveling at the speed of light would be ideal. Light travels at a constant speed in the vacuum of space, which makes the math easy. On the other hand, the distance between Earth and Mars varies significantly, depending on where the planets are in their orbits around the Sun.
The following listing introduces two new keywords, const and var, for declaring constants and variables respectively.
// How long does it take to get to Mars? package main import "fmt" func main() { const lightSpeed = 299792 // km/s var distance = 56000000 // km fmt.Println(distance/lightSpeed, "seconds") 1 distance = 401000000 fmt.Println(distance/lightSpeed, "seconds") 2 }
Type listing 2.3 into the Go Playground and click Run. Light speed is pretty convenient; you probably wouldn’t hear anyone asking, “Are we there yet?”
The first calculation is based on Mars and Earth being nearby, with distance declared and assigned an initial value of 56,000,000 km. Then the distance variable is assigned a new value of 401,000,000 km, with the planets on opposite sides of the Sun, though plotting a course directly through the Sun could be problematic.
The lightSpeed constant can’t be changed. If you try to assign it a new value, the Go compiler will report the error “cannot assign to lightSpeed.”
Variables must be declared before you can use them. Go will report an error if you assign a value to a variable that hasn’t been declared with var—for example, speed = 16. This restriction can help catch mistakes, such as accidentally assigning a value to distence when you intended to type distance.
The SpaceX Interplanetary Transport System lacks a warp drive, but it will coast to Mars at a respectable 100,800 km/h. An ambitious launch date of January 2025 would place Mars and Earth 96,300,000 km apart. How many days would it take to reach Mars? Modify listing 2.3 to find out.
There are 24 hours in one Earth day. To give 24 a descriptive name in your program, which keyword would you use?
Spaceships don’t travel in a straight line, but as an approximation, the trip would take 39 days.
const hoursPerDay = 24 var speed = 100800 // km/h var distance = 96300000 // km fmt.Println(distance/speed/hoursPerDay, "days")
The const keyword because the value doesn’t change while the program is running.
There may not be any shortcuts to visit Mars, but Go provides a few keystroke-saving shortcuts.
When you declare variables or constants, you can declare each one on its own line like this:
var distance = 56000000 var speed = 100800
Or you can declare them as a group:
var ( distance = 56000000 speed = 100800 )
Yet another option is to declare multiple variables on a single line:
var distance, speed = 56000000, 100800
Before you declare multiple variables as a group or on a single line, consider whether or not the variables are related. Always keep in mind the readability of your code.
What single line of code would declare both the number of hours in a day and the minutes per hour?
There are a few shortcuts to perform assignment with other operations. The last two lines of the following listing are equivalent.
var weight = 149.0 weight = weight * 0.3783 weight *= 0.3783
Incrementing by one has an additional shortcut, as shown in the following listing.
var age = 41 age = age + 1 1 age += 1 age++
You can decrement with count-- or shorten other operations like price /= 2 in the same way.
In case you’re wondering, Go does not support the prefix increment ++count like C and Java.
Write the shortest line of code to subtract two pounds from a variable named weight.
Think of a number between 1 and 10.
Got it? Okay.
Now have your computer “think” of a number between 1 and 10. Your computer can generate pseudorandom numbers using the rand package. They’re called pseudorandom because they’re more or less random, but not truly random.
The code in listing 2.6 will display two numbers between 1–10. Passing 10 to Intn returns a number from 0–9, to which you add 1 and assign the result to num. The num variable can’t be a Go constant because it’s the result of a function call.
If you forget to add 1, you’ll get a number between 0–9. Because we want a number between 1–10, that’s an example of an off-by-one error, a classic programming mistake.
package main import ( "fmt" "math/rand" ) func main() { var num = rand.Intn(10) + 1 fmt.Println(num) num = rand.Intn(10) + 1 fmt.Println(num) }
The import path for the rand package is math/rand. The Intn function is prefixed with the package name rand, but the import path is longer.
To use a new package, it must be listed as an import. The Go Playground can add import paths for you. First ensure the Imports checkbox is checked and then click the Format button. The Go Playground will determine which packages are being used and update your import paths.
Every time you run listing 2.6, the same two pseudorandom numbers are displayed. It’s rigged! In the Go Playground, time stands still and results are cached, but these numbers are good enough for our purposes.
The distance between Earth and Mars varies from nearby to opposite sides of the sun. Write a program that generates a random distance from 56,000,000 to 401,000,000 km.
// a random distance to Mars (km) var distance = rand.Intn(345000001) + 56000000 fmt.Println(distance)
Let’s see if you got this...
Malacandra is much nearer than that: we shall make it in about twenty-eight days.
C.S. Lewis, Out of the Silent Planet
Malacandra is another name for Mars in The Space Trilogy by C. S. Lewis. Write a program to determine how fast a ship would need to travel (in km/h) in order to reach Malacandra in 28 days. Assume a distance of 56,000,000 km.
Compare your solution to the code listing in the appendix.