Problem med skoluppgift, Bastun, C#

Permalänk
Medlem

Problem med skoluppgift, Bastun, C#

Hej!
Sitter och läser en preparandkurs för en utbildning som jag förhoppningsvis ska köra i slutet på augusti.
Som många andra har jag problem med uppgiften Bastun och något går fel. Tycker koden verkar korrekt, om än inte så snygg.

using System; namespace Bastu { class Program { public static int FahrToCel(int fahr) { int cel = ((fahr - 32) * 5/ 9); return cel; } static void Main(string[] args) { int maxTemp = 77; int minTemp = 73; int optiTemp = 75; int cel; Console.WriteLine("Welcome to the Sauna!"); Console.WriteLine("Please enter a temperature in fahrenheit"); do { int fahr = Int32.Parse(Console.ReadLine()); cel = FahrToCel(fahr); if (cel > maxTemp) { Console.WriteLine("The Sauna is too hot! Turn down the temperature!"); } else if (cel < minTemp) { Console.WriteLine("The Sauna is too cold! Turn up the temperature!"); } else if (cel == optiTemp) { Console.WriteLine("The Sauna now has a perfect temperature, have a nice visit!"); } else { Console.WriteLine("The sauna has a decent temperature now, enjoy"); } } while (cel >= minTemp || cel <= maxTemp); Console.ReadKey(); } } }

Linjen " int fahr = int.Parse(Console.ReadLine()); " är vad som ger mig ett fel varje gång, då den säger att "System.FormatException: 'Input string was not in a correct format.'"
jag har suttit och skrivit om detta så många gånger att jag förmodligen rört till det mer än jag löst det. Är väldigt ny så kan inte så många sätt att vöersätta string till int, men "kan" parse, och convert.ToInt32.
I denna uppgift vill dock att man använder parse som jag förstått det.

Om någon ser vad jag gjort för fel så tar jag gärna emot feedback, inte en lösning för jag måste lära mig detta
Mvh Gustav

Permalänk
Medlem

Parse kastar en exception ifall strängen inte kunde tolkas som ett heltalsnummer. Så det är egentligen inget fel på koden som sådan, utan felet bör snarare vara vad du matar in. Om du bara matar in t.ex. 75 och trycker på enter när programmet frågar efter en temperatur, får du samma fel då också?

Sen bör du förstås hantera felet när användaren matar in ett felaktigt värde m.h.a. en catch-sats runt Parse, men programmet ska fungera ändå så länge som ett korrekt värde matas in.

Permalänk
Medlem

Hej! Tack för svar.
Ja det blir samma fel när jag sätter in siffror, exempelvis 75. Det verkar inte spela någon roll vad jag fyller i, felet uppstår iallafall

Skickades från m.sweclockers.com

Permalänk
Medlem

Efter att jag testad koden själv så får jag inget fel alls(copy & paste).
Något som kanske skulle kunna ge fel är "int fahr = Int32.Parse(Console.ReadLine());", varför ha Int32.Parse och inte bara int.Parse?

Permalänk
Medlem

Hmm. Ska göra så att när jag kommer hen ikväll ska jag copy paste koden i ett nytt projekt och se vad som händer. Ang int.32.parse och int.parse så är det nog för att jag suttit och testst så många alternativ att det var det som vart i slutändan!

Skickades från m.sweclockers.com

Permalänk

Int32.Parse borde som tidigare nämnts inte ha några problem att tolka "75".
Det du dock bör tänka på att den inte kan tolka något annat än just siffror.

När du fått Int32.Parse att fungera bör du fundera på att ha någon felhantering om användaren försöker skriva in något helt annat, t.ex. int.TryParse eller en try/catch annars kommer hela ditt program att krascha.

Permalänk
Medlem

Tack för alla svar. Hade en try catch förut men då fick jag ett annat fel , för krångligt att skriva över telefon, men får jag inte koden att funka ilväll skriver jag igrn! Tack för hjälpen alla!

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av Masadan:

Efter att jag testad koden själv så får jag inget fel alls(copy & paste).
Något som kanske skulle kunna ge fel är "int fahr = Int32.Parse(Console.ReadLine());", varför ha Int32.Parse och inte bara int.Parse?

int är bara ett alias på Int32, så int.Parse() & Int32.Parse() kommer generera samma kod.

OnT: Kopierar du in värdet från t.ex en textfil? Så du eventuellt kan fått med en newline före värdet?

Permalänk
Medlem
Skrivet av Zedong:

OnT: Kopierar du in värdet från t.ex en textfil? Så du eventuellt kan fått med en newline före värdet?

Vad jag vet är parse relativt snällt vad gäller sådant, provade just att köra:
int test = Int32.Parse("\r\n63\r\n");

och den hanterade det utan att ge något felmeddelande. (kanske skiljer sig mellan versioner av visual studio och/eller .net?)

Föreslår ju dock som andra tidigare nämnt att lägga in någon form av felhantering runt parse-funktionen, TryParse är väl den rekommenderade metoden. Lika bra att lära sig göra det på "rätt" sätt från början, sett så många exempel på parse utan felhantering och liknande i produktionskod att man ibland blir orolig.

