Permalänk

Får ej min loop att fungera

Hejsan har suttit med min uppgift och försökt klura ut det ena efter det andra, vet ej hur jag ska lyckas. Är ny inom detta och lärarhjälpen är i princip obefintlig då jag ska googla mig fram till allt mellan himmel och jord. Hur som helst ska jag göra en uppgift där man ska omvandla fahr till cels och det ska ske i en console och man ska gissa upprepade gånger tills man får rätt tempratur. Felet i min kod är att när jag tar mig till "hej skriv temp" och baserat på vad jag skriver första gången så blir svaret den samma hela tiden efter, så om jag skriver 100 första gången och sen ändrar till 10000 så kommer det vara samma svar. Vet ej hur jag får den att gå tillbaka till början och lagra ett nytt svar. här är min kod

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyBastu { class Program { public static int FahrToCel(int fahr) { int cel = (fahr - 32) * 5 / 9; return cel; } static void Main(string[] args) { bool Slut = false; Console.WriteLine("Tjena min vän, skriv hur många grader du vill att aggregatet ska vara:"); int fahr = int.Parse(Console.ReadLine()); int cel = FahrToCel(fahr); int hogsta = 77; int lagsta = 73; while (Slut == false) { if (cel <= hogsta & cel >= lagsta) { Console.WriteLine("Nu är det rätt värme i bastun, varsågod och basta."); Console.ReadLine(); Slut = true; } else if (cel < 25) { Console.WriteLine("Bastun har precis blivit varm, långt kvar till rätt temperatur"); } else if (cel < lagsta & cel > 25) { Console.WriteLine("Det är för kallt i aggregatet, höj tempraturen."); Console.ReadLine(); } else if (cel > hogsta & cel > 100) { Console.WriteLine("Det är för varmt i aggregatet, sänk tempraturen."); Console.ReadLine(); } else if (cel > 100) { Console.WriteLine("Det är fööööööööööööööör varmt i aggregatet, sänk tempraturen."); Console.ReadLine(); } } } } }

Permalänk
Medlem

I loopen sätter du aldrig inläsningen från Console.ReadLine(); till din variabel.

Och använd inte svenska i variabelnamn eller dylikt

Visa signatur

Intel i7 4970K, Fractal define mini, 24GB DDR3 1600mhz , 500GB SSD * 2 RAID0, GeForce 1060 6gb

Permalänk
Medlem

Prova med dubbla & istället.

Visa signatur

i7 4790k | Asus Z97M-Plus | 16gb ram | Asus Strix 970 | Phanteks PH-TC12DX | Samsung 850 Evo 250gb | Corsair Force GS 120gb | Fractal Design Integra M 650w | Fractal Design Define Mini C

Permalänk

@railman: Tar jag bort Console.ReadLine();
Så får jag svaret "Det är för kallt" över hela skärmen, fortsätter bara ner och ner

Permalänk
Medlem

@mattin123: Menar inte att du ska ta bort, kolla på koden innan loopen, där tar du hand om värdet som matas in och sparar det i variabler.
Det behöver du även göra i loopen. Annars förändras aldrig värdena.

Ska även vara dubbla & i IF-satserna som Snorlena skriver.

Visa signatur

Intel i7 4970K, Fractal define mini, 24GB DDR3 1600mhz , 500GB SSD * 2 RAID0, GeForce 1060 6gb

Permalänk

@Snorlena: @railman:

Tack så mycket, ska åtgärda och se vad som händer. Hur lång tid kommer detta ta innan man lär sig grunderna

Permalänk

@railman: Förlåt, men förstår inte vad du vill att jag ska skriva i loopen?
Jag förstår att koderna jag skrivit gör om mitt svar från fahr till cels och sedan sparar det i variabel.

Men hur menar du att jag ska göra det i loopen?

Permalänk
Medlem

@mattin123:

// Läser in en sträng-rad från användaren och slänger sen bort den utan att göra något: Console.ReadLine(); // Läser in en sträng-rad och sparar strängen i en variabel: string s = Console.ReadLine(); // Läser in en sträng-rad och gör direkt om den till en int utan att mellanlagra i en variabel: int i = int.Parse(Console.ReadLine());

Men du gör samma fel som så många andra när det gäller såna här uppgifter. Du vill ju upprepa inläsningen tills användaren gissar rätt, så att börja med att läsa in en gissning innan du börjat loopa krånglar bara till det. Läs in gissningen inne i loopen istället, så att du har inläsningen på ett enda ställe i koden (d.v.s. koden ska endast innehålla ett enda anrop till Console.ReadLine).

Om du inte måste använda en while-loop så är det för övrigt bättre med en do-while-loop i detta fall, eftersom du alltid vill läsa in minst en gissning. Då behöver du inte heller Slut-variabeln, du kan istället göra kontrollen direkt i while-villkoret.

