Permalänk
Medlem

Programmering 1

Hej,

Jag pluggar programmering 1 på Hermods och har kört fast helt och hållet.
Uppgiften är enligt följande:
Denna uppgift går ut på att en amerikanare ska skriva in en temperatur för ett bastuaggregat tills man skriver in
en temperatur som anses lagom. För att kontrollera detta ska vi ha en temperatur som anger den lägsta
godtagbara temperaturen och en som anger den högsta godtagbara temperaturen.
Tyvärr förstår vår kära bastubesökare enbart Fahrenheit medan
bastuaggregatet enbart förstår Celsius. Därför har du fått skriva ett program
som konverterar det som skrivs in från Fahrenheit till Celsius.
Den optimala temperaturen för bastun är 75 grader men den godtagbara
temperaturen är från 73 till 77 grader. Detta ska styras hela i villkorssatsen i
loopen.
Om talet är mindre än den minsta godtagbara temperaturen ska programmet
skriva att det är för kallt och man får skruva upp lite. Därefter får
bastubesökaren ställa in ett nytt värde på bastuaggregatet och loopen
upprepas.
I denna uppgift ska ni hantera följande:
1. Undantagshantering
2. Metoder
3. Villkor
Då amerikanaren kan skriva in i Fahrenheit så innebär det ett värde på 167 grader (=75 grader) men det vet ju
inte han eller hon då det är deras första bastubesök någonsin.

Lös uppgiften och att värdet Celsius sparas som ett flyttal
med decimaler.
För att en beräkning ska fungera med decimaltal måste
alla tal i formeln vara av flyttalstyp.
Denna formel kommer inte att fungera då fahr är ett
heltal.
double temp = (fahr - 32) * 5
/ 9;
Här behöver man alltså omvandla fahr till samma double (eller float om ni jobbar med det). Ett sätt att göra detta
på är att ”typomvandla” fahr i formeln ovan så det behandlas som en double i formeln.
För att lösa detta kan man jobba med så kallad explicit typomvandling som beskrivs på MSDNs hemsida med ett
enkelt exempel på följande länk:
https://msdn.microsoft.com/en-us/library/ms173105.aspx#Anchor...
Jag vill fortfarande att det tal användaren skriver in lagras i en int först eftersom man med stor sannolikhet bara
skriver in heltal. Det innebär att metoden ska se ut så här:
public static double FahrToCels(int fahr)
{
//Typomvandla fahr till flyttal
//Gör uträkning med decimaler i svaret
return temp;
}
Utöver detta fungerar programmet på ett liknande sätt förutom att det är ett decimaltal som testas mot en
lämplig temperatur

Jag vill inte be om ett facit utan enbart hjälp att förstå hur jag ska tänka och var jag gör fel. Vill verkligen lära mig.
Nu omvandlas graderna felaktigt när jag kör programmet. När jag tex. slår in 123 fahrenheit så blir svaret att det motsvarar 0 grader celsius, medan om jag slår in 100 blir svaret 50.56, också felaktigt.
Det jag behöver hjälp med är att jag vill veta vad jag gör för fel i decimalomvandlingen?
Tar jag bort mina valda 2 decimaler helt från koden så blir svaret korrekt men med för många decimaler.
Vore tacksam om någon ville förklara

