N070 Hastighedskonvertering
Du skal designe et værktøj, der hjælper brugeren med at konvertere hastighed fra miles per hour (MPH) til kilometer i timen (KMT). Brugeren skal have mulighed for at indtaste en hastighed i MPH (som et heltal), og værktøjet skal derefter vise den tilsvarende hastighed i KMT (med eller uden decimaler). Formlen for konvertering er: KMT = MPH x 1.60934. Værktøjet skal først vise en besked, der beder brugeren om at indtaste en hastighed i MPH. Efter indtastning skal værktøjet vise den konverterede hastighed i KMT ved hjælp af den tidligere nævnte metode.
Information til undervisere
Dette er en opgave som typisk kan bruges til “fælles opgaveløsning” fordi der er elementer som kunne kræve en instruktør. Til sidst er en del ekstra tillæg som typisk viser forskellige teknologier.
Den kunne bruges som et afsluttende projekt efter en halv dags undervisning.
Eksempel på konsolinteraktion:
Version 1: Iterativ løsning (uden metode)
Opgaven kan løses på mange måder men prøv at løse den uden at tænke på genbrugelighed mv - bare skriv koden i sin første version.
Version 2: Procedural løsning (med metode)
For at sikre genbrugelighed og enkelhed i din løsning, anbefales det at oprette en særskilt metode, der håndterer konverteringen. Denne metode kan tage en hastighed i MPH som parameter og returnere den tilsvarende hastighed i KMT. Ved at isolere konverteringslogikken i sin egen metode gør du det nemmere at genbruge denne funktionalitet i fremtidige projekter eller udvide værktøjet med yderligere funktioner.
Prøv at skrive version 2.
Version 3: Fejlhåndtering
Metoden bør tjekke, om det indtastede input faktisk er et tal. Hvis ikke, bør den returnere en fejlmeddelelse. Yderligere bør den også tjekke for negative tal, da hastighed ikke kan være negativ. Hvis et negativt tal indtastes, bør en fejlmeddelelse returneres.
Eksempler på en fejlmeddelelse kunne være:
Prøv at skrive version 3.
Tips til C#
1. Udskrivning på konsol:
2. Hente input fra konsol:
3. Typekonvertering: For at konvertere en streng til et heltal (int):
4. Eksempel på en metode:
5. Fejlhåndtering:
try
{
int num = int.Parse(input);
}
catch (FormatException)
{
Console.WriteLine("Input var ikke et gyldigt tal.");
}
Tips til Python
1. Udskrivning på konsol:
2. Hente input fra konsol:
3. Typekonvertering: For at konvertere en streng til et heltal (int):
4. Eksempel på en metode:
5. Fejlhåndtering:
Løsning i C#
Version 1: Iterativ løsning (uden metode)
using System;
Console.Write("Indtast hastighed i MPH: ");
string input = Console.ReadLine();
double mph = double.Parse(input);
double kmt = mph * 1.60934;
Console.WriteLine($"Resultat: {mph} MPH er lig med {kmt} KMT.");
Version 2: Procedural løsning (med metode)
using System;
Console.Write("Indtast hastighed i MPH: ");
string input = Console.ReadLine();
double mph = double.Parse(input);
double kmt = ConvertMphToKmt(mph);
Console.WriteLine($"Resultat: {mph} MPH er lig med {kmt} KMT.");
double ConvertMphToKmt(double mph)
{
return mph * 1.60934;
}
Version 3: Fejlhåndtering
using System;
Console.Write("Indtast hastighed i MPH: ");
string input = Console.ReadLine();
try
{
double mph = double.Parse(input);
if (mph < 0)
{
Console.WriteLine("Hastighed kan ikke være negativ.");
return;
}
double kmt = ConvertMphToKmt(mph);
Console.WriteLine($"Resultat: {mph} MPH er lig med {kmt} KMT.");
}
catch (FormatException)
{
Console.WriteLine("Input var ikke et gyldigt tal.");
}
double ConvertMphToKmt(double mph)
{
return mph * 1.60934;
}
Løsning i Python
Version 1: Iterativ løsning (uden funktion)
input_data = input("Indtast hastighed i MPH: ")
mph = float(input_data)
kmt = mph * 1.60934
print(f"Resultat: {mph} MPH er lig med {kmt:.4f} KMT.")
Version 2: Procedural løsning (med funktion)
def convert_mph_to_kmt(mph):
return mph * 1.60934
input_data = input("Indtast hastighed i MPH: ")
mph = float(input_data)
kmt = convert_mph_to_kmt(mph)
print(f"Resultat: {mph} MPH er lig med {kmt:.4f} KMT.")
Version 3: Fejlhåndtering
def convert_mph_to_kmt(mph):
return mph * 1.60934
input_data = input("Indtast hastighed i MPH: ")
try:
mph = float(input_data)
if mph < 0:
print("Hastighed kan ikke være negativ.")
else:
kmt = convert_mph_to_kmt(mph)
print(f"Resultat: {mph} MPH er lig med {kmt:.4f} KMT.")
except ValueError:
print("Input var ikke et gyldigt tal.")
Ekstra: WPF Brugerflade
Der er mange måder at skabe en brugerflade i .NET til alle platforme. På en ren Windows platform er WPF en af mulighederne. Prøv følgende i en tom mappe:
Tilret MainWindow.xaml
til følgende
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Speed Converter" Height="200" Width="400">
<Grid Margin="10">
<Label Content="Enter speed in mph:" VerticalAlignment="Top" />
<TextBox x:Name="mphTextBox" VerticalAlignment="Top" Margin="0,25,0,0" />
<Button Content="Convert to kmt" VerticalAlignment="Top" Margin="0,60,0,0" Click="OnConvertClicked" />
<Label x:Name="resultLabel" VerticalAlignment="Top" Margin="0,100,0,0" />
</Grid>
</Window>
og MainWindow.cs
til følgende
using System;
using System.Windows;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void OnConvertClicked(object sender, RoutedEventArgs e)
{
if (double.TryParse(mphTextBox.Text, out double mph))
{
try
{
double kmt = ConvertMphToKmt(mph);
resultLabel.Content = $"Result: {kmt} kmt";
}
catch (ArgumentException ex)
{
resultLabel.Content = ex.Message;
}
}
else
{
resultLabel.Content = "Please enter a valid number.";
}
}
double ConvertMphToKmt(double mph)
{
return mph * 1.60934;
}
}
Kør applikationen med
Ikke super køn og “UI-agtig” brugerflade men det er nemt at tilrette - især i værktøjer som VS.
Ekstra: Web
En web brugerflade kan eksempelvis skabes med ASP.NET MVC. Prøv følgende i en tom mappe:
Tilret herefter /Views/Home/Index.cshtml
til
@{
ViewData["Title"] = "Speed Converter";
}
<h2>@ViewData["Title"]</h2>
<form asp-action="Convert" method="post">
<div>
<label>Enter speed in mph:</label>
<input type="text" name="mph" />
</div>
<div>
<input type="submit" value="Convert to kmt" />
</div>
</form>
@if (ViewBag.Result != null)
{
<div>
<strong>Result:</strong> @ViewBag.Result kmt
</div>
}
og /Controllers/HomeController.cs
til
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
{
[HttpGet("~/")]
[HttpPost("~/")]
public IActionResult Convert(double mph)
{
try
{
double kmt = ConvertMphToKmt(mph);
ViewBag.Result = kmt;
}
catch (ArgumentException ex)
{
ViewBag.Result = ex.Message;
}
return View("Index");
}
[HttpGet("~/Privacy")]
public IActionResult Privacy()
{
return View();
}
double ConvertMphToKmt(double mph)
{
return mph * 1.60934;
}
}
Prøv herefter at køre applikationen med dotnet run
. Det burde resultere i noget ala
PS C:\temp\SpeedConverterWebApp> dotnet run
Building...
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5292
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\temp\SpeedConverterWebApp
hvorefter applikationen kan tilgås ved at indtaste http://localhost:5292 i en browser.
Ekstra: Unit test
Se i øvrigt denne side for at få en ide om hvordan unit test virker.
Ekstra: HTTP Service
Som eksempel på konvertering af opgaven så den benytter en HTTP service kan du hente et Docker image og kalde metoden over nettet i stedet. Se GitHub for at installere service (kræver Docker Desktop).
Når først tjenesten kører kan alle mulige klienter benytte den - her C# og Python.
Løsning i C#
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading.Tasks;
const string ServiceUrl = "http://localhost:8080/api/speedconverter";
var client = new HttpClient();
// GET request
var responseJson = await client.GetFromJsonAsync<SpeedResponse>($"{ServiceUrl}?mph=60");
Console.WriteLine($"GET: {responseJson?.Mph} MPH er lig med {responseJson?.Kmt} KMT. Server tid: {responseJson?.ServerTime}");
// POST request
var data = new { Mph = 60 };
var postResponse = await client.PostAsJsonAsync(ServiceUrl, data);
var postResponseJson = await postResponse.Content.ReadFromJsonAsync<SpeedResponse>();
Console.WriteLine($"POST: {postResponseJson?.Mph} MPH er lig med {postResponseJson?.Kmt} KMT. Server tid: {postResponseJson?.ServerTime}");
public class SpeedResponse
{
public double Mph { get; set; }
public double Kmt { get; set; }
public DateTime ServerTime { get; set; }
}
Løsning i Python
import requests
SERVICE_URL = "http://localhost:8080/api/speedconverter"
# GET request
response = requests.get(f"{SERVICE_URL}?mph=60")
response_json = response.json()
print(f"GET: {response_json['Mph']} MPH er lig med {response_json['Kmt']} KMT. Server tid: {response_json['ServerTime']}")
# POST request
data = {"Mph": 60}
post_response = requests.post(SERVICE_URL, json=data)
post_response_json = post_response.json()
print(f"POST: {post_response_json['Mph']} MPH er lig med {post_response_json['Kmt']} KMT. Server tid: {post_response_json['ServerTime']}")