Permalänk
Medlem

C# Bastun

Tjena alla som läser,

Jag har stött på problem med min kod som jag skrivit.

Problem 1: När jag skriver in te.x. 165 grader Fahrenheit får jag ut texten att det inte är varmt nog men jag vill få ut t.ex. "minst godtagbara temperaturen är uppnådd och aktuell temp är {0} osv osv.

Problem 2: och när jag skriver in 168-170 så får jag ingen output..

Vad är det som är galet, känns som att jag bara rör runt det i koden, ändrar jag en sak så är det något annat som inte fungerar.
Btw. det är inte riktigt finslipat eller strukturerad ännu!

Tacksam för all tips o hjälp!

using System; namespace Uppdrag2_Amerikanen { class Program { /* * == (lika med) * < (Mindre än) * > (större än) * <= (Mindre än eller lika med) * >= (Mer än eller lika med) * != (Inte lika med) */ static int FahrToCels(int fahr) { int cel = (fahr - 32) * 5 / 9; return cel; } static void Main(string[] args) { int tempstart = 0; int templow = 73; int tempup = 77; int celsius; int fahrenheit; Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Amerikanen i Bastun\n"); Console.ForegroundColor = ConsoleColor.White; do { Console.Write("Skriv in Fahrenheit grader!: "); while (true) { try { fahrenheit = int.Parse(Console.ReadLine()); break; } catch (Exception) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[Fel, skriv endast heltal!]"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("\nSkriv in Fahrenheit grader: "); } } celsius = FahrToCels(fahrenheit); if (celsius < tempstart) { Console.WriteLine("Bastun är ej igång, du måste slå på bastun! Aktuell värme i bastun {0}°C.\n", celsius); } else if (celsius <= templow) { Console.WriteLine("Bastun är inte varm nog, öka värmen! Aktuell värme i bastun {0}°C.\n", celsius); } else if (celsius == templow) { Console.WriteLine("\nBastun är minst godtagbar för att kunna njuta. Värmen i bastun är {0}°C.", celsius); Console.WriteLine("Du kan ange högre fahrenheit för skönare bastu!"); } else if (celsius > tempup) { Console.WriteLine("Bastun är för varm, Värmen i bastun är {0}°C, dra ner värmen!\n", celsius); } continue; } while (celsius != tempup); { Console.WriteLine("Den maximala temperaturen för ren avnjutning är uppnådd, temperaturen i bastun är {0}°C", celsius); Console.WriteLine("\n[Avsluta genom att trycka valfri tangent. . .]"); } Console.ReadLine(); } } }

gjort den användbar
Permalänk
Hedersmedlem

Hej! Det är bra om du redigerar din kod så att den åtminstone kompilerar om vi ska mecka med den!

Permalänk
Medlem
Skrivet av pv2b:

Hej! Det är bra om du redigerar din kod så att den åtminstone kompilerar om vi ska mecka med den!

Hur menar du nu?

Permalänk
Medlem

Rekommenderar dig att lägga in lite console.write efter varje steg och se vart det går fel, hur ser din input ut, hur ser det ut efter att du gjort beräkningen etc så får du en klarat bild av vad som sker 😊

Skickades från m.sweclockers.com

Visa signatur

"One is always considered mad, when one discovers something that others cannot grasp."
- Ed Wood

Permalänk
Medlem

@Dritonkb:

Problem1:
Har du kollat vad din celcius int faktist blir? Ta en titt och sedan kollar du else if (celsius <= templow) igen

Problem2:
Ett tag sedan jag höll på med console.readline men du gör ett matematiskt värde 168-168? Sätt en breakpoint i FahrToCels() och se vad du får för inparameter.

Visa signatur

Gaming: MSI X570 MPG Gaming Plus -- AMD Ryzen 9 5900X -- Sapphire Radeon RX 6800 XT NITRO+ -- G.Skill 32GB 3600MHz CL14 -- Samsung 960 EVO 1TB -- 2x ASUS MG278Q -- Arch-based EndeavourOS
VR: ASRock B550M-ITX/ac -- AMD Ryzen 5 5600G -- ASUS RTX 3070 -- Corsair 16GB 3600MHz CL18 -- Kingston A2000 250GB -- Windows 10