// METOD: FahrToInt, konverterar Fahrenheit till Celsius // Här följer metoddefinitionen: public static double FahrToCels(int fahr) { double temp = (double)fahr;// casting i högerled - tilldela fahr till double temp = (fahr - 32) * 5 / 9.0; // konverta fahr till celsius & rfeturnera return temp; } //METOD: Main, Startar programmet. public static void Main(string[] args) { int fahr = 0; double temp = 0; double tvåDecimaler = 2; Console.WriteLine("Welcome to the Sauna!\n" + "Please set a temperature in fahrenheit: "); //Metodanrop do { try { fahr = int.Parse(Console.ReadLine()); //Konvertera grader fahr till heltal tvåDecimaler = Math.Round(temp,2); } catch { Console.WriteLine("invalid number"); continue; //denna kod gör att koden börjar om vid DO och kör om loopen på nyttWel } temp = FahrToCels(fahr); Console.WriteLine($"{fahr} degrees fahrenheit is {tvåDecimaler} degrees Celsius."); //metoden har anropats och värdet för celsius har decimaltal // programmet följer här med villkor och dylikt if (temp < 73.0) { Console.WriteLine("it's too cold in the sauna. please raise the temperature:"); } else if (temp > 77.0) { Console.WriteLine("It's too hot in the sauna, please lower the temperature: "); } else if (temp == 75.0) { Console.WriteLine("This temperature is perfect, enjoy the sauna!"); } else { Console.WriteLine("This temperature is almost perfect, enjoy the sauna!"); } } while (temp <= 73.0 || temp >= 77.0); Console.ReadKey();

Permalänk
Medlem

I avrundningen använder du fel variabel för första parametern. Samt så finns det ingen anledning att avrunda något förrän efter att man har konverterat, samt här så konverterar du en int vilket kommer ge felmeddelande samt vore onödigt då dem endast kan innehålla heltal.

tvåDecimaler = Math.Round(temp,2);

Här skriver du ut fel variabel för att få ut Celsius(inte tvåDecimaler utan ...?). Detta är dock rätt om du fixar till det fel som jag nämnde ovan.

Console.WriteLine($"{fahr} degrees fahrenheit is {tvåDecimaler} degrees Celsius.");

Första raden blir ganska meningslös, du sätter temp till fahr men konverterad till double, men sen skriver du över det direkt igen på nästa rad.
Ta bort den raden helt istället och göra deklareringen och omvandlingen istället på samma rad som formeln, alternativt så ändrar du helt enkelt till (temp - 32) på raden nedan vilket bör fungera korrekt.