Permalänk
Medlem

@mattin123: Testa det här:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyBastu { class Program { public static int FahrToCel(int fahr) { int cel = (fahr - 32) * 5 / 9; return cel; } static void Main(string[] args) { bool Slut = false; int hogsta = 77; int lagsta = 73; while (Slut == false) { Console.WriteLine("Tjena min vän, skriv hur många grader du vill att aggregatet ska vara:"); int fahr = int.Parse(Console.ReadLine()); int cel = FahrToCel(fahr); if (cel <= hogsta & cel >= lagsta) { Console.WriteLine("Nu är det rätt värme i bastun, varsågod och basta."); Slut = true; } else if (cel < 25) { Console.WriteLine("Bastun har precis blivit varm, långt kvar till rätt temperatur"); } else if (cel < lagsta & cel > 25) { Console.WriteLine("Det är för kallt i aggregatet, höj tempraturen."); } else if (cel > hogsta & cel > 100) { Console.WriteLine("Det är för varmt i aggregatet, sänk tempraturen."); } else if (cel > 100) { Console.WriteLine("Det är fööööööööööööööör varmt i aggregatet, sänk tempraturen."); } } } } }

Permalänk

@SaadRH: Tack för hjälpen, fattar inte hur jag ska kunna detta utan någon slags genomgång. Men hur som helst så har jag lagt in din kod och även lagt in två &&, misstänkte att du hade missat det, men koden krånglar fortfarande.
1. skriver jag in "200" så repeterar den första raden.
2. Sen efter att den skriver värdet, så måste jag trycka på en bokstav och då kommer första raden upp igen,

Permalänk

Nu har jag grejat lite med den, har fortfarande två fel.
1. Sista else if funkar ej.
2. efter att jag skrivit in tempratuern måste jag skriva in den igen innan jag får ett värde.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyBastu { class Program { public static int FahrToCel(int fahr) { int cel = (fahr - 32) * 5 / 9; return cel; } static void Main(string[] args) { bool Slut = false; int hogsta = 77; int lagsta = 73; Console.WriteLine("Tjena min vän, skriv hur många grader du vill att aggregatet ska vara:"); while (Slut == false) { int fahr = int.Parse(Console.ReadLine()); int cel = FahrToCel(fahr); if (cel <= hogsta && cel >= lagsta) { Console.WriteLine("Nu är det rätt värme i bastun, varsågod och basta."); Slut = true; Console.ReadKey(); } else if (cel < 25) { Console.WriteLine("Bastun har precis blivit varm, långt kvar till rätt temperatur, försök igen:"); Console.ReadLine(); } else if (cel < lagsta && cel > 25) { Console.WriteLine("Det är för kallt i aggregatet, höj tempraturen. Försök igen:"); Console.ReadLine(); } else if (cel > hogsta && cel > 100) { Console.WriteLine("Det är för varmt i aggregatet, sänk tempraturen. Försök igen:"); Console.ReadLine(); } else if (cel > 100) { Console.WriteLine("Det är fööööööööööööööör varmt i aggregatet, sänk tempraturen. Försök igen:"); Console.ReadLine(); } } } } }

EDIT: Ändrade allt till readkey och svaren är olika beroende på hur jag börjar. men nu får jag iaf ett värde varje gång, dock blir det samma värde varje gång beroende på vilken siffra jag matar in.

Permalänk
Medlem

Varje gång du skriver Console.ReadKey(); eller Console.ReadLine(); så väntar applikationen på input från tangentbordet. Ta bort de du har i varje "if" och "else if" så har du inte det problemet.

Permalänk

@toobypls: Tack så mycket.
Att det ska vara så lätt men så svårt.

Permalänk
Medlem

@mattin123: Ett tips är att lära dig hur du debuggar din kod, se t.ex. denna sida som tar upp grunderna. Med debuggern kan du bl.a. stega igenom programmet rad för rad och se exakt vad som händer, så att du t.ex. kan se vilken gren av if-satsen programmet går in i när ett visst värde matas in.

Permalänk
99:e percentilen
Skrivet av railman:

Och använd inte svenska i variabelnamn eller dylikt

Jag tycker det är helt OK att använda svenska variabelnamn i början, när man ännu är osäker på språkets grammatik, eftersom det kan göra det lättare att se skillnad på nyckelord (som är huggna i sten – if, while, …) och identifierare (som man får välja själv – cel, fahr, ettSchysstTal, …). Samma sak kan även gälla namn som kommer från standardbiblioteket (Console.WriteLine, …) vs namn man valt helt själv (cel, fahr, …).

Tramsiga variabelnamn kan även fungera som en stämningshöjande faktor om man sitter med en kämpig inlämningsuppgift. Betrakta till exempel följande framtvingade och orealistiska, men ändock illustrativa, exempel:

-- Just to show the type of (>>=): (>>=) :: Monad m => m a -> ( a -> m b) -> m b -- rolig a -> (tråkig a -> rolig b) -> rolig b tenDividedBy :: Int -> Maybe Int tenDividedBy x = let roligA = Just x tråkigATillRoligB a = if a == 0 then Nothing else Just (10 `div` a) in roligA >>= tråkigATillRoligB

I "riktiga" projekt har du naturligtvis rätt, och man bör absolut gå över till engelska namn så snart man lärt sig skillnaden mellan nyckelord och identifierare samt börjat få lite koll på standardbiblioteket.

Visa signatur

Skrivet med hjälp av Better SweClockers

Permalänk
Medlem
Skrivet av mattin123:

Nu har jag grejat lite med den, har fortfarande två fel.
1. Sista else if funkar ej.

Tycker din kod ser bra ut för att vara nybörjare, tar ett tag innan man kommer in i tankesättet, men tillslut lossnar det, så kämpa på!

Angående varför koden inte kommer in i den sista if-satsen så får du höja blicken till den ovanför. Den kommer alltid att vara sann varje gång som den sista också är det, vilket gör att det är den du kommer in i.

Hint: jag tror att det du egentligen vill kontrollera där är ifall värden ligger mellan högsta och 100.

Skickades från m.sweclockers.com

Permalänk
99:e percentilen
Skrivet av mattin123:

Sista else if funkar ej.

Betrakta ett av dina if-villkor:

cel > hogsta && cel > 100

hogsta har du definierat högre upp. Fundera över vad villkoret ovan betyder. (Läs noggrant! Det viktiga är vad det faktiskt står, inte vad du förväntar dig att det ska stå.)

Visa signatur

Skrivet med hjälp av Better SweClockers

Permalänk

@noyce: @Alling: @perost:

Tack så mycket för hjälpen. Löste problemen tillslut med eran hjälp, fick googla till mig hur jag skulle använda try catch, visste ej att alla koder skulle in i try så det tog en stund men tillslut stämmer koden och allt fungerar som jag vill med olika svar. Ändrade det till engelska med iochmed att det är en amerikan som ska skriva in fahr. Såhär ser den ut, vet ej om jag gjort allt rätt som man ska men den fungerar, kom gärna med inputs.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyBastu { class Program { public static int FahrToCel(int fahr) { int cel = (fahr - 32) * 5 / 9; return cel; } static void Main(string[] args) { bool Slut = false; int hogsta = 77; int lagsta = 73; Console.WriteLine("Hello my friend, it's time to sauna. Together we will find the right temperature."); Console.WriteLine("Please enter your thought of a perfect temperature in a sauna: "); while (Slut == false) { try { int fahr = int.Parse(Console.ReadLine()); int cel = FahrToCel(fahr); if (cel <= hogsta && cel >= lagsta) { Console.WriteLine("Now you have a perfect temperature to sauna, enjoy your time"); Console.ReadLine(); Slut = true; } else if (cel < 25) { Console.WriteLine("Thats unfortunaly too cold, you will freeze inside the sauna. Try higher temperature:"); } else if (cel < 60 && cel >= 25) { Console.WriteLine("Still cold for you to go inside, but you are getting closer to the right temperature. Try warmer:"); } else if (cel > 101 && cel < 150) { Console.WriteLine("Now is it to hot inside, you wont handle the heat, lower the temperature my friend. Write again:"); } else if (cel >= 150) { Console.WriteLine("If you dont wanna burn yourself you have to lower the temperature:"); } else if (cel < 73 & cel >= 60) { Console.WriteLine("You are getting really close to the perfect temperature. Little bit warmer:"); } else if (cel >= 78 & cel <= 100) { Console.WriteLine("You are getting really close to the perfect temperature. Little bit colder:"); } } catch (Exception) { Console.WriteLine("Just integers my friend:"); } } } } }

Permalänk
Medlem

@mattin123: Din lösning är inte direkt fel, men normalt vill man ha så lite som möjligt i en try-catch så att man har koll på vilka exceptions det är man kan tänkas få. Om t.ex. Console.WriteLine skulle kasta ett IOException (inte så troligt i ditt fall, men det är möjligt) så vill du ju inte säga åt användaren att mata in ett heltal, eftersom det inte reflekterar felet som uppstod.

Jag gissar att problemet du stötte på var att du deklarerade dina variabler inne i try-satsen, och sen inte kunde komma åt dem utanför. D.v.s. så här:

try { int fahr = int.Parse(Console.ReadLine()); } catch (Exception) { Console.WriteLine("Just integers my friend:"); } int cel = FahrToCel(fahr); // Fel, fahr är inte deklarerad här!.

I C# så definierar nämligen { } ett block, variabler som är deklarerade inne i ett block slutar existera när exekveringen av koden går ut ur blocket. Vad du får göra istället är att deklarera variabeln utanför try-satsen, d.v.s.:

int fahr; while (true) { try { fahr = int.Parse(Console.ReadLine()); break; // Avsluta loopen om ett giltigt värde matas in. } catch (...) { } } int cel = FahrToCel(fahr); // Ok, fahr är deklarerad i samma block som cel.

Notera att jag lade try-catch-satsen i en egen liten loop, så att den upprepas tills dess att ett giltigt värde matas in. Denna lösning blir alltså lite mer invecklad, men samtidigt enklare att resonera kring eftersom inläsningen blir mer samlad på ett ställe i koden (man skulle med fördel kunna lägga inläsningskoden i en egen metod, men det kanske är överkurs vid det här laget).

Permalänk
Medlem
Skrivet av perost:

@mattin123: Din lösning är inte direkt fel, men normalt vill man ha så lite som möjligt i en try-catch så att man har koll på vilka exceptions det är man kan tänkas få. Om t.ex. Console.WriteLine skulle kasta ett IOException (inte så troligt i ditt fall, men det är möjligt) så vill du ju inte säga åt användaren att mata in ett heltal, eftersom det inte reflekterar felet som uppstod.

Jag gissar att problemet du stötte på var att du deklarerade dina variabler inne i try-satsen, och sen inte kunde komma åt dem utanför. D.v.s. så här:

try { int fahr = int.Parse(Console.ReadLine()); } catch (Exception) { Console.WriteLine("Just integers my friend:"); } int cel = FahrToCel(fahr); // Fel, fahr är inte deklarerad här!.

I C# så definierar nämligen { } ett block, variabler som är deklarerade inne i ett block slutar existera när exekveringen av koden går ut ur blocket. Vad du får göra istället är att deklarera variabeln utanför try-satsen, d.v.s.:

int fahr; while (true) { try { fahr = int.Parse(Console.ReadLine()); break; // Avsluta loopen om ett giltigt värde matas in. } catch (...) { } } int cel = FahrToCel(fahr); // Ok, fahr är deklarerad i samma block som cel.

Notera att jag lade try-catch-satsen i en egen liten loop, så att den upprepas tills dess att ett giltigt värde matas in. Denna lösning blir alltså lite mer invecklad, men samtidigt enklare att resonera kring eftersom inläsningen blir mer samlad på ett ställe i koden (man skulle med fördel kunna lägga inläsningskoden i en egen metod, men det kanske är överkurs vid det här laget).

Förstår ditt resonemang, men i detta fall är det obviously en skoluppgift där de ska använda try/catch.
I vanliga fall vid en parse så använder man TryParse och inte ett try/catch block runt parsning. Något man också kan bryta ut till en egen liten metod inklusive ett prompt-message

public static void Main() { var num = InputToInt("Skriv ett heltal: "); } public static int InputToInt(string prompt) { int result; Console.Write(prompt); while (!int.TryParse(Console.ReadLine(), out result)) { Console.WriteLine("Du måste ange ett heltal."); } return result; }

Skrivet av mattin123:

@noyce: @Alling: @perost:

Tack så mycket för hjälpen. Löste problemen tillslut med eran hjälp, fick googla till mig hur jag skulle använda try catch, visste ej att alla koder skulle in i try så det tog en stund men tillslut stämmer koden och allt fungerar som jag vill med olika svar. Ändrade det till engelska med iochmed att det är en amerikan som ska skriva in fahr. Såhär ser den ut, vet ej om jag gjort allt rätt som man ska men den fungerar, kom gärna med inputs.

I början då man lär sig koda är det viktigaste att saker fungerar, vilket det verkar göra Best practises och sådant lär man sig med tiden.
Men något som jag kan påpeka är:

Använd endast try-blocket runt koden som kan throwa ett exception. All kod du lägger i ett try block kommer att ingå i felhantering och på så vis påverka prestandan.
Använd aldrig catch(Exception) om du inte specifikt letar någon bugg eller dylikt och vill få ut mer information om felet som throwas.
Exception är basklassen för alla exceptions och den kommer att fånga ALLA fel som kan uppstå och i vanliga fall vill man inte göra detta.
I detta fall då det är en parse kan du avända dig av FormatException då det är specifikt det felet du vill hantera.

Sedan vet jag inte om du läst något om switch-case, men det gör koden mycket cleanare och lättare att läsa än att skriva en hög med else if. Annars är det något jag rekommenderar att du kollar upp, jag använder det ofta.

Permalänk

@perost:
Jag la in det i en egen try först men då krånglade det med att jag var tvungen att mata in temperaturen två gånger för varje gång jag skulle gissa temperatur.

Skickades från m.sweclockers.com

Permalänk

@zaibuf:

Absolut. Jag ska kolla in i switch, tack för tipset

Skickades från m.sweclockers.com