Permalänk
Hedersmedlem
Skrivet av Dritonkb:

Hur menar du nu?

Jag menar att om jag klipper in koden in i typ Visual Studio som ser det ut just nu så funkar den inte alls, saknas bl.a. "public" på main-metoden, saknas måsvingar på slutet, saknas klassdefinition i början, saknas "using"-satser, etc.

Klipp in hela filen som du jobbar med.

Permalänk
Medlem
Skrivet av pv2b:

Jag menar att om jag klipper in koden in i typ Visual Studio som ser det ut just nu så funkar den inte alls, saknas bl.a. "public" på main-metoden, saknas måsvingar på slutet, saknas klassdefinition i början, saknas "using"-satser, etc.

Klipp in hela filen som du jobbar med.

ah nu har jag redigerat inlägget

Permalänk
Hedersmedlem
Skrivet av Dritonkb:

Problem 1: När jag skriver in te.x. 165 grader Fahrenheit får jag ut texten att det inte är varmt nog men jag vill få ut t.ex. "minst godtagbara temperaturen är uppnådd och aktuell temp är {0} osv osv.

Kolla dina villkor. Tänk på att i en if-elseif-else-konstruktion så testar den villkoren ett och ett, och hoppar in i det FÖRSTA villkoret som stämmer.

I ditt fall om, du skriver in 165 grader Fahrenheit (typ 73 grader Celsius) så blir Celsius till 73. Då går ditt program igenom dina villkor, och den kommer matcha på if (celsius <= templow) eftersom celsius=73 och templow=73

<= betyder "mindre eller lika med"

Du kanske ska ha < istället?

Skrivet av Dritonkb:

Problem 2: och när jag skriver in 168-168 så får jag ingen output..

Samma grej där, du har ju inget villkor i din if-elseif-else som matchar detta fall.

Permalänk
Medlem

1: kolla på funktionen som omvandlar till Celsius, iom att du arbetar med heltal (int) så kommer du tappa precision. Prova att logga ut vad dina variabler faktiskt innehåller så kommer du se vad som blir fel.

2: det finns inget intervall som hanterar temperaturer mellan templow och tempup

Visa signatur

| Ryzen 5800x | Asus prime x470 pro | Asus rtx 3080 tuf oc | Gskill 32gb 3,6ghz | aw3225qf |

Permalänk
Medlem
Skrivet av Kokefa:

@Dritonkb:

Problem1:
Har du kollat vad din celcius int faktist blir? Ta en titt och sedan kollar du else if (celsius <= templow) igen

Problem2:
Ett tag sedan jag höll på med console.readline men du gör ett matematiskt värde 168-168? Sätt en breakpoint i FahrToCels() och se vad du får för inparameter.

Sorry det skulle vara 168 - (till) 170, alltså om jag skriver in såhär nedan så får jag ingen output:

Skriv in Fahrenheit grader!: 165

Bastun är minst godtagbar för att kunna njuta. Värmen i bastun är 73°C.
Du kan ange högre Fahrenheit för skönare bastu!
Skriv in Fahrenheit grader!: 168
Skriv in Fahrenheit grader!: 169
Skriv in Fahrenheit grader!: 167
Skriv in Fahrenheit grader!: 168
Skriv in Fahrenheit grader!: 169
Skriv in Fahrenheit grader!: 170
Skriv in Fahrenheit grader!: 171
Den maximala temperaturen för ren njutning är uppnådd, temperaturen i bastun är 77°C

Permalänk
Medlem

Tack alla som kom med tips!
Jag tror jag har löst problemen nu, är det någon som vill ge input på vad de tycker?