Sedan finns det ju andra saker i koden som sannolikt inge ger förväntat resultat men eftersom det är en skoluppgift behöver vi ju inte spoila saker som inte gäller det aktuella felet

Permalänk

Jag gjorde programmet nu på kvällen och jag använde två whileloopar som egentligen inte kollade något utan jag har alltid true(vilket kan bli oändlig loop om man gör fel), sedan kör jag break när något infaller som passar.

Kör try{ testa detta} catch {gör detta om try stötte på fel }

Permalänk
Medlem

Återigen, tack för hjälpen alla, har fått till uppgiften nu efter några timmars pillande och testande med era förslag.
Har sparat den "fungerande" koden i ett projekt och ska ge mig på att förbättra koden så jag kan få in floats istället.
Även om det inte spelar någon större roll för världen så lägger jag upp kodens om funkade iaf, så tar jag väldigt gärna feedback på den om ni ser något som man kan göra snyggare/bättre, you get the point!

using System; namespace Bastu { class Program { public static int FahrToCel(int fahr) { int cel = ((fahr - 32) * 5/ 9); return cel; } static void Main(string[] args) { int maxTemp = 77; int minTemp = 73; int optiTemp = 75; int cel = 0; Console.WriteLine("Welcome to the Sauna!"); do { try { Console.WriteLine("Please enter a temperature in fahrenheit"); int fahr = int.Parse(Console.ReadLine()); cel = FahrToCel(fahr); } catch (Exception) { Console.WriteLine("Please enter only numbers"); continue; } if (cel > maxTemp) { Console.WriteLine("The Sauna is too hot! Turn down the temperature!"); } else if (cel < minTemp) { Console.WriteLine("The Sauna is too cold! Turn up the temperature!"); } else if (cel == optiTemp) { Console.WriteLine("The Sauna now has a perfect temperature, have a nice visit!"); break; } else { Console.WriteLine("The sauna has a decent temperature now, enjoy"); break; } } while (cel >= minTemp || cel <= maxTemp); Console.ReadKey(); } } }

Permalänk

Jag hade tittat på att förtydliga variabelnamnen så att det blir tydligare, dokumentera mer använd //sen text så att det går att läsa ut vad varje del gör.

Kör double istället. Har något minne av att jag läste/hörde någonstans att double blir bättre att använda hmm undrar om det var om man ska casta till något annat hmm.

Vad sa uppgiften? Jag hittade en uppgift på internet som bara efterfrågade att kontrollera att värdet är inom max och minimum.

Kan kopiera min lösning när jag är hemma sen.

Tror inte du behöver break i en if sats då du har while som har ett kriterie som den lyssnar på varje varv

Skrivet av Gurral83:

Återigen, tack för hjälpen alla, har fått till uppgiften nu efter några timmars pillande och testande med era förslag.
Har sparat den "fungerande" koden i ett projekt och ska ge mig på att förbättra koden så jag kan få in floats istället.
Även om det inte spelar någon större roll för världen så lägger jag upp kodens om funkade iaf, så tar jag väldigt gärna feedback på den om ni ser något som man kan göra snyggare/bättre, you get the point!

using System; namespace Bastu { class Program { public static int FahrToCel(int fahr) { int cel = ((fahr - 32) * 5/ 9); return cel; } static void Main(string[] args) { int maxTemp = 77; int minTemp = 73; int optiTemp = 75; int cel = 0; Console.WriteLine("Welcome to the Sauna!"); do { try { Console.WriteLine("Please enter a temperature in fahrenheit"); int fahr = int.Parse(Console.ReadLine()); cel = FahrToCel(fahr); } catch (Exception) { Console.WriteLine("Please enter only numbers"); continue; } if (cel > maxTemp) { Console.WriteLine("The Sauna is too hot! Turn down the temperature!"); } else if (cel < minTemp) { Console.WriteLine("The Sauna is too cold! Turn up the temperature!"); } else if (cel == optiTemp) { Console.WriteLine("The Sauna now has a perfect temperature, have a nice visit!"); break; } else { Console.WriteLine("The sauna has a decent temperature now, enjoy"); break; } } while (cel >= minTemp || cel <= maxTemp); Console.ReadKey(); } } }

Skickades från m.sweclockers.com

Permalänk
Medlem

Hej igen! Kollade noggrannare på uppgiften och insåg att det ENDA som behövde vara i int från början var int fahr. Jag skrev till lite extra i koden och omvandlade till double som ni rekommenderat. La även till lite avrundningar och kommentarer (extremt övertydliga iom skoluppgift).
Allt verkar funka bra nu och tror uppgiften kan ge ett C i betyg iaf.
Kommentera gärna!

