Skip to content

Commit 5c75d90

Browse files
Finishing up the exercise
1 parent c678303 commit 5c75d90

File tree

12 files changed

+263
-126
lines changed

12 files changed

+263
-126
lines changed

concepts/stringers/.meta/config.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
"authors": [
44
"norbs57"
55
],
6-
"contributors": []
6+
"contributors": [
7+
"andrerfcsantos"
8+
]
79
}

concepts/stringers/about.md

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ type Stringer interface {
1010
}
1111
```
1212

13-
Types that want to implement this interface must have a `String()` method that returns a human-friendly string representation of the type. The [fmt][fmt-package] package (and many others) will look for this method to print values.
13+
Types that want to implement this interface must have a `String()` method that returns a human-friendly string representation of the type. The [fmt][fmt-package] package (and many others) will look for this method to format and print values.
1414

1515
## Example: Distances
1616

@@ -23,7 +23,6 @@ type DistanceUnit int
2323
const (
2424
Kilometer DistanceUnit = 0
2525
Mile DistanceUnit = 1
26-
NauticalMile DistanceUnit = 2
2726
)
2827

2928
type Distance struct {
@@ -32,38 +31,54 @@ type Distance struct {
3231
}
3332
```
3433

34+
In the example above, `Kilometer` and `Mile` ane constants of type `DistanceUnit`.
35+
3536
These types do not implement interface `Stringer` as they lack the `String` method.
3637
Hence `fmt` functions will print `Distance` values using Go's "default format":
3738

38-
```go
39-
var distances = []Distance{
40-
{number: 790.7, unit: Kilometer},
41-
{number: 415.2, unit: Mile},
42-
{number: 10_500, unit: NauticalMile},
43-
}
44-
fmt.Println(distances)
45-
// Output: [{790.7 0} {415.2 1} {10500 2}]
39+
```go
40+
mileUnit := Mile
41+
fmt.Sprint(mileUnit)
42+
// => 1
43+
// The result is '1' because that is the underlying value of the 'Mile' contant (see contant declarations above)
44+
45+
dist := Distance{number: 790.7, unit: Kilometer}
46+
fmt.Sprint(dist)
47+
// => {790.7 0}
48+
// not a very useful output!
4649
```
4750

48-
In order to make the output more informative, we implement interface `Stringer` by adding a `String` method to each type:
51+
In order to make the output more informative, we implement interface `Stringer` for `DistanceUnit` and `Distance` types by adding a `String` method to each type:
4952

5053
```go
5154
func (sc DistanceUnit) String() string {
52-
units := []string{"km", "mi", "nmi"}
55+
units := []string{"km", "mi"}
5356
return units[sc]
5457
}
5558

5659
func (d Distance) String() string {
5760
return fmt.Sprintf("%v %v", d.number, d.unit)
58-
}
61+
}
5962
```
6063

6164
`fmt` package functions will call these methods when formatting `Distance` values:
6265

6366
```go
64-
fmt.Println(distances)
65-
// Output: [790.7 km 415.2 mi 10500 nmi]
67+
kmUnit := Kilometer
68+
kmUnit.String()
69+
// => km
70+
71+
mileUnit := Mile
72+
mileUnit.String()
73+
// => mi
74+
75+
dist := Distance{
76+
number: 790.7,
77+
unit: Kilometer,
78+
}
79+
dist.String()
80+
// => 790.7 km
6681
```
6782

6883
[stringer-interface]: https://pkg.go.dev/fmt#Stringer
69-
[fmt-package]: https://pkg.go.dev/fmt
84+
[fmt-package]: https://pkg.go.dev/fmt

concepts/stringers/introduction.md

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ type Stringer interface {
1010
}
1111
```
1212

13-
Types that want to implement this interface must have a `String()` method that returns a human-friendly string representation of the type. The [fmt][fmt-package] package (and many others) will look for this method to print values.
13+
Types that want to implement this interface must have a `String()` method that returns a human-friendly string representation of the type. The [fmt][fmt-package] package (and many others) will look for this method to format and print values.
1414

1515
## Example: Distances
1616

@@ -23,7 +23,6 @@ type DistanceUnit int
2323
const (
2424
Kilometer DistanceUnit = 0
2525
Mile DistanceUnit = 1
26-
NauticalMile DistanceUnit = 2
2726
)
2827

2928
type Distance struct {
@@ -32,37 +31,53 @@ type Distance struct {
3231
}
3332
```
3433

34+
In the example above, `Kilometer` and `Mile` ane constants of type `DistanceUnit`.
35+
3536
These types do not implement interface `Stringer` as they lack the `String` method.
3637
Hence `fmt` functions will print `Distance` values using Go's "default format":
3738

38-
```go
39-
var distances = []Distance{
40-
{number: 790.7, unit: Kilometer},
41-
{number: 415.2, unit: Mile},
42-
{number: 10_500, unit: NauticalMile},
43-
}
44-
fmt.Println(distances)
45-
// Output: [{790.7 0} {415.2 1} {10500 2}]
39+
```go
40+
mileUnit := Mile
41+
fmt.Sprint(mileUnit)
42+
// => 1
43+
// The result is '1' because that is the underlying value of the 'Mile' contant (see contant declarations above)
44+
45+
dist := Distance{number: 790.7, unit: Kilometer}
46+
fmt.Sprint(dist)
47+
// => {790.7 0}
48+
// not a very useful output!
4649
```
4750

48-
In order to make the output more informative, we implement interface `Stringer` by adding a `String` method to each type:
51+
In order to make the output more informative, we implement interface `Stringer` for `DistanceUnit` and `Distance` types by adding a `String` method to each type:
4952

5053
```go
5154
func (sc DistanceUnit) String() string {
52-
units := []string{"km", "mi", "nmi"}
55+
units := []string{"km", "mi"}
5356
return units[sc]
5457
}
5558

5659
func (d Distance) String() string {
5760
return fmt.Sprintf("%v %v", d.number, d.unit)
58-
}
61+
}
5962
```
6063

6164
`fmt` package functions will call these methods when formatting `Distance` values:
6265

6366
```go
64-
fmt.Println(distances)
65-
// Output: [790.7 km 415.2 mi 10500 nmi]
67+
kmUnit := Kilometer
68+
kmUnit.String()
69+
// => km
70+
71+
mileUnit := Mile
72+
mileUnit.String()
73+
// => mi
74+
75+
dist := Distance{
76+
number: 790.7,
77+
unit: Kilometer,
78+
}
79+
dist.String()
80+
// => 790.7 km
6681
```
6782

6883
[stringer-interface]: https://pkg.go.dev/fmt#Stringer
Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,40 @@
11
# Hints
22

33
## 1. Implement the `Stringer` interface for type `TemperatureUnit`
4-
5-
See [yourbasic.org][yourbasic-enum] for an example how to define a "enum" type with a `String` method.
4+
5+
- The type `TemperatureUnit` is already created for you and represents a temperature unit
6+
- Note that there are already 2 constants created for you that are of this type: `Celsius` and `Fahrenheit`, representing a temperature in Celsius and Fahrenheit, respectively
7+
- Add a `String()` method to the `TemperatureUnit` type so it satisfies the `Stringer` interface. This method must return the string `"°C"` if the temperature unit is Celsius or `"°F"` if the temperature unit is Fahrenheit
68

79
## 2. Implement the `Stringer` interface for type `Temperature`
810

9-
See [yourbasic.org][yourbasic-enum] for an example how to define a "enum" type with a `String` method.
11+
- Add a `String()` method to the `Temperature` type so it satisfies the `Stringer` interface
12+
- The `String()` method should return a string with the numeric value for the temperature and the temperature unit separated by a space (`<temperature> <unit>`)
13+
- The `Temperature` struct contains a `TemperatureUnit` and a `int`. You can use [fmt.Sprintf][sprintf] to help you format this string
14+
- Since `TemperatureUnit` already implements the `Stringer` interface (from task 1), the functions of the `fmt` package like [fmt.Sprintf][sprintf] will know how to format it when you use the `%v` or `%s` [formatting verbs][fmt]
1015

1116
## 3. Implement the `Stringer` interface for type `SpeedUnit`
1217

13-
See [yourbasic.org][yourbasic-enum] for an example how to define a "enum" type with a `String` method.
18+
- The type `SpeedUnit` is already created for you and represents a temperature unit
19+
- Note that there are already 2 constants created for you that are of this type: `KmPerHour` and `MilesPerHour`, representing a speed in kilometers per hour and miles per hour, respectively
20+
- Add a `String()` method to the `SpeedUnit` type so it satisfies the `Stringer` interface. This method must return the string `"km/h"` if the speed unit is kilometers per hour or `"mph"` if the speed unit is miles per hour.
1421

1522
## 4. Implement the `Stringer` interface for `Speed`
1623

17-
See [yourbasic.org][yourbasic-enum] for an example how to define a "enum" type with a `String` method.
24+
- Add a `String()` method to the `Speed` type so it satisfies the `Stringer` interface
25+
- The `String()` method should return a string with the numeric value for the speed and the speed unit separated by a space (`<speed> <unit>`)
26+
- The `Speed` contains a `SpeedUnit` and a `int`. You can use [fmt.Sprintf][sprintf] to help you format this string
27+
- Since `TemperatureUnit` struct already implements the `Stringer` interface (from task 3), the functions of the `fmt` package like [fmt.Sprintf][sprintf] will know how to format it when you use the `%v` or `%s` [formatting verbs][fmt]
28+
- To insert a `%` in the final string when using [fmt.Sprintf][sprintf], use `%%` in the formatting string.
29+
30+
## 5. Implement the `Stringer` interface for type `MeteorologyData`
31+
32+
- The `Speed` contains a `Temperature` and a `Speed` fields, among other fields. You can use [fmt.Sprintf][sprintf] to help you format this string
33+
- The `String` method should return the meteorology data in the following format: `"<location>: <temperature>, Wind <wind_speed> at <wind_direction>, <humidity>% Humidity"`
34+
- Since the `Temperature` and `Speed` types already implement the `Stringer` interface (from task 2 and 4), the functions of the `fmt` package like [fmt.Sprintf][sprintf] will know how to format it when you use the `%v` or `%s` [formatting verbs][fmt]
1835

19-
## 5. Implement the `Stringer` interface for type `MetData`
2036

21-
See [yourbasic.org][yourbasic-enum] for an example how to define a "enum" type with a `String` method.
22-
37+
[fmt]: https://pkg.go.dev/fmt
38+
[sprint]: https://pkg.go.dev/fmt#Sprint
39+
[sprintf]: https://pkg.go.dev/fmt#Sprintf
2340
[yourbasic-enum]: https://yourbasic.org/golang/iota/#complete-enum-type-with-strings-best-practice

exercises/concept/meteorology/.docs/instructions.md

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,51 +7,121 @@ Your task is to add suitable `String` methods to all types so that they implemen
77

88
## 1. Implement the `Stringer` interface for type `TemperatureUnit`
99

10-
After some discussion, the team have agreed that the unit of temperature will be either `Celsius` or `Fahrenheit`. Values should be formatted as shown below:
10+
After some discussion, the team have agreed that the unit of temperature will be either `Celsius` or `Fahrenheit`. Values should be formatted as shown in the examples below.
11+
12+
Make the `TemperatureUnit` type implement the `Stringer` interface by adding a `String` method to it. This method must return the string `"°C"` if the temperature unit is Celsius or `"°F"` if the temperature unit is Fahrenheit.
1113

1214
```go
1315
temperatureUnit := Celsius
14-
fmt.Println(temperatureUnit)
15-
// Output: C
16+
celsiusUnit := Celsius
17+
fahrenheitUnit := Fahrenheit
18+
19+
celsiusUnit.String()
20+
// => °C
21+
fahrenheitUnit.String()
22+
// => °F
23+
fmt.Sprint(celsiusUnit)
24+
// => °C
1625
```
1726

1827
## 2. Implement the `Stringer` interface for type `Temperature`
1928

20-
Temperature values consist of an integer and a temperature unit. They should be formatted as in the example below:
29+
Temperature values consist of an integer and a temperature unit. They should be formatted as in the examples below.
30+
31+
For that to happen, make the `Temperature` type implement the `Stringer` interface by adding a `String` method to it. This method should return a string with the numeric value for the temperature and the temperature unit separated by a space: `<temperature> <unit>`:
32+
2133

2234
```go
23-
temperature := Temperature{21, Celsius}
24-
fmt.Println(temperature)
25-
// Output: 21 °C
35+
celsiusTemp := Temperature{
36+
degree: 21,
37+
unit: Celsius,
38+
}
39+
celsiusTemp.String()
40+
// => 21 °C
41+
fmt.Sprint(celsiusTemp)
42+
// => 21 °C
43+
44+
fahrenheitTemp := Temperature{
45+
degree: 75,
46+
unit: Fahrenheit,
47+
}
48+
fahrenheitTemp.String()
49+
// => 75 °F
50+
fmt.Sprint(fahrenheitTemp)
51+
// => 75 °F
2652
```
2753

2854
## 3. Implement the `Stringer` interface for type `SpeedUnit`
2955

30-
After lengthy discussions, thee team has agreed that the unit of wind speed will be either `KmPerHour` or `MilesPerHour`. Values should be formatted as shown below:
56+
After lengthy discussions, the team has agreed that the unit of wind speed will be either `KmPerHour` or `MilesPerHour`. Values should be formatted as the examples below.
57+
58+
For that to happen, make the `SpeedUnit` type implement the `Stringer` interface by adding a `String` method to it. This method must return the string `"km/h"` if the speed unit is kilometers per hour or `"mph"` if the speed unit is miles per hour:
59+
3160

3261
```go
33-
speedUnit := MilesPerHour
34-
fmt.Println(speedUnit)
35-
// Output: mph
62+
mphUnit := MilesPerHour
63+
mphUnit.String()
64+
// => mph
65+
fmt.Sprint(mphUnit)
66+
// => mph
67+
68+
kmhUnit := KmPerHour
69+
kmhUnit.String()
70+
// => km/h
71+
fmt.Sprint(mphUnit)
72+
// => km/h
3673
```
3774

3875
## 4. Implement the `Stringer` interface for `Speed`
3976

40-
Wind speed values consist of an integer and a speed unit. They should be formatted as in the example below:
77+
Wind speed values consist of an integer and a speed unit. They should be formatted as in the example below.
78+
79+
For that to happen, make the `Speed` type implement the `Stringer` interface by adding a `String` method to it. This method should return a string with the numeric value for the speed and the speed unit separated by a space: `<speed> <unit>`:
4180

4281
```go
43-
windSpeed := Speed{18, KmPerHour}
44-
fmt.Println(windSpeed)
45-
// Output: 18 km/h
82+
windSpeedNow := Speed{
83+
magnitude: 18,
84+
unit: KmPerHour,
85+
}
86+
windSpeedNow.String(windSpeedNow)
87+
// => 18 km/h
88+
fmt.Sprintf(windSpeedNow)
89+
// => 18 km/h
90+
91+
windSpeedYesterday := Speed{
92+
magnitude: 22,
93+
unit: MilesPerHour,
94+
}
95+
windSpeedYesterday.String(windSpeedYesterday)
96+
// => 22 mph
97+
fmt.Sprint(windSpeedYesterday)
98+
// => 22 mph
4699
```
47100

48101
## 5. Implement the `Stringer` interface for type `MetData`
49102

50103
Meteorological data specifies location, temperature, wind direction, wind speed
51-
and humidity. It should be formatted as in the example below:
104+
and humidity. It should be formatted as in the example below:
105+
106+
For that to happen, make the `MeteorologyData` type implement the `Stringer` interface by adding a `String` method to it. This method should return the meteorology data in the following format: `"<location>: <temperature>, Wind <wind_speed> at <wind_direction>, <humidity>% Humidity"`:
52107

53108
```go
54-
metData := MetData{"San Francisco", Temperature{57, Fahrenheit}, "NW", Speed{19, MilesPerHour}, 60}
55-
fmt.Println(metData)
56-
// Output: San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity
109+
sfData := MeteorologyData{
110+
location: "San Francisco",
111+
temperature: Temperature{
112+
degree: 57,
113+
unit: Fahrenheit
114+
},
115+
windDirection: "NW",
116+
windSpeed: Speed{
117+
magnitude: 19,
118+
unit: MilesPerHour
119+
},
120+
humidity: 60
121+
}
122+
123+
sfData.String()
124+
// => San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity
125+
fmt.Sprint(sfData)
126+
// => San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity
57127
```

0 commit comments

Comments
 (0)