Tracks
/
Elixir
Elixir
/
Ejercicios
/
Auto de control remoto
Auto de control remoto

Auto de control remoto

Ejercicio de aprendizaje

Introducción

Structs

Los structs son una extensión construida sobre los mapas, que proporcionan verificaciones en tiempo de compilación y valores predeterminados. Un struct recibe el nombre del módulo en el que se define. Para definir un struct, usa la construcción defstruct. Por lo general, la construcción va inmediatamente después de la definición del módulo. defstruct acepta una lista de átomos (para valores predeterminados nil) o una lista de palabras clave (para valores predeterminados especificados). Los campos sin valores predeterminados deben ir antes que los campos con valores predeterminados.

defmodule Plane do
  defstruct [:engine, wings: 2]
end

plane = %Plane{}
# => %Plane{engine: nil, wings: 2}

Acceder a los campos y actualizarlos

Como los structs se construyen sobre mapas, podemos usar la mayoría de las funciones de mapas para obtener y manipular valores. El Access Behaviour no está implementado para los structs. En su lugar, se recomienda usar el operador de acceso estático . para acceder a los campos del struct.

  • obtener/consultar los valores de los campos:

    plane = %Plane{}
    plane.engine
    # => nil
    Map.fetch(plane, :wings)
    # => {:ok, 2}
    
  • actualizar los valores de los campos

    plane = %Plane{}
    %{plane | wings: 4}
    # => %Plane{engine: nil, wings: 4}
    

Coincidencia de patrones

Los structs se pueden usar en la coincidencia de patrones con o sin el nombre del struct.

plane = %Plane{}
%Plane{wings: wings} = plane
%{wings: wings} = plane

Al incluir el nombre del struct en el patrón, puedes asegurarte de que tanto el lado izquierdo como el derecho sean structs del mismo tipo.

defmodule Helicopter do
  defstruct [:engine, rotors: 1]
end

%Plane{} = %Helicopter{}
# => (MatchError) no match of right hand side value: %Helicopter{engine: nil, rotors: 1}

Exigir la inicialización de los valores de los campos

Podemos usar el atributo de módulo @enforce_keys con una lista de las claves de los campos para asegurarnos de que los valores se inicialicen cuando se crea el struct. Si una clave no está en la lista, su valor será nil, como se vio en el ejemplo anterior. Si una clave exigida no se inicializa, se produce un error.

defmodule User do
  @enforce_keys [:username]
  defstruct [:username]
end

%User{}
# => (ArgumentError) the following keys must also be given when building struct User: [:username]

Instrucciones

En este ejercicio vas a jugar con un auto a control remoto, para el que por fin ahorraste suficiente dinero para comprarlo.

Los autos empiezan con la batería llena (100%). Cada vez que conduces el auto con el control remoto, recorre 20 metros y consume uno por ciento de la batería. El apodo del auto no se conoce hasta que se crea.

El auto a control remoto tiene una elegante pantalla LED que muestra dos datos:

  • La distancia total que ha recorrido, mostrada como: "<METERS> meters".
  • La carga restante de la batería, mostrada como: "Battery at <PERCENTAGE>%".

Si la batería está al 0%, ya no puedes conducir el auto y la pantalla de la batería mostrará "Battery empty".

1. Crea un auto a control remoto totalmente nuevo

Implementa la función RemoteControlCar.new/0 para que devuelva un struct de auto a control remoto totalmente nuevo:

RemoteControlCar.new()
# => %RemoteControlCar{
#      battery_percentage: 100,
#      distance_driven_in_meters: 0,
#      nickname: "none"
#    }

El struct requiere el apodo; asegúrate de inicializar un valor en la función new, pero no en el struct.

2. Crea un auto a control remoto totalmente nuevo con un apodo

Implementa la función RemoteControlCar.new/1 para que devuelva un struct de auto a control remoto totalmente nuevo con un apodo proporcionado:

RemoteControlCar.new("Blue")
# => %RemoteControlCar{
#      battery_percentage: 100,
#      distance_driven_in_meters: 0,
#      nickname: "Blue"
#    }

3. Muestra la distancia

Implementa la función RemoteControlCar.display_distance/1 para que devuelva la distancia tal como se muestra en la pantalla LED:

car = RemoteControlCar.new()
RemoteControlCar.display_distance(car)
# => "0 meters"

Asegúrate de que la función solo acepte un struct RemoteControlCar como argumento.

4. Muestra el porcentaje de batería

Implementa la función RemoteControlCar.display_battery/1 para que devuelva el porcentaje de batería tal como se muestra en la pantalla LED:

car = RemoteControlCar.new()
RemoteControlCar.display_battery(car)
# => "Battery at 100%"

Asegúrate de que la función solo acepte un struct RemoteControlCar como argumento. Si la batería está al 0%, la pantalla de la batería mostrará "Battery empty".

5. Conducir cambia la batería y la distancia recorrida

Implementa la función RemoteControlCar.drive/1 que:

  • aumente en 20 la cantidad de metros recorridos
  • consuma el 1% de la batería
RemoteControlCar.new("Red")
|> RemoteControlCar.drive()

# => %RemoteControlCar{
#      battery_percentage: 99,
#      distance_driven_in_meters: 20,
#      nickname: "Red"
#    }

Asegúrate de que la función solo acepte un struct RemoteControlCar como argumento.

6. Ten en cuenta la conducción con la batería agotada

Actualiza la función RemoteControlCar.drive/1 para que no aumente la distancia recorrida ni disminuya el porcentaje de batería cuando la batería esté descargada (al 0%):

%RemoteControlCar{
  battery_percentage: 0,
  distance_driven_in_meters: 1980,
  nickname: "Red"
}
|> RemoteControlCar.drive()

# => %RemoteControlCar{
#      battery_percentage: 0,
#      distance_driven_in_meters: 1980,
#      nickname: "Red"
#    }
Editar en GitHub El enlace se abre en una ventana o una pestaña nuevas
Elixir Exercism

¿Todo listo para empezar Auto de control remoto?

Regístrate en Exercism para aprender y dominar Elixir con 58 conceptos168 ejercicios y mentoría humana real, todo gratis.