using System; namespace Bastu { class Program { public static double FahrToCel(int fahr)//Metod som tar in int fahr (fahrenheit) men konverterar till double cel (celcius) och returnerar celcius { double cel = System.Convert.ToDouble(fahr); //int till double cel = ((fahr - 32.0) * 5.0 / 9.0); return cel; } static void Main(string[] args) { double maxTemp = 77.0;// deklarerar värden som ska jämnföras i vilkoren senare, de behövs här så de nås överallt double minTemp = 73.0; double optiTemp = 75.0; double cel = 0.0; //samma gäller denna, men den får värdet 0.0 då det kommer att ändras när användaren sätter in ett värde. Console.WriteLine("Welcome to the Sauna!"); do // loopen körs minst en gång och kommer då först be om att få ett fahrenheit värde av användaren { try // satte try här för den största risken för fel är vid user input, ex bokstäver istället för siffror { Console.WriteLine("Please enter a temperature in fahrenheit"); int fahr = int.Parse(Console.ReadLine()); // ett värde tas in, och tilldelas int fahr. cel = FahrToCel(fahr); // Metoden fahrenheit to celcius anropas, och returnerar ett double värde till cel } catch (Exception)// Om nått blir fel så kommer användaren få ett meddelande om att bara använda siffror { Console.WriteLine("Please enter only numbers"); continue;// Så att loopen inte stannar här utan startar om och ger "Amerikanen" ett nytt försök } if (cel > maxTemp)//Ber om nytt temp då nuvarande är för hög, samt skriver ut nuvarande temp, avrundat till 2 decimaler { Console.WriteLine("The Sauna is too hot! Its " + Math.Round(cel, 2) + " celcius! Turn down the temperature!"); } else if (cel < minTemp)//Ber om ny temp då nuvarande är för låg, samt skriver ut nuvarande temp, avrundat till 2 decimaler { Console.WriteLine("The Sauna is too cold! Its only " + Math.Round(cel, 2) + " celcius! Turn up the temperature!"); } else if (cel == optiTemp)//Avslutar loopen då bästa resultatet uppnåtts och säger vad tempen är, avrundat till 2 decimaler { Console.WriteLine("The Sauna now has a perfect temperature of " + Math.Round(cel, 2) + "celcius! Have a nice visit!"); break; } else//Bastun är i ett godkänt temp intervall , tempen skrivs ut, avrundat till 2dec { Console.WriteLine("The sauna has a decent temperature now of " + Math.Round(cel, 2) + " celcius! Enjoy"); break; } } while (cel >= minTemp || cel <= maxTemp); //Villkoret för hur länge loopen ska köra Console.ReadKey(); } } }

Permalänk
Medlem

@Gurral83: Lägg Console.WriteLine("Please enter a temperature in fahrenheit"); utanför/innan din try/catch

Permalänk

@Gurral83:
Se nedan hur jag gjorde men jag har enbart kontrollerat om temperaturen är lika med eller högre än 73 och lika med eller under 77
Samt inte kommentera allt utan lagom är bäst även om jag nu ser att jag kunde skrivit vissa anteckningar lite bättre och smartare

using System; namespace Bastu { class Program { //const temperatures in celcius const int minimumTemperature = 73; const int maximumTemperature = 77; private static int convertFahrenheitToCelsius(int fahrenheit) { int celsius = (fahrenheit - 32) * 5 / 9; return celsius; } static void Main(string[] args) { string inputTemperatureInFahrenheit; int fahrenheit = 0; //Allways true until the temperature is between 73 and 77 then the loop breaks while (true) { //Allways true unless only numbers are converted from input then the loop breaks while (true) { //Takes user input of temperature Console.WriteLine("Enter temperature: "); inputTemperatureInFahrenheit = Console.ReadLine(); try { fahrenheit = int.Parse(inputTemperatureInFahrenheit); break; } catch { Console.WriteLine("Only whole numbers is valid"); } } //Checks the temperature if (convertFahrenheitToCelsius(fahrenheit) < minimumTemperature) { Console.WriteLine("Temperature is to low, Turn up the temperature"); } else if (convertFahrenheitToCelsius(fahrenheit) > maximumTemperature) { Console.WriteLine("Temperature is to high, Turn down the temperature"); } else { Console.WriteLine("Temperature is acceptable range"); break; } } } } }

Permalänk
Medlem

@Gurral83: Jag hade tagit bort alla kommentarer i koden. Varför kommentera något som redan är väldigt obvious vad det gör? Skriver man kod med bra namngivna metoder och variabler så ska inte kommenterar behövas.

Skriv celcius istället för cel, fahrenheit istället för fahr, optimalTemp istället för optiTemp.
Metoden FahrenheitToCelcius.

Förkortningar är bara förvirrande och bör i största möjlighet undvikas. Om det inte är väldigt obvious standard förkortning så som str för string och arr för array via en iteration.

Permalänk

@zaibuf: Många skolor har det som krav att man ska kommentera.
När jag gick programmering 1 så var dem noga med det

Permalänk
Medlem

@zaibuf: Gjorde nyligen Programmering 1 och tentar av Programmering 2 och om man vill få C eller högre så måste man kommentera koden(Gäller kanske inte överallt men i alla fall på min gymnasieskola).