public static double FahrToCels(int fahr) { double temp = (double)fahr;// casting i högerled - tilldela fahr till double temp = (fahr - 32) * 5 / 9.0; // konverta fahr till celsius & rfeturnera return temp; }

Kan alltid utveckla på svaren, men är relativt lätta fel som du säkert kan åtgärda relativt lätt.

Permalänk
Medlem

du söka "bastun" här i forumet - svarat minst 4-5 ggr tidigare

//LZ

Permalänk
Medlem
Skrivet av Tea42BBS:

du söka "bastun" här i forumet - svarat minst 4-5 ggr tidigare

//LZ

Beroende på hur man lär sig så kanske man inte vill söka upp en redan befintlig lösning. Det blir förmodligen rätt att återanvända en lösning, men jag gissar att det inte är lika lärorikt och problemet är förmodligen inte exakt detsamma.

För de som lär sig programmering så tycker jag att det är en fördel att de får förklara just sitt problem. Det hjälper i alla fall mig att reflektera över vad jag håller på med.

Permalänk
Medlem
Skrivet av MickeBoy:

Beroende på hur man lär sig så kanske man inte vill söka upp en redan befintlig lösning. Det blir förmodligen rätt att återanvända en lösning, men jag gissar att det inte är lika lärorikt och problemet är förmodligen inte exakt detsamma.

För de som lär sig programmering så tycker jag att det är en fördel att de får förklara just sitt problem. Det hjälper i alla fall mig att reflektera över vad jag håller på med.

Det är en skoluppgift - så det känns som den är exakt den samma.

En stor del av att vara utvecklare idag är att söka information/lösning - sen kan man diskutera lösningen, det finns alltid många sätt att lösa samma problem. Även att ta delar av en färdig lösning kräver förståelse för de ingående pusselbitarna. Jag har programmerat sen 1980 - för mig har det ofta börjat med att kopiera delar, förstå, göra om - reflektera. Sen ta nästa projekt / uppgift o då förhoppningsvis kunna använda min tidigare kod/kunskap för att lösa uppgiften snabbare

Men alla är fria att ha sina egna tillvägagångssätt, det är det fina med att bo i Sverige

mvh Lazze

Permalänk
Medlem
Skrivet av Hot Dogs:

I avrundningen använder du fel variabel för första parametern. Samt så finns det ingen anledning att avrunda något förrän efter att man har konverterat, samt här så konverterar du en int vilket kommer ge felmeddelande samt vore onödigt då dem endast kan innehålla heltal.

tvåDecimaler = Math.Round(temp,2);

Här skriver du ut fel variabel för att få ut Celsius(inte tvåDecimaler utan ...?). Detta är dock rätt om du fixar till det fel som jag nämnde ovan.

Console.WriteLine($"{fahr} degrees fahrenheit is {tvåDecimaler} degrees Celsius.");

Första raden blir ganska meningslös, du sätter temp till fahr men konverterad till double, men sen skriver du över det direkt igen på nästa rad.
Ta bort den raden helt istället och göra deklareringen och omvandlingen istället på samma rad som formeln, alternativt så ändrar du helt enkelt till (temp - 32) på raden nedan vilket bör fungera korrekt.

public static double FahrToCels(int fahr) { double temp = (double)fahr;// casting i högerled - tilldela fahr till double temp = (fahr - 32) * 5 / 9.0; // konverta fahr till celsius & rfeturnera return temp; }

Kan alltid utveckla på svaren, men är relativt lätta fel som du säkert kan åtgärda relativt lätt.

Tusen tack för utförlig förklaring, hjälper massor
Jag har nu "möblerat" om lite i koden och fått den att fungera, jag flyttade bland annat Math.round som gav mig rätt antal decimaler.
Däremot förstod jag inte riktigt hur du menade med:
Första raden blir ganska meningslös, du sätter temp till fahr men konverterad till double, men sen skriver du över det direkt igen på nästa rad.
Ta bort den raden helt istället och göra deklareringen och omvandlingen istället på samma rad som formeln, alternativt så ändrar du helt enkelt till (temp - 32) på raden nedan vilket bör fungera korrekt.

public static double FahrToCels(int fahr) { double temp = (double)fahr;// casting i högerled - tilldela fahr till double temp = (fahr - 32) * 5 / 9.0; // konverta fahr till celsius & rfeturnera return temp; }

När jag tar bort den övre raden får jag felmeddelande" the name 'temp' does not exist in the current context"
Menade du att jag kunde ta bort den raden och på rad nr två ändra från "(fahr-32)" till "(temp-32)" och få korrekt svar?
Jag har flera gånger lyckats med dessa fel, att skriva en kod som jag sedan skriver över och jag vill gärna lära mig hur jag ska tänka där mer än att koden läses uppifrån och ner, eller är det så enkelt? är verkligen helt grön och uppskattar tips och feedback super mycket!!

nedan är min "nya" kod:

class Program { // METOD: FahrToInt, konverterar Fahrenheit till Celsius // Här följer metoddefinitionen: public static double FahrToCels(int fahr) { // casting i högerled - tilldela fahr till double temp = (fahr - 32) * 5 / 9.0; // konverta Fahrenheit till Celsius & returnerar. return temp; } //METOD: Main, Startar programmet. public static void Main(string[] args) { //Nedan koder deklarerar variabler för Fahrenheit, Celsius och antal decimaler. int fahr = 0; double temp = 0; double enDecimal = 1; Console.WriteLine("Welcome to the Sauna!\n" + "Please set a temperature in Fahrenheit: "); // Nedan börjar Do-While loopen som innehåller en try catch felhantering. // om användaren matar in annat än siffror kommer ett felmeddelande och loopen körs om. // Metoden anropas och värdet för Celsius avrundas till en deimal. Efter följer if else villkor. do { try { fahr = int.Parse(Console.ReadLine()); } catch { Console.WriteLine("invalid number"); continue; //denna kod gör att koden börjar om vid DO och kör om loopen på nytt. } temp = FahrToCels(fahr); enDecimal = Math.Round(temp, 1); Console.WriteLine($"{fahr} degrees Fahrenheit is {enDecimal} degrees Celsius."); if (temp < 73.0) { Console.WriteLine("it's too cold in the sauna, please raise the temperature:"); } else if (temp > 77.0) { Console.WriteLine("It's too hot in the sauna, please lower the temperature: "); } else if (temp == 75.0) { Console.WriteLine("This temperature is perfect, enjoy the sauna!"); } else { Console.WriteLine("This temperature is almost perfect, enjoy the sauna!"); } } while (temp <= 73.0 || temp >= 77.0); Console.ReadKey();

Permalänk
Medlem
Skrivet av evelinan:

Däremot förstod jag inte riktigt hur du menade med:
Första raden blir ganska meningslös, du sätter temp till fahr men konverterad till double, men sen skriver du över det direkt igen på nästa rad.
Ta bort den raden helt istället och göra deklareringen och omvandlingen istället på samma rad som formeln, alternativt så ändrar du helt enkelt till (temp - 32) på raden nedan vilket bör fungera korrekt.

public static double FahrToCels(int fahr) { double temp = (double)fahr;// casting i högerled - tilldela fahr till double temp = (fahr - 32) * 5 / 9.0; // konverta fahr till celsius & rfeturnera return temp; }

När jag tar bort den övre raden får jag felmeddelande" the name 'temp' does not exist in the current context"
Menade du att jag kunde ta bort den raden och på rad nr två ändra från "(fahr-32)" till "(temp-32)" och få korrekt svar?

Problemet är att du deklarerar temp och initierar den med värdet från fahr, men på nästa rad skriver du över värdet på temp igen. D.vs. istället för att skriva double temp = (double)fahr; så kan du lika gärna skriva double temp;, för du kommer ju ändå ge temp ett nytt värde på nästa rad.

Att casta fahr till double är också onödigt, det händer automatiskt när du delar (farh - 32) * 5 med 9.0 eftersom 9.0 är en double.

Men sen finns det ingen större mening med att separera deklarationen och initieringen av temp, d.v.s. istället för att deklarera temp på en rad och ge den ett värde på nästa så kan du lika gärna deklarera och initiera variabeln samtidigt (vilket ofta är en bra idé att göra):

double temp = (fahr - 32) * 5 / 9.0;

Nästa steg är sen att inse att du inte gör någonting med temp annat än att returnera dess värde från metoden, vilket innebär att du lika gärna kan returnera värdet direkt och helt strunta i variabeln:

return (fahr - 32) * 5 / 9.0;

Permalänk
Medlem
Skrivet av perost:

Problemet är att du deklarerar temp och initierar den med värdet från fahr, men på nästa rad skriver du över värdet på temp igen. D.vs. istället för att skriva double temp = (double)fahr; så kan du lika gärna skriva double temp;, för du kommer ju ändå ge temp ett nytt värde på nästa rad.

Att casta fahr till double är också onödigt, det händer automatiskt när du delar (farh - 32) * 5 med 9.0 eftersom 9.0 är en double.

Men sen finns det ingen större mening med att separera deklarationen och initieringen av temp, d.v.s. istället för att deklarera temp på en rad och ge den ett värde på nästa så kan du lika gärna deklarera och initiera variabeln samtidigt (vilket ofta är en bra idé att göra):

double temp = (fahr - 32) * 5 / 9.0;

Nästa steg är sen att inse att du inte gör någonting med temp annat än att returnera dess värde från metoden, vilket innebär att du lika gärna kan returnera värdet direkt och helt strunta i variabeln:

return (fahr - 32) * 5 / 9.0;

Tusen tack!! Nu förstår jag vad ni menar det rensar upp en hel del i min kod och gör den mycket tydligare. Detta är som sagt något jag råkar göra ofta så ska tänka på det!