Permalänk
Medlem

Programmering 1 C# uppgift

Hej allihop,

Jag håller på att plugga programmering 1 och har fått en uppgift som många kanske känner till "Amerikanen i bastun".
Mitt mål med denna uppgift är få betyg C.
Länk till uppgiften: https://www.docdroid.net/33sbaWy/amerikanen-i-bastun.pdf

Jag har lyckats programmera basdelen av programmet och det funkar till en viss del. När man skriver in 164 till 172 får man ingen text.
163 neråt och 173 uppåt funkar utmärkt. Vad kan jag ha gjort för fel?

Har sökt lite i forumet om man kan använda Try and Catch med if-sats men hittade ingen bra tråd. Om det finns så har jag säkert missat det.

Meningen med denna tråd är att ni inte ska göra uppgiften åt mig. Jag vill att ni ska komma med idéer eller ledtråd hur jag kan lösa uppgiften på egen hand.

EDIT:
Lade till ny länk till uppgiften så att man kan se pdf filen online istället för att ladda ner.

public static double FahrToCel(int fahr) { int cel = (fahr - 32) * 5 / 9; return cel; } public static void Main(string[] args) { Console.WriteLine("Skriv in Fahrenheit: "); int fh = int.Parse(Console.ReadLine()); //Användaren skriver in ett värde som lagras i fahrenheit double ce = FahrToCel(fh); // I celsius finns nu antal grader omvandlat från fahrenheit till celsius. int lag = 73; int hog = 77; do { if (ce < lag) { Console.WriteLine("Du kan ej basta än. Värme {0}, höj värmen", ce); } else if (ce > hog) { Console.WriteLine("För varmt. Värme {0}, sänk värmen", ce); } Console.WriteLine("Skriv in Fahrenheit: "); fh = int.Parse(Console.ReadLine()); ce = FahrToCel(fh); } while (ce < lag || ce > hog); Console.WriteLine("Nu kan du basta. Värme {0}", ce); Console.Write("Press any key to continue . . . "); Console.ReadKey(true); }

Permalänk
Hedersmedlem

Du har ett fel i flödet i ditt program. Om du skriver in 170 två gånger på raden så bör det hända något. Varför blir det så?

Ett generellt tips kan vara att göra ett flöde på hur man vill att programmet ska funka och sedan skriva det i kod. Då kan du kanske se hur du kan bli av med dupliceringen av koden som frågar användaren om temperatur.

Jag vet inte exakt vad du menar med try-catch med if-sats. Men du kan lägga in en kontroll av vilket fel som skickas i din catch för att göra olika saker beroende på fel. Du kan också lägga flera try-catch i en metod, i princip en per kommando om du vill det, för att få ännu mer kontroll. I detta fallet när du inte förstår vad din kod faktiskt gör så är det nog bättre att stega koden i debuggern och kolla vilka värden som sätts och vilken väg exekveringen tar i din kod.

Visa signatur

Använd gilla för att markera nyttiga inlägg!

Permalänk
99:e percentilen

Bra att du skrivit själva omvandlingen som en ren funktion! Fortsätt programmera på det sättet.

Det går till och med att skriva den funktionen ännu lite bättre:

public static double FahrToCel(int fahr) { return (fahr - 32) * 5 / 9; }

Visa signatur

Skrivet med hjälp av Better SweClockers

Permalänk
Medlem

@Gunel: I dina ifsatser har kollar du > och <
Du hanterar inte om det är lika med. Alltså skriver du 164 så är det lika med "lag" och dina if-satser kollar bara om de är lägre än eller större än. Prova sätt >= och <= istället.

Visa signatur

Ryzen 1700 @3,8Ghz 1,342V | Corsair Vengeance LPX 2x8Gb (CMK16GX4M2B3000C15) | Asus Prime x370 Pro | KFA2 GTX 1080 Ti

Permalänk
Medlem
Skrivet av giplet:

Du har ett fel i flödet i ditt program. Om du skriver in 170 två gånger på raden så bör det hända något. Varför blir det så?

Ett generellt tips kan vara att göra ett flöde på hur man vill att programmet ska funka och sedan skriva det i kod. Då kan du kanske se hur du kan bli av med dupliceringen av koden som frågar användaren om temperatur.

Jag vet inte exakt vad du menar med try-catch med if-sats. Men du kan lägga in en kontroll av vilket fel som skickas i din catch för att göra olika saker beroende på fel. Du kan också lägga flera try-catch i en metod, i princip en per kommando om du vill det, för att få ännu mer kontroll. I detta fallet när du inte förstår vad din kod faktiskt gör så är det nog bättre att stega koden i debuggern och kolla vilka värden som sätts och vilken väg exekveringen tar i din kod.

Första gången när jag skriver 170 får jag blankt, andra gången när jag skriver får jag fram rätt text "Nu kan du basta. Värme 76".
Har kollat igenom koden ett par gånger. Vet inte riktigt varför det blir så.

Du menar alltså att jag skulle behöva skapa aktivitets/sekvensdiagram

Try and Catch med if-sats menar jag att när jag försöker använda koden nedan innan Do loopen börjar får denna felmeddelandet: Namnet ce finns inte i den aktuella kontexten (CS0103)

Console.WriteLine("Skriv in Fahrenheit: "); int lag = 73; int hog = 77; try { int fh = int.Parse(Console.ReadLine()); //Användaren skriver in ett värde som lagras i fahrenheit double ce = FahrToCel(fh); // I celsius finns nu antal grader omvandlat från fahrenheit till celsius. } catch (Exception) { Console.WriteLine("Du kan endast skriva heltal"); }

Skrivet av Alling:

Bra att du skrivit själva omvandlingen som en ren funktion! Fortsätt programmera på det sättet.

Det går till och med att skriva den funktionen ännu lite bättre:

public static double FahrToCel(int fahr) { return (fahr - 32) * 5 / 9; }

Omvandlingen är redan skrivet av läraren.

Skrivet av Tony32:

@Gunel: I dina ifsatser har kollar du > och <
Du hanterar inte om det är lika med. Alltså skriver du 164 så är det lika med "lag" och dina if-satser kollar bara om de är lägre än eller större än. Prova sätt >= och <= istället.

När skriver in 165F(73C) får man meddelandet att "Du kan ej basta än" men egentligen ska man få meddelandet "Nu kan du basta" eftersom värmen stämmer bra med lag variabeln.

Permalänk
Medlem

Nu är jag inte så bekant i C# men din while sats om jag fattat rätt så är din inparameter II en OR operand. Men om jag förstått det rätt för frågan så vill du att while satsen ska hålla sig till om temperaturen ligger mellan 73-77.

Dock att använda en OR operand så kanske det ger ett problem om båda argumenten är sanna. I och med att det är en OR operand så borde detta inte vara problem men mitt tips skulle vara att göra en till if sats med 2 argument som begränsar temperaturen så att ifall den är mindre än 77 och större än 73 så kan du mata ut den kod du vill ha.

Permalänk
Medlem

@Gunel: Detta är ett utmärkt tillfälle att använda debuggern och stega igenom programmet, då kommer du lätt kunna se varför det blir som det blir. Här är en kort introduktion till hur man använder debuggern.

@Teicaus: Villkoret i while-loopen är korrekt, den ska loopa så länge som temperaturen ligger utanför de uppsatta gränserna vilket den också gör.

Permalänk

Problemet ligger i att nedanstående rader alltid genomlöps i do while slingan oavsett inmatad temperatur. De ska bara genomlöpas om temperaturen är för hög eller för låg.

Console.WriteLine("Skriv in Fahrenheit: ");
fh = int.Parse(Console.ReadLine());
ce = FahrToCel(fh);

Visa signatur

/GannTrader

Permalänk
Hedersmedlem
Skrivet av Gunel:

Första gången när jag skriver 170 får jag blankt, andra gången när jag skriver får jag fram rätt text "Nu kan du basta. Värme 76".
Har kollat igenom koden ett par gånger. Vet inte riktigt varför det blir så.

Om du använder dubuggern och stegar dig igenom koden så kommer du att se precis varför det blir så här.

Skrivet av GannTrader:

Problemet ligger i att nedanstående rader alltid genomlöps i do while slingan oavsett inmatad temperatur. De ska bara genomlöpas om temperaturen är för hög eller för låg.

Console.WriteLine("Skriv in Fahrenheit: ");
fh = int.Parse(Console.ReadLine());
ce = FahrToCel(fh);

Du har rätt, men din lösning skulle skapa ett i mina ögon rörigt program. Det finns en sekvens som ska återupprepas tills dess att "rätt" svar ges. Den sekvensen inleds alltid med att läsa en temperatur. Men så ser inte programmet ut i nuläget.

Visa signatur

Använd gilla för att markera nyttiga inlägg!

Permalänk
Skrivet av giplet:

Du har rätt, men din lösning skulle skapa ett i mina ögon rörigt program. Det finns en sekvens som ska återupprepas tills dess att "rätt" svar ges. Den sekvensen inleds alltid med att läsa en temperatur. Men så ser inte programmet ut i nuläget.

Det ser jag allt. Jag bara påpekade vad som är fel i denna kod.

Visa signatur

/GannTrader

Permalänk
Medlem

Tack för all svar och hjälp.

Kommer sitta i veckan med koden och se om jag lösa problemet.
Återkommer hur det har gått

Permalänk
Medlem

Hej,

Här kommer uppdaterad kod på min programmering. Nu har jag fått det att fungera.
Hur ser det ut nu?

public static int FahrToCel(int fahr) { int cel = (fahr - 32) * 5 / 9; return cel; } public static void Main(string[] args) { Console.WriteLine("Skriv in Fahrenheit: "); int fahrenheit = int.Parse(Console.ReadLine()); //Användaren skriver in ett värde som lagras i fahrenheit int celsius = FahrToCel(fahrenheit); /* I celsius finns nu antal grader omvandlat från fahrenheit till celsius. */ int lowerTempLimit = 73; int upperTempLimit = 77; do { if (celsius < lowerTempLimit) { Console.WriteLine("Bastun är inte tillräckligt varmt. Värme i bastun {0}, skruva upp värmen", celsius); } else if (celsius > upperTempLimit) { Console.WriteLine("Bastun är för varmt. Värme i bastun {0}, skruva ner värmen", celsius); } else { Console.WriteLine("Bastun är tillräckligt varmt för att kunna basta. Värme i bastun {0}", celsius); } break; } while (celsius <= lowerTempLimit || celsius >= upperTempLimit); Console.Write("Press any key to continue . . . "); Console.ReadKey(); }

Permalänk

Nja detta lär väl inte fungera som tänkt.
Det kommer att skriva ut om temperaturen är hög/låg eller lagom men du får inte mata in en ny temperatur om den inmatade tempen är för hög eller för låg.
Dessutom tycker jag att det är dålig programmering att avbryta en slinga med break.

Visa signatur

/GannTrader

Permalänk
Medlem
Skrivet av GannTrader:

Nja detta lär väl inte fungera som tänkt.
Det kommer att skriva ut om temperaturen är hög/låg eller lagom men du får inte mata in en ny temperatur om den inmatade tempen är för hög eller för låg.
Dessutom tycker jag att det är dålig programmering att avbryta en slinga med break.

Om jag kör koden så?
Om jag vill använda Try-Catch. Vart är det lämpligast ha koden?

do { if (celsius < lowerTempLimit) { Console.WriteLine("Bastun är inte tillräckligt varmt. Värme i bastun {0}, skruva upp värmen", celsius); } else if (celsius > upperTempLimit) { Console.WriteLine("Bastun är för varmt. Värme i bastun {0}, skruva ner värmen", celsius); } else { Console.WriteLine("Bastun är tillräckligt varmt för att kunna basta. Värme i bastun {0}", celsius); } Console.WriteLine("\nSkriv in Fahrenheit: "); fahrenheit = int.Parse(Console.ReadLine()); celsius = FahrToCel(fahrenheit); } while (celsius <= lowerTempLimit || celsius >= upperTempLimit);

Permalänk
Vila i frid

Det största problemet är inte programmeringen utan det att man inte har funderat på vad det är man vill lösa. Kan man inte beskriva vad som skall uppnås är det räligt svårt att programmera en lösning.

Mitt första hack var till en trevåningshiss maskinkodat för en Motorola 6800 år -78. Utan flödesschema var det omöjligt att åstadkomma något inom rimlig tid.

Permalänk
Skrivet av GannTrader:

Dessutom tycker jag att det är dålig programmering att avbryta en slinga med break.

I just det här fallet är ju inte användningen av break helt ideal, men finessen med break och continue är ju just att man kan bryta kontrollflödet på ett kontrollerat sätt. Korrekt använt tycker jag att det blir mycket tydligare om man hanterar särfallen med break eller continue istället för att stoppa in en massa villkorsvariabler som skall styra huruvida resten av loopen skall köras och om man skall köra ett varv till.

Om man inte får avsluta sin loop med break, får man göra return inne i loopen? Om svaret är ja på den frågan, vad skiljer då return och break? Båda bryter kontrollflödet i loopen.

Permalänk
Skrivet av Ingetledigtnamn:

I just det här fallet är ju inte användningen av break helt ideal, men finessen med break och continue är ju just att man kan bryta kontrollflödet på ett kontrollerat sätt. Korrekt använt tycker jag att det blir mycket tydligare om man hanterar särfallen med break eller continue istället för att stoppa in en massa villkorsvariabler som skall styra huruvida resten av loopen skall köras och om man skall köra ett varv till.

Om man inte får avsluta sin loop med break, får man göra return inne i loopen? Om svaret är ja på den frågan, vad skiljer då return och break? Båda bryter kontrollflödet i loopen.

Det finns ju undantag som bekräftar regeln givetvis men alltför ofta missbrukas break när man kunnat lösa det på ett snyggare sätt utan break. Därmed inte sagt att man inte ska använda break men i detta fall behövs det inte.

Visa signatur

/GannTrader

Permalänk
Medlem
Skrivet av Gunel:

Om jag kör koden så?
Om jag vill använda Try-Catch. Vart är det lämpligast ha koden?

Try-Catch behöver du använda när något kan gå åt helvete. Vad skulle hända om jag matade in "hej" t.ex?

Permalänk
Medlem

Hej igen allihop,

Nu har jag lyckats få programmet köra som jag vill.
Vad tycker ni? Har jag kodat rätt nu?

public static int FahrToCel(int fahr) { int cel = (fahr - 32) * 5 / 9; return cel; } public static void Main(string[] args) { int startTempLimit = 0; int lowerTempLimit = 73; int upperTempLimit = 77; int celsius; int fahrenheit; do { Console.WriteLine("Skriv in Fahrenheit grader: "); fahrenheit = int.Parse(Console.ReadLine()); //Användaren skriver in ett värde som lagras i fahrenheit celsius = FahrToCel(fahrenheit); // I celsius finns nu antal grader omvandlat från fahrenheit till celsius. if (celsius < startTempLimit) { Console.WriteLine ("Bastun är ej påslagen. Du måste sätta på bastun. Värme i bastu {0}C.", celsius); } else if (celsius < lowerTempLimit) { Console.WriteLine("Bastun är inte tillräckligt varm. Värme i bastun {0}C, skruva upp värmen", celsius); } else if (celsius > upperTempLimit) { Console.WriteLine("Bastun är för varm. Värme i bastun {0}C, skruva ner värmen", celsius); } else { Console.WriteLine("Bastun är tillräckligt varm för att kunna basta. Värme i bastun {0}C.", celsius); } } while (celsius <= lowerTempLimit || celsius >= upperTempLimit);

Permalänk
Medlem

Programmet ser bra och välstrukturerat ut men du har inte med någon undantagshantering, matar användaren in något annat än ett tal så kommer programmet krascha.

Visa signatur

flippy @ Quakenet

Permalänk
Medlem

@Gunel: Vad händer om man matar in t.ex. 164?

Permalänk
Medlem
Skrivet av ante84:

Programmet ser bra och välstrukturerat ut men du har inte med någon undantagshantering, matar användaren in något annat än ett tal så kommer programmet krascha.

Det vet jag inte hur jag ska lösa. Har provat ett par metoder men har inte lyckats få det synkad med koden.

Skrivet av perost:

@Gunel: Vad händer om man matar in t.ex. 164?

Får texten:
"Bastun är inte tillräckligt varm. Värme i bastun 73C, skruva upp värmen"
Och det är inom de ramen som är lämpligt att basta men säger att det är inte det.

Permalänk
Medlem
Skrivet av Gunel:

Får texten:
"Bastun är inte tillräckligt varm. Värme i bastun 73C, skruva upp värmen"
Och det är inom de ramen som är lämpligt att basta men säger att det är inte det.

Är du helt säker på det? Då är någonting riktigt fel, för villkoret celsius < lowerTempLimit kan ju omöjligtvis vara sant om både celsius och lowerTempLimit är 73. Vad jag egentligen syftade på var att du har olika villkor i if-satsen och while-loopen, så om man skriver in t.ex. 164 så borde den säga att bastun är lagomt varm men ändå be användaren mata in en ny temperatur.

Permalänk
Medlem
Skrivet av perost:

Är du helt säker på det? Då är någonting riktigt fel, för villkoret celsius < lowerTempLimit kan ju omöjligtvis vara sant om både celsius och lowerTempLimit är 73. Vad jag egentligen syftade på var att du har olika villkor i if-satsen och while-loopen, så om man skriver in t.ex. 164 så borde den säga att bastun är lagomt varm men ändå be användaren mata in en ny temperatur.

Jag hade faktiskt glömt att spara kodningen så <= och >= var kvar men det ska vara celsius < lowerTempLimit och celsius > upperTempLimit.

Jag får rätt text när jag skriver 164. Jag tror du syftade på att den frågar om Fahrenheit grader igen.

Permalänk
Medlem
Skrivet av Gunel:

Jag får rätt text när jag skriver 164. Jag tror du syftade på att den frågar om Fahrenheit grader igen.

Ja, precis.

Permalänk
Medlem
Skrivet av perost:

Vad jag egentligen syftade på var att du har olika villkor i if-satsen och while-loopen, så om man skriver in t.ex. 164 så borde den säga att bastun är lagomt varm men ändå be användaren mata in en ny temperatur.

Hur kan jag lösa det?

Permalänk
Medlem
Skrivet av Gunel:

Hur kan jag lösa det?

Problemet är som sagt att if-satsen tycker att t.ex. 164 är en lagom temperatur, men while-loopen tycker att den är för låg och börjar om ändå. Lösningen är att använda samma gränser i båda fallen.

Permalänk
Medlem
Skrivet av perost:

Problemet är som sagt att if-satsen tycker att t.ex. 164 är en lagom temperatur, men while-loopen tycker att den är för låg och börjar om ändå. Lösningen är att använda samma gränser i båda fallen.

Tack så hemsk mycket för hjälpen!

Permalänk
Medlem

Nu har jag äntligen fått igång.

På vilket viss kan man använda Try-Catch?

När jag försöker ha Try-Catch både i och utanför loppen får jag denna felmeddelande. Denna vet jag verkligen inte hur jag ska lösa.
En lokal variabel som inte har tilldelats används: celsius (CS0165)

do { try { Console.WriteLine("Skriv in Fahrenheit grader: "); fahrenheit = int.Parse(Console.ReadLine()); //Användaren skriver in ett värde som lagras i fahrenheit celsius = FahrToCel(fahrenheit); /* I celsius finns nu antal grader omvandlat * från fahrenheit till celsius. */ } catch { Console.WriteLine ("Du skrev inget gilltigt fahrenheit grader"); } if (celsius < startTempLimit) { Console.WriteLine ("Bastun är ej påslagen. Du måste sätta på bastun. Värme i bastu {0}C.", celsius); } else if (celsius < lowerTempLimit) { Console.WriteLine("Bastun är inte tillräckligt varm. Värme i bastun {0}C, skruva upp värmen", celsius); } else if (celsius > upperTempLimit) { Console.WriteLine("Bastun är för varm. Värme i bastun {0}C, skruva ner värmen", celsius); } else { Console.WriteLine("Bastun är tillräckligt varm för att kunna basta. Värme i bastun {0}C.", celsius); } }

Permalänk
Medlem

@Gunel: Felmeddelandet beror på att du utanför do (och try) satsen har deklarerat variabeln "celcius" utan att ge den ett värde och användaren har därefter skrivit in ett värde som inte är numeriskt vilket inte stöds av FahrToCel(). Du fångar detta exception i catch men går därefter in i ett nytt block där du försöker jämföra en ännu inte initialiserad variabel (kom ihåg, din funktion misslyckades) med något annat.

Visa signatur

Skoj: Ryzen 9 5900x, RTX 3080, 32 GB RAM @3200MHz CL16
Jobb: Alienware M15 R6, RTX 3080, 32 GB RAM
Privat: Macbook Pro 13" late 2016