using System; namespace Uppdrag2_Amerikanen { class Program { /* * == (lika med) * < (Mindre än) * > (större än) * <= (Mindre än eller lika med) * >= (Mer än eller lika med) * != (Inte lika med) */ static int FahrToCels(int fahr) { int cel = (fahr - 32) * 5 / 9; return cel; } static void Main(string[] args) { int tempstart = 0; int templow = 73; int tempup = 77; int celsius; int fahrenheit; Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Amerikanen i Bastun\n"); Console.ForegroundColor = ConsoleColor.White; do { Console.Write("Skriv in Fahrenheit grader!: "); while (true) { try { fahrenheit = int.Parse(Console.ReadLine()); break; } catch (Exception) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[Fel, skriv endast heltal!]"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("\nSkriv in Fahrenheit grader: "); } } celsius = FahrToCels(fahrenheit); if (celsius < tempstart) { Console.WriteLine("Bastun är ej igång, du måste slå på bastun! Aktuell värme i bastun {0}°C.\n", celsius); } else if (celsius < templow) { Console.WriteLine("Bastun är inte varm nog, öka värmen! Aktuell värme i bastun {0}°C.\n", celsius); } else if (celsius <= templow) { Console.WriteLine("Nu är bastun varm nog för dig att gå in, aktuell temperatur i bastun är {0}°C.\n", celsius); } else if (tempup > celsius) { Console.WriteLine("Ange högre fahrenheit för skönare bastu! Aktuell temperatur i bastun är {0}°C.\n", celsius); } else if (celsius > tempup) { Console.WriteLine("Temperaturen är för hög, aktuell temp i bastun är {0}°C", celsius); } continue; } while (celsius != tempup); { Console.WriteLine("Den maximala temperaturen för ren avnjutning är uppnådd, temperaturen i bastun är {0}°C", celsius); Console.WriteLine("\n[Avsluta genom att trycka valfri tangent. . .]"); Console.ReadKey(true); } } } }

Permalänk
Medlem

@Dritonkb: Jag rekommenderar att du lär dig använda debuggern, så att du kan stega igenom programmet rad för rad medan det körs och se vad som händer. Här finns en kort guide för hur man gör, det räcker att du läser de tre första sektionerna för att lära dig grunderna.

En liten snabb kommentar på denna kod:

do { Console.Write("Skriv in Fahrenheit grader!: "); ... continue; } while (celsius != tempup); { Console.WriteLine("Den maximala temperaturen för ren avnjutning är uppnådd, temperaturen i bastun är {0}°C", celsius); Console.WriteLine("\n[Avsluta genom att trycka valfri tangent. . .]"); Console.ReadKey(true); }

För det första fyller continue; i slutet av do-while-loopen ingen funktion, det orsakar bara ett hopp till slutet av loopen vilket ändå är vad som sker utan continue.

För det andra så är måsvingarna runt de tre sista raderna väldigt missvisande, tillsammans med indenteringen får de det att se ut som att det är en while-loop i slutet när de tre sista raderna i själva verket är helt fristående. Att du satt måsvingar runt dem är tillåtet, det definierar bara ett nytt block, men rent formateringsmässigt är det väldigt fel här.

Permalänk
Medlem

Vill bara lägga till ett kort tips för snyggare kod.

static int FahrToCels(int fahr) { return (fahr - 32) * 5 / 9; }

Du behöver inte deklarera en variabel om du bara ska använda den en gång.

Sen kan du kolla på att använda decimaltal, exempelvis double istället för int.

Men det ingår nog inte i uppgiften.

Sen skulle nog jag kolla på att använda ett switch-case istället för massa if-else.

Lycka till!

Visa signatur

Stationär: Core i9 13900k | Asus X790 ROG Strix Gaming-F | 32GB DDR5 | RX 7900 XT | Lian Li PC-O11 dynamic evo
Laptop: Macbook Air | Apple M1

Permalänk
Medlem
Skrivet av MaxieTheHatter:

Vill bara lägga till ett kort tips för snyggare kod.

static int FahrToCels(int fahr) { return (fahr - 32) * 5 / 9; }

