CS 245 - Programming Languages
Lab 5
Go packages
This lab is mostly a review of stuff you have already seen, but not used much in Go. In particular, several packages
containing useful stuff that is not a part of the language.
Command Line Args
Recall that to get the command line args in Go, you look at the Args variable in the os package, as is illustrated
in the following very short program.
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Args)
}
String conversion
strconv.Atoi() converts a string containing a number to an int. It returns two values, the number itself, and an
error value in case there it was unable to convert the string into an int. The error value returned is nil
if successful. The program below tests to see if err is nil before printing the value of the integer command line
argument. For instance:
package main
import ( "fmt"
"strconv"
)
func main() {
v1,err1 := strconv.Atoi("3")
if err1==nil {
fmt.Printf("%d\n", v1)
}
v2,e2 := strconv.Atoi("this fails")
if e2==nil {
fmt.Printf("%d\n", v2)
} else {
fmt.Printf("ERR: %v\n", e2)
}
}
Random Numbers
A random number generator can be perceived of as consisting of two parts: a very long array of random numbers and a
pointer to the current location in the array. (It does not work this way, but it is a useful metaphor.) When you get
a random number, the function returns the value at the current
position in the very long array and increments the position.
So, when you want a random number, you first have to create the array and set where in the array you want to read.
In Go, this requires two commands as shown in the following little example. Once those two commands have been
executed, you use the thing returned to actually get random numbers. Note that if you do the exact same thing to
create the array and choose a location in that array, then you will get the exact same sequence of random numbers.
For this reason, it is common why you want reasonably random numbers to create the array and set the position using
the current system clock time (as shown below).
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
fmt.Printf("%d\n", r1.Intn(100))
}
Exercise
Collecting Cards in Candy
A candy company wishes to run a promotion in the next quarter. Every candy wrapper will contain a picture of a
player from the Women's National Soccer Team. There are 28 players on the roster, plus 7 coaches, making a total of
35 pictures. Pictures will be randomly inserted in each candy wrapper. The company hopes that kids buying their
candy will engage in collecting all 35 pictures and placing them in a picture album (sold separately by the
company). Each picture will carry a unique number (from 0..34).
Before running with the idea the company wants to examine how this promotion might improve sales of its candy.
Write a program in Go that performs a simulation to determine the number of candies a kid would have to purchase in
order to collect all 35 cards. Your program should input the number of pictures (i.e., 35) on the command line. Further, your program should assume that an equal of number of cards are printed and that a sufficient number are printed so that getting one instance of a card has no effect on the probability of getting another instance that same card.
$ go run collector.go 35
The program will print out the expected number of candies (XXX) that kids will purchase to collect all 35 cards.
Here is a possible design:
- Write a function collect(c) that will perform a simulation of collecting c cards. It will return the total
number of candies bought in order to collect all 35 cards.
- Once written, you can use collect(c) to perform several trials (for instance one million, and keep track of the number of candies bought
n = Number of cards to collect
trials = 1000000
sum = 0
do trials times:
sum = sum + collect(n)
output sum/trials
as the average number of candies to buy in order to collect n cards. As the number of trials
increases, the data will start to converge on a good estimate of the expected number of candies a kid would
have to buy. Suggestion: write your program in a way such that it runs correctly but possibly rather slowly (ie do not worry about efficiency.) Once your program is running correctly think about efficiency; one million trials of a slow program could take quite a long time. (In particular, the biggest gain in efficiency of the program will be to to require O(1) time to calculate the number of distinct cards seen rather than O(m) where m is the number of distinct cards.)
- Run the program with 1,000,000 trials to compute the number of candies required to be bought in order to
collect 35, 100 pictures, and 500 pictures.
What to hand in
You candy card program. As far as you get in 80 minutes. Do not spend more than 80 minutes on this program. If you
have estimates, send those as well.
Send your program to gtowell@brynmawr.edu