-
-
Notifications
You must be signed in to change notification settings - Fork 657
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #2184 New concept stringers New concept exercise Meteorology
- Loading branch information
Showing
14 changed files
with
599 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"blurb": "Stringer is an interface for defining the string format of values.", | ||
"authors": [ | ||
"norbs57" | ||
], | ||
"contributors": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# About | ||
|
||
[Stringer][stringer-interface] is an interface for defining the string format of values. | ||
|
||
The interface consists of a single `String` method: | ||
|
||
```go | ||
type Stringer interface { | ||
String() string | ||
} | ||
``` | ||
|
||
The [fmt][fmt-package] package (and many others) will look for this interface to print values. | ||
|
||
## Example: Distances | ||
|
||
Assume we are working on an application that deals with geographical distances measured in different units. | ||
We have defined types `DistanceUnit` and `Distance` as follows: | ||
|
||
```go | ||
type DistanceUnit string | ||
|
||
const ( | ||
Kilometer DistanceUnit = 0 | ||
Mile DistanceUnit = 1 | ||
NauticalMile DistanceUnit = 2 | ||
) | ||
|
||
type Distance struct { | ||
number float64 | ||
unit DistanceUnit | ||
} | ||
``` | ||
|
||
These types do not implement interface `Stringer` as they lack the `String` method. | ||
Hence `fmt` functions will print `Distance` values using Go's "default format": | ||
|
||
```go | ||
var distances = []Distance{ | ||
{790.7, Kilometer}, | ||
{415.2, Mile}, | ||
{10_500, NauticalMile}, | ||
} | ||
fmt.Println(distances) | ||
\\ => [{790.7 0} {415.2 1} {10500 2}] | ||
``` | ||
|
||
In order to make the output more informative, we implement interface `Stringer` by adding a `String` method to each type: | ||
|
||
```go | ||
func (sc DistanceUnit) String() string { | ||
return [...]string{"km", "mi", "nmi"}[sc] | ||
} | ||
|
||
func (d Distance) String() string { | ||
return fmt.Sprintf("%v %v", d.number, d.unit) | ||
} | ||
``` | ||
|
||
`fmt` package functions will call these methods when formatting `Distance` values: | ||
|
||
```go | ||
fmt.Println(distances) | ||
\\ => [790.7 km 415.2 mi 10500 nmi] | ||
``` | ||
|
||
[stringer-interface]: https://pkg.go.dev/fmt#Stringer | ||
[fmt-package]: https://pkg.go.dev/fmt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# Introduction | ||
|
||
[Stringer][stringer-interface] is an interface for defining the string format of values. | ||
|
||
The interface consists of a single `String` method: | ||
|
||
```go | ||
type Stringer interface { | ||
String() string | ||
} | ||
``` | ||
|
||
The [fmt][fmt-package] package (and many others) will look for this interface to print values. | ||
|
||
## Example: Distances | ||
|
||
Assume we are working on an application that deals with geographical distances measured in different units. | ||
We have defined types `DistanceUnit` and `Distance` as follows: | ||
|
||
```go | ||
type DistanceUnit string | ||
|
||
const ( | ||
Kilometer DistanceUnit = 0 | ||
Mile DistanceUnit = 1 | ||
NauticalMile DistanceUnit = 2 | ||
) | ||
|
||
type Distance struct { | ||
number float64 | ||
unit DistanceUnit | ||
} | ||
``` | ||
|
||
These types do not implement interface `Stringer` as they lack the `String` method. | ||
Hence `fmt` functions will print `Distance` values using Go's "default format": | ||
|
||
```go | ||
var distances = []Distance{ | ||
{790.7, Kilometer}, | ||
{415.2, Mile}, | ||
{10_500, NauticalMile}, | ||
} | ||
fmt.Println(distances) | ||
\\ => [{790.7 0} {415.2 1} {10500 2}] | ||
``` | ||
|
||
In order to make the output more informative, we implement interface `Stringer` by adding a `String` method to each type: | ||
|
||
```go | ||
func (sc DistanceUnit) String() string { | ||
return [...]string{"km", "mi", "nmi"}[sc] | ||
} | ||
|
||
func (d Distance) String() string { | ||
return fmt.Sprintf("%v %v", d.number, d.unit) | ||
} | ||
``` | ||
|
||
`fmt` package functions will call these methods when formatting `Distance` values: | ||
|
||
```go | ||
fmt.Println(distances) | ||
\\ => [790.7 km 415.2 mi 10500 nmi] | ||
``` | ||
|
||
[stringer-interface]: https://pkg.go.dev/fmt#Stringer | ||
[fmt-package]: https://pkg.go.dev/fmt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[ | ||
{ | ||
"url": "https://pkg.go.dev/fmt", | ||
"description": "Go standard library: package fmt" | ||
}, | ||
{ | ||
"url": "https://pkg.go.dev/fmt#Stringer", | ||
"description": "Go standard library: interface Stringer" | ||
}, | ||
{ | ||
"url": "https://go.dev/tour/methods/17", | ||
"description": "A Tour of Go: Stringers" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Hints | ||
|
||
## General | ||
|
||
See [yourbasic.org][yourbasic-enum] for an example how to define a "enum" type with a `String` method. | ||
|
||
[yourbasic-enum]: https://yourbasic.org/golang/iota/#complete-enum-type-with-strings-best-practice | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Instructions | ||
|
||
Your team is working on a meteorology application. | ||
They have defined an API with various types and constants representing meteorological data, see file `meteorology.go`. | ||
|
||
Your task is to add suitable `String` methods all types so that they implement interface `Stringer`. | ||
|
||
Values should be formatted as in the examples below: | ||
|
||
```go | ||
temperatureUnit := Celsius | ||
fmt.Println(temperatureUnit) | ||
// => C | ||
|
||
temperature := Temperature{21, Celsius} | ||
fmt.Println(temperature) | ||
// => 21 °C | ||
|
||
speedUnit := MilesPerHour | ||
fmt.Println(speedUnit) | ||
// => mph | ||
|
||
windSpeed := Speed{18, KmPerHour} | ||
fmt.Println(windSpeed) | ||
// => 18 km/h | ||
|
||
metData := MetData{"San Francisco", Temperature{57, Fahrenheit}, "NW", Speed{19, MilesPerHour}, 60}, | ||
fmt.Println(metData) | ||
// => San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity | ||
``` | ||
|
||
In the test data, you can assume that | ||
|
||
- the unit of temperature be either `Celsius` or `Fahrenheit` | ||
- the unit of wind speed will be either `KmPerHour` or `MilesPerHour` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# Introduction | ||
|
||
[Stringer][stringer-interface] is an interface for defining the string format of values. | ||
|
||
The interface consists of a single `String` method: | ||
|
||
```go | ||
type Stringer interface { | ||
String() string | ||
} | ||
``` | ||
|
||
The [fmt][fmt-package] package (and many others) will look for this interface to print values. | ||
|
||
## Example: Distances | ||
|
||
Assume we are working on an application that deals with geographical distances measured in different units. | ||
We have defined types `DistanceUnit` and `Distance` as follows: | ||
|
||
```go | ||
type DistanceUnit string | ||
|
||
const ( | ||
Kilometer DistanceUnit = 0 | ||
Mile DistanceUnit = 1 | ||
NauticalMile DistanceUnit = 2 | ||
) | ||
|
||
type Distance struct { | ||
number float64 | ||
unit DistanceUnit | ||
} | ||
``` | ||
|
||
These types do not implement interface `Stringer` as they lack the `String` method. | ||
Hence `fmt` functions will print `Distance` values using Go's "default format": | ||
|
||
```go | ||
var distances = []Distance{ | ||
{790.7, Kilometer}, | ||
{415.2, Mile}, | ||
{10_500, NauticalMile}, | ||
} | ||
fmt.Println(distances) | ||
\\ => [{790.7 0} {415.2 1} {10500 2}] | ||
``` | ||
|
||
In order to make the output more informative, we implement interface `Stringer` by adding a `String` method to each type: | ||
|
||
```go | ||
func (sc DistanceUnit) String() string { | ||
return [...]string{"km", "mi", "nmi"}[sc] | ||
} | ||
|
||
func (d Distance) String() string { | ||
return fmt.Sprintf("%v %v", d.number, d.unit) | ||
} | ||
``` | ||
|
||
`fmt` package functions will call these methods when formatting `Distance` values: | ||
|
||
```go | ||
fmt.Println(distances) | ||
\\ => [790.7 km 415.2 mi 10500 nmi] | ||
``` | ||
|
||
[stringer-interface]: https://pkg.go.dev/fmt#Stringer | ||
[fmt-package]: https://pkg.go.dev/fmt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"blurb": "Learn how to work with interface Stringer", | ||
"authors": [ | ||
"norbs57" | ||
], | ||
"contributors": [], | ||
"files": { | ||
"solution": [ | ||
"meteorology.go" | ||
], | ||
"test": [ | ||
"meteorology_test.go" | ||
], | ||
"exemplar": [ | ||
".meta/exemplar.go" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Design | ||
|
||
## Goal | ||
|
||
The goal here is to create a new concept exercise that teaches about structs that implement the `fmt.Stringer` interface. | ||
That includes writing a concept and creating a new exercise. | ||
|
||
## Learning objectives | ||
|
||
The student should learn about the following topics and then practice them in the concept exercise: | ||
|
||
- present the `fmt.Stringer` interface | ||
- implement a struct that satisfies the `fmt.Stringer` | ||
- the use of a type that satisfies `fmt.Stringer` with `fmt.Sprintf` and other methods of `fmt` | ||
|
||
## Concepts | ||
|
||
- `stringers` | ||
|
||
## Prerequisites | ||
|
||
- `strings` | ||
- `string-formatting` | ||
- `interfaces` | ||
- `methods` | ||
- `structs` | ||
|
||
These prerequisites should be listed in the `config.json` entry for the exercise. | ||
The prerequisites above are a baseline of the prerequisites that might be needed for the exercise. | ||
When implementing the exercise, feel free to add more prerequisites if the exercise needs them. | ||
|
||
## Story | ||
|
||
Try to think of a story for the exercise that ties all the tasks together. | ||
The story doesn't need to be highly complex. | ||
Even a small story goes a long way to improve the enjoyment of the exercise. | ||
|
||
## Resources | ||
|
||
Some links that might be helpful as a starting point and/or for the links section of the concept: | ||
|
||
- Tour of Go: [Stringers][tour-of-go-stringers] | ||
|
||
|
||
[tour-of-go-stringers]: https://go.dev/tour/methods/17 |
Oops, something went wrong.