Du behöver inte deklarera en variabel om du bara ska använda den en gång.

Sen kan du kolla på att använda decimaltal, exempelvis double istället för int.

Men det ingår nog inte i uppgiften.

Sen skulle nog jag kolla på att använda ett switch-case istället för massa if-else.

Lycka till!

Tack för tipsen!
Uppgiften vill att jag ska använda if-satser..

Och de med double, bytar jag ut alla int till double? för när jag gör det och matar in tex 165 F så får jag som output:

Citat:

Skriv in Fahrenheit grader!: 165
Ange högre fahrenheit för skönare bastu! Aktuell temperatur i bastun är 73,8888888888889°C.

Permalänk
Medlem
Skrivet av perost:

@Dritonkb: Jag rekommenderar att du lär dig använda debuggern, så att du kan stega igenom programmet rad för rad medan det körs och se vad som händer. Här finns en kort guide för hur man gör, det räcker att du läser de tre första sektionerna för att lära dig grunderna.

En liten snabb kommentar på denna kod:

do { Console.Write("Skriv in Fahrenheit grader!: "); ... continue; } while (celsius != tempup); { Console.WriteLine("Den maximala temperaturen för ren avnjutning är uppnådd, temperaturen i bastun är {0}°C", celsius); Console.WriteLine("\n[Avsluta genom att trycka valfri tangent. . .]"); Console.ReadKey(true); }

För det första fyller continue; i slutet av do-while-loopen ingen funktion, det orsakar bara ett hopp till slutet av loopen vilket ändå är vad som sker utan continue.

För det andra så är måsvingarna runt de tre sista raderna väldigt missvisande, tillsammans med indenteringen får de det att se ut som att det är en while-loop i slutet när de tre sista raderna i själva verket är helt fristående. Att du satt måsvingar runt dem är tillåtet, det definierar bara ett nytt block, men rent formateringsmässigt är det väldigt fel här.

Måsvingarna är borta med vinden nu, tack!
och debugg ska jag gräva mig mer in på!

Permalänk
Medlem
Skrivet av Dritonkb:

Tack för tipsen!
Uppgiften vill att jag ska använda if-satser..

Och de med double, bytar jag ut alla int till double? för när jag gör det och matar in tex 165 F så får jag som output:

Här finns det lite olika lösningar för att få det snyggt

Du kan t.ex runda av till ett visst antal decimaler

Math.Round(temp, antalDecimaler);

eller runda av till närmaste heltal (uppåt)

Math.Round(temp, MidpointRounding.AwayFromZero)); // 1.4 -> 1 // 1.5 -> 2 // 1.6 -> 2 etc.

Visa signatur

| EVGA Z170 FTW | i7 6700k | ASUS RTX 3070 | 16GB DDR4 3200MHz | Cooler Master V850 | Samsung 840 Evo 250GB + 2x WD Black 500GB + Seagate 2TB SSHD + Samsung 970 Evo M.2 500GB |

Permalänk
Medlem
Skrivet av BrutalSwede:

Här finns det lite olika lösningar för att få det snyggt

Du kan t.ex runda av till ett visst antal decimaler

Math.Round(temp, antalDecimaler);

eller runda av till närmaste heltal (uppåt)

Math.Round(temp, MidpointRounding.AwayFromZero)); // 1.4 -> 1 // 1.5 -> 2 // 1.6 -> 2 etc.

Tack för tipsen! min hjärna är slut, vet ej vart jag ska få in dem, har provat olika metoder men ej lyckats..

