Rutas
/
Go
Go
/
Ejercicios
/
Meteorología
Meteorología

Meteorología

Ejercicio de aprendizaje

Introducción

Stringer es una interfaz para definir el formato string de los valores.

La interfaz consta de un único método String:

type Stringer interface {
    String() string
}

Los tipos que quieran implementar esta interfaz deben tener un método String() que devuelva una representación del tipo legible para las personas. El paquete fmt (y muchos otros) buscará este método para dar formato e imprimir valores.

Ejemplo: distancias

Supongamos que trabajamos en una aplicación que maneja distancias geográficas medidas en distintas unidades. Hemos definido los tipos DistanceUnit y Distance de la siguiente manera:

type DistanceUnit int

const (
	Kilometer    DistanceUnit = 0
	Mile         DistanceUnit = 1
)

type Distance struct {
	number float64
	unit   DistanceUnit
}

En el ejemplo anterior, Kilometer y Mile son constantes de tipo DistanceUnit.

Estos tipos no implementan la interfaz Stringer, ya que no tienen el método String. Por lo tanto, las funciones de fmt imprimirán los valores de Distance usando el «formato predeterminado» de Go:

mileUnit := Mile
fmt.Sprint(mileUnit)
// => 1
// The result is '1' because that is the underlying value of the 'Mile' constant (see constant declarations above)

dist := Distance{number: 790.7, unit: Kilometer}
fmt.Sprint(dist)
// => {790.7 0}
// not a very useful output!

Para que la salida sea más informativa, implementamos la interfaz Stringer para los tipos DistanceUnit y Distance añadiendo un método String a cada tipo:

func (sc DistanceUnit) String() string {
	units := []string{"km", "mi"}
	return units[sc]
}

func (d Distance) String() string {
	return fmt.Sprintf("%v %v", d.number, d.unit)
}

Las funciones del paquete fmt llamarán a estos métodos al dar formato a los valores de Distance:

kmUnit := Kilometer
kmUnit.String()
// => km

mileUnit := Mile
mileUnit.String()
// => mi

dist := Distance{
	number: 790.7,
	unit: Kilometer,
}
dist.String()
// => 790.7 km

Instrucciones

Tu equipo trabaja en una aplicación de meteorología. Han definido una API con varios tipos y constantes que representan datos meteorológicos; consulta el archivo meteorology.go.

Tu tarea es añadir métodos String adecuados a todos los tipos para que implementen la interfaz Stringer.

1. Implementa la interfaz Stringer para el tipo TemperatureUnit

Tras un pequeño debate, el equipo ha acordado que la unidad de temperatura será Celsius o Fahrenheit. Los valores deben formatearse como se muestra en los ejemplos siguientes.

Haz que el tipo TemperatureUnit implemente la interfaz Stringer añadiéndole un método String. Este método debe devolver el string "°C" si la unidad de temperatura es Celsius o "°F" si la unidad de temperatura es Fahrenheit.

celsiusUnit := Celsius
fahrenheitUnit := Fahrenheit

celsiusUnit.String()
// => °C
fahrenheitUnit.String()
// => °F
fmt.Sprint(celsiusUnit)
// Output: °C

2. Implementa la interfaz Stringer para el tipo Temperature

Los valores de temperatura constan de un número entero y una unidad de temperatura. Deben formatearse como en los ejemplos siguientes.

Para conseguirlo, haz que el tipo Temperature implemente la interfaz Stringer añadiéndole un método String. Este método debe devolver un string con el valor numérico de la temperatura y la unidad de temperatura separados por un espacio: <temperature> <unit>:

celsiusTemp := Temperature{
    degree: 21,
    unit: Celsius,
}
celsiusTemp.String()
// => 21 °C
fmt.Sprint(celsiusTemp)
// Output: 21 °C

fahrenheitTemp := Temperature{
    degree: 75,
    unit: Fahrenheit,
}
fahrenheitTemp.String()
// => 75 °F
fmt.Sprint(fahrenheitTemp)
// Output: 75 °F

3. Implementa la interfaz Stringer para el tipo SpeedUnit

Tras largos debates, el equipo ha acordado que la unidad de velocidad del viento será KmPerHour o MilesPerHour. Los valores deben formatearse como en los ejemplos siguientes.

Para conseguirlo, haz que el tipo SpeedUnit implemente la interfaz Stringer añadiéndole un método String. Este método debe devolver el string "km/h" si la unidad de velocidad es kilómetros por hora o "mph" si la unidad de velocidad es millas por hora:

mphUnit := MilesPerHour
mphUnit.String()
// => mph
fmt.Sprint(mphUnit)
// Output: mph

kmhUnit := KmPerHour
kmhUnit.String()
// => km/h
fmt.Sprint(kmhUnit)
// Output: km/h

4. Implementa la interfaz Stringer para Speed

Los valores de velocidad del viento constan de un número entero y una unidad de velocidad. Deben formatearse como en el ejemplo siguiente.

Para conseguirlo, haz que el tipo Speed implemente la interfaz Stringer añadiéndole un método String. Este método debe devolver un string con el valor numérico de la velocidad y la unidad de velocidad separados por un espacio: <speed> <unit>:

windSpeedNow := Speed{
    magnitude: 18,
    unit: KmPerHour,
}
windSpeedNow.String()
// => 18 km/h
fmt.Sprintf(windSpeedNow)
// Output: 18 km/h

windSpeedYesterday := Speed{
    magnitude: 22,
    unit: MilesPerHour,
}
windSpeedYesterday.String()
// => 22 mph
fmt.Sprint(windSpeedYesterday)
// Output: 22 mph

5. Implementa la interfaz Stringer para el tipo MeteorologyData

Los datos meteorológicos especifican la ubicación, la temperatura, la dirección del viento, la velocidad del viento y la humedad. Deben formatearse como en el ejemplo siguiente:

Para conseguirlo, haz que el tipo MeteorologyData implemente la interfaz Stringer añadiéndole un método String. Este método debe devolver los datos meteorológicos con el siguiente formato:

<location>: <temperature>, Wind <wind_direction> at <wind_speed>, <humidity>% Humidity
sfData := MeteorologyData{
    location: "San Francisco",
    temperature: Temperature{
        degree: 57,
        unit: Fahrenheit
    },
    windDirection: "NW",
    windSpeed: Speed{
        magnitude: 19,
        unit: MilesPerHour
    },
    humidity: 60
}

sfData.String()
// => San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity
fmt.Sprint(sfData)
// Output: San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Go Exercism

¿Listo para empezar Meteorología?

Regístrate en Exercism para aprender y dominar Go con 34 conceptos165 ejercicios y mentoría humana real, todo gratis.