using System; namespace Uppdrag2_AmerikanenBetygC { class Program { public static double FahrToCels(double fahr) { double cels = (fahr - 32) * 5 / 9; return cels; } static void Main(string[] args) { double fahrenheit = 0; double celcius = FahrToCels(fahrenheit); do { Console.WriteLine("Skriv in fahrenheit grader!:"); while (true) { try { fahrenheit = double.Parse(Console.ReadLine()); break; } catch { Console.WriteLine("Fel inmatning!"); } } celcius = FahrToCels(Math.Round(fahrenheit)); Math.Round(fahrenheit, MidpointRounding.AwayFromZero); if (celcius < 30) { Console.WriteLine("Bastun är iskall! Aktuell temperatur i bastun är {0}c", celcius); Console.ReadLine(); } else if (celcius > 30) { Console.WriteLine("aktuell temp {0}C", celcius); } } while (celcius != 77); Console.WriteLine("Den maximala temperaturen för ren njutning är uppnådd, temperaturen i bastun är {0}°C. Glöm ej att dricka vatten!", celcius); Console.WriteLine("\n\n[Avsluta genom att trycka valfri tangent. . .]"); Console.ReadKey(true); } } }

Permalänk
Medlem

@Dritonkb: Nu har du bara ändrat till double överallt, och anropet till Math.Round efter konverteringen har ingen effekt eftersom du inte sparar resultatet någonstans. D.v.s.

Math.Round(variabel);

kommer inte ändra på variabel, utan returnerar ett nytt värde som är avrundat. Math.Round returnerar dessutom ett flyttal, så man måste fortfarande konvertera till t.ex. int om man vill använda heltal. T.ex.:

double d = 4.73; int i = (int)Math.Round(d); // Math.Round returnerar 5.0, som sen konverteras till 5.

Man kan även konvertera till int rakt av utan att använda Math.Round, då kapas bara decimalerna så att t.ex. 4.73 skulle bli 4.

Men problemet som din ursprungliga kod hade var att du utförde heltalsoperationer i FahrToCels, d.v.s. (fahr - 32) * 5 / 9. Eftersom t.ex. heltalsdivision i C# innebär att eventuella decimaler bara slängs bort så kan detta bli ett problem när man utför flera operationer där varje operation tappar precision. 37°F skulle t.ex. resultera i 2°C, istället för 3°C som man skulle kunna förvänta sig.

Den enklaste lösningen utan att ändra allt för mycket i din kod hade varit att bara utföra själva beräkningen med flyttal, och sen konvertera till en int när du returnerar värdet. Det räcker i själva verket att bara ändra 9 till 9.0 i beräkningen för att utföra flyttalsdivision istället, eftersom heltal / flyttal automatiskt konverteras till flyttal / flyttal.

Permalänk
Medlem
Skrivet av perost:

@Dritonkb: Nu har du bara ändrat till double överallt, och anropet till Math.Round efter konverteringen har ingen effekt eftersom du inte sparar resultatet någonstans. D.v.s.

Math.Round(variabel);

kommer inte ändra på variabel, utan returnerar ett nytt värde som är avrundat. Math.Round returnerar dessutom ett flyttal, så man måste fortfarande konvertera till t.ex. int om man vill använda heltal. T.ex.:

double d = 4.73; int i = (int)Math.Round(d); // Math.Round returnerar 5.0, som sen konverteras till 5.

Man kan även konvertera till int rakt av utan att använda Math.Round, då kapas bara decimalerna så att t.ex. 4.73 skulle bli 4.

Men problemet som din ursprungliga kod hade var att du utförde heltalsoperationer i FahrToCels, d.v.s. (fahr - 32) * 5 / 9. Eftersom t.ex. heltalsdivision i C# innebär att eventuella decimaler bara slängs bort så kan detta bli ett problem när man utför flera operationer där varje operation tappar precision. 37°F skulle t.ex. resultera i 2°C, istället för 3°C som man skulle kunna förvänta sig.

Den enklaste lösningen utan att ändra allt för mycket i din kod hade varit att bara utföra själva beräkningen med flyttal, och sen konvertera till en int när du returnerar värdet. Det räcker i själva verket att bara ändra 9 till 9.0 i beräkningen för att utföra flyttalsdivision istället, eftersom heltal / flyttal automatiskt konverteras till flyttal / flyttal.

Tack!! jag ska tugga lite på detta återkommer!