Komplettering på uppgift / modulus / växel

Permalänk

Komplettering på uppgift / modulus / växel

Hejsan allihopa!

Jag håller på att studera programmering 1 och lämnade precis in min första inlämningsuppgift.

Jag testade att köra den flera gånger och det gick galant.

Men när läraren fick uppgiften så märkte han att det var fel och fick fel uträkning.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Växel { internal class Program { static void Main(string[] args) { int växel; int tusenlapp = 0; int femhundralapp = 0; int hundralapp = 0; int femtiolapp = 0; int tjugolapp = 0; int tiokrona = 0; int femkrona = 0; int enkrona = 0; Console.WriteLine("Hej och välkommen till växeln. Tryck på enter för att fortsätta "); Console.ReadLine(); Console.Write("Mata in varans pris: "); int nummer1 = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Din vara kostar: " + nummer1 + " kronor "); Console.Write("Hur mycket pengar har du?: "); int nummer2 = Convert.ToInt32(Console.ReadLine()); växel = nummer2 - nummer1; Console.WriteLine("Du får tillbaka " + ( växel ) + " kronor "); Console.ReadLine(); tusenlapp = växel / 1000; femhundralapp = (växel % 1000) / 500; hundralapp = (växel % 500) / 100; femtiolapp = (växel % 100) / 50; tjugolapp = (växel % 50) / 20; tiokrona = (växel % 20) / 10; femkrona = (växel % 10) / 5; enkrona = växel % 5; Console.WriteLine("Du får: " + tusenlapp + " tusenlapp(ar) " ); Console.WriteLine("Du får: " + femhundralapp + " femhundralapp(ar) " ); Console.WriteLine("Du får: " + hundralapp + " hundralapp(ar) "); Console.WriteLine("Du får: " + femtiolapp + " femtiolapp(ar) "); Console.WriteLine("Du får: " + tjugolapp + " tjugolapp(ar) "); Console.WriteLine("Du får: " + tiokrona + " tiokron(or) "); Console.WriteLine("Du får: " + femkrona + " femkron(or) "); Console.WriteLine("Du får: " + enkrona + " enkron(or) ");

Problemet var att när han matade in 25kr och matade in att han hade 100kr så skulle uträkningen = 75kr tillbaka.

Men fick 85kr tillbaka (en extra tiokrona)

Jag har suttit ett bra tag och kollat igenom men hittar inte problemet.

Ser ni något?

Mvh

Permalänk
Medlem
Skrivet av Scratchifyy:

Hejsan allihopa!

Jag håller på att studera programmering 1 och lämnade precis in min första inlämningsuppgift.

Jag testade att köra den flera gånger och det gick galant.

Men när läraren fick uppgiften så märkte han att det var fel och fick fel uträkning.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Växel { internal class Program { static void Main(string[] args) { int växel; int tusenlapp = 0; int femhundralapp = 0; int hundralapp = 0; int femtiolapp = 0; int tjugolapp = 0; int tiokrona = 0; int femkrona = 0; int enkrona = 0; Console.WriteLine("Hej och välkommen till växeln. Tryck på enter för att fortsätta "); Console.ReadLine(); Console.Write("Mata in varans pris: "); int nummer1 = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Din vara kostar: " + nummer1 + " kronor "); Console.Write("Hur mycket pengar har du?: "); int nummer2 = Convert.ToInt32(Console.ReadLine()); växel = nummer2 - nummer1; Console.WriteLine("Du får tillbaka " + ( växel ) + " kronor "); Console.ReadLine(); tusenlapp = växel / 1000; femhundralapp = (växel % 1000) / 500; hundralapp = (växel % 500) / 100; femtiolapp = (växel % 100) / 50; tjugolapp = (växel % 50) / 20; tiokrona = (växel % 20) / 10; femkrona = (växel % 10) / 5; enkrona = växel % 5; Console.WriteLine("Du får: " + tusenlapp + " tusenlapp(ar) " ); Console.WriteLine("Du får: " + femhundralapp + " femhundralapp(ar) " ); Console.WriteLine("Du får: " + hundralapp + " hundralapp(ar) "); Console.WriteLine("Du får: " + femtiolapp + " femtiolapp(ar) "); Console.WriteLine("Du får: " + tjugolapp + " tjugolapp(ar) "); Console.WriteLine("Du får: " + tiokrona + " tiokron(or) "); Console.WriteLine("Du får: " + femkrona + " femkron(or) "); Console.WriteLine("Du får: " + enkrona + " enkron(or) ");

Problemet var att när han matade in 25kr och matade in att han hade 100kr så skulle uträkningen = 75kr tillbaka.

Men fick 85kr tillbaka (en extra tiokrona)

Jag har suttit ett bra tag och kollat igenom men hittar inte problemet.

Ser ni något?

Mvh

Övergripande råd:
Använd debuggern för att stega igenom koden så blir det tydligt för dig vad som faktiskt händer.

Att lägga en liten stund på att lära sig att använda verktygen man har är extremt värdefullt för att arbeta effektivt, om kursen inte gått igenom hur man använder debuggern så ta en stund och lär dig på egen hand. Det är mitt råd iaf.
Och ju tidigare du lär dig detta ju mer tid sparar du på att faktiskt kunna se vad som händer och effektivt kunna lösa problem själv. (Extremt svårt för nybörjare att tänka sig fram till vad som faktiskt händer, så i mitt tycke borde detta vara bland det första som nybörjarkurser går igenom!)

Antar att du använder Visual Studio? Här finns ett relevant avsnitt i Microsofts "getting started"-del av dokumentationen:
https://docs.microsoft.com/en-us/visualstudio/get-started/csh...

Vad gäller ditt konkreta problem så ligger det i hur du väljer ut vilka valörer man ska ta av (totalbeloppet är ju rätt i första steget, men summan av vilka valörer man ska ge stämmer inte).
Utan att ge dig svaret helt så fattas det ett steg i logiken, vilket du kommer inse när du går igenom detta steg för steg och tittar på värdena.

Visa signatur

Desktop spel m.m.: Ryzen 9800X3D || MSI X870 Tomahawk Wifi || MSI Ventus 3x 5080 || Gskill FlareX 6000 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Arbetsstation: Ryzen 7945HX || Minisforum BD790i || Asus Proart 4070 Ti Super || Kingston Fury Impact 5600 65 GB || WD SN850 2TB || Samsung 990 Pro 2TB || Fractal Ridge
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Medlem

Som skriver ovan så är följande snutt fel:

tusenlapp = växel / 1000; femhundralapp = (växel % 1000) / 500; hundralapp = (växel % 500) / 100; femtiolapp = (växel % 100) / 50; tjugolapp = (växel % 50) / 20; tiokrona = (växel % 20) / 10; femkrona = (växel % 10) / 5; enkrona = växel % 5;

Att använda debuggern är ett utmärkt tips. Du bör även se till så du har samma indentering på all kod.

Mitt tips är annars att du gör det manuellt på papper. Börja med 75kr växel och stega genom. Vad får du? Varför får du det?

Visa signatur

CPU: Ryzen 5600xGPU: 1080 TI ROG Strix RAM:2x16GB G.skill Trident @ 3600MHz MoBo: Asus B550FPSU: Corsair SF750
En resa till Nordkorea
2 dagar i Tjernobyl

Permalänk

Hej och tack för tipsen.

Ska jag vara ärlig så har jag inte fått någon information om debuggern. Jag använde mig inte av den nu men jag tänkte sätta mig kommande timman och lära mig hur jag kör den.

Jag gjorde som Pelegrrino sa och skrev ner på papper.

tusenlapp = växel / 1000; femhundralapp = (växel % 1000) / 500; hundralapp = (växel % 500) / 100; femtiolapp = (växel % 100) / 50; tjugolapp = (växel % 50) / 20; tiokrona = (växel % 25) / 10; femkrona = (växel % 10) / 5; enkrona = växel % 5;

Nu fungerar det som det ska

Tack för hjälpen och dem grymma tipsen!

Permalänk
Medlem
Skrivet av Scratchifyy:

Nu fungerar det som det ska

Vad händer om du nu matar in så att du ska få tillbaka t.ex. 95 kr?

Permalänk
Skrivet av perost:

Vad händer om du nu matar in så att du ska få tillbaka t.ex. 95 kr?

Ja detta var ju problematiskt.
Jag insåg ju nyss själv att jag åtgärdade problemet för jag redan visste vad inmatningen av kr var.

Jättesvårt för mig att förstå detta..

Permalänk
Medlem

Är uppgiften specifikt för att använda modulus i slututräkningen? Användningen är intressant, men inte alls så som jag skulle löst det rent spontant (genom att räkna ner kvarvarande växel efter antalet av varje valör).

Ett övrigt tips är att se till att dina tester har bra täckning, som i detta fallet att testa att samtliga valörer räknas rätt (vilket borde kunna göras genom en enda körning med växel som innebär att man får tillbaka av varje valör). Nu har du nog fixat felet i dett orginalinlägg men antar att felet var att e.g. 10-kronan aldrig var testad

Visa signatur

Redbox: Asrock B650 Lightning ATX, 7800x3D -20CCO, XFX 6950XT, 2x32GB Corsair Vengence 6400 CL32, WD SN770 2TB, Corsair RMe 1000, Lian Li Lancool 216, Peerless Assassin 120 SE
Purpbox: Z87-Pro, I5 4670K@4.2, Sapphire 290 TRI-X, 2x8GB Crucial Tactical@stock, Deep Silence 1
Samsung Evo 250+500GB + QVO 1TB, 2x1TB 7200RPM backup/lagring
Det var bättre förr: E5300 2600MHz -> 3640MHz, Celeron 300A -> 450MHz

Permalänk
Skrivet av e1m1:

Är uppgiften specifikt för att använda modulus i slututräkningen? Användningen är intressant, men inte alls så som jag skulle löst det rent spontant (genom att räkna ner kvarvarande växel efter antalet av varje valör).

Ett övrigt tips är att se till att dina tester har bra täckning, som i detta fallet att testa att samtliga valörer räknas rätt (vilket borde kunna göras genom en enda körning med växel som innebär att man får tillbaka av varje valör). Nu har du nog fixat felet i dett orginalinlägg men antar att felet var att e.g. 10-kronan aldrig var testad

Inte specifikt det var bara ett "tips" då man räknar resten vid heltalsdivision.

Ska jag vara ärlig så hjälpte en vän mig lite att förstå på modulus. Han var inte jättekunnig i det men verkade ändå som han förstod vad han pratade om. Vi bollade lite fram & tillbaka och han fick mig att förstå. Och när vi kodade på detta viset så körde vi programmet ex antal gånger för att se att vi fick rätt svar. Vilket vi fick.

ex på tal vi använde ( mata in: 32456)
( hur mycket pengar har du: 84345kr)

Vid dem talen så fungerade det galant.

Men när läraren valde att använda sig utav
( mata in: 25kr)
( hur mycket pengar har du?: 100kr)

Så blev det en 10kr för mycket.

Och nu sitter jag här i skiten med en komplettering som jag själv nästan inte förstår hur jag ska felsöka.

(dumt gjort av mig)

Permalänk
Medlem

@Scratchifyy: Du kan använda modulo för att lösa uppgiften, men inte på sättet som du försöker göra nu.

Problemet är att dina beräkningar är helt oberoende, d.v.s. de utgår alltid från hela växelbeloppet istället för att ta hänsyn till hur mycket växel du redan givit tillbaka. Tänk dig hur du skulle räkna på det själv om du skulle ge tillbaka t.ex. 95 kr, då blir det först en femtiolapp, sen är det 45 kr kvar så det blir två tjugor, o.s.v.

Permalänk
Skrivet av perost:

@Scratchifyy: Du kan använda modulo för att lösa uppgiften, men inte på sättet som du försöker göra nu.

Problemet är att dina beräkningar är helt oberoende, d.v.s. de utgår alltid från hela växelbeloppet istället för att ta hänsyn till hur mycket växel du redan givit tillbaka. Tänk dig hur du skulle räkna på det själv om du skulle ge tillbaka t.ex. 95 kr, då blir det först en femtiolapp, sen är det 45 kr kvar så det blir två tjugor, o.s.v.

tusenlapp = växel / 1000; femhundralapp = (växel % 1000) / 500; hundralapp = (växel % 500) / 100; femtiolapp = (växel % 100) / 50; tjugolapp = (25 % 50) / 20; tiokrona = (5 % 20) / 10; femkrona = (växel % 10) / 5; enkrona = växel % 5;

Är jag inne på rätt spår?

Permalänk
Medlem
Skrivet av Scratchifyy:

tusenlapp = växel / 1000; femhundralapp = (växel % 1000) / 500; hundralapp = (växel % 500) / 100; femtiolapp = (växel % 100) / 50; tjugolapp = (25 % 50) / 20; tiokrona = (5 % 20) / 10; femkrona = (växel % 10) / 5; enkrona = växel % 5;

Är jag inne på rätt spår?

Nej, det är inte detaljerna som är fel utan hela metoden Du måste som sagt ta hänsyn till hur mycket växel som faktiskt är kvar, d.v.s. du behöver uppdatera växel efter varje steg.

Permalänk
Medlem
Skrivet av Scratchifyy:

tusenlapp = växel / 1000; femhundralapp = (växel % 1000) / 500; hundralapp = (växel % 500) / 100; femtiolapp = (växel % 100) / 50; tjugolapp = (25 % 50) / 20; tiokrona = (5 % 20) / 10; femkrona = (växel % 10) / 5; enkrona = växel % 5;

Är jag inne på rätt spår?

Nej. Du behöver hela tiden hålla reda på hur mycket växel som återstår.
Själv skulle jag gjort nåt i stil med

tusenlapp = växel/1000; växel = växel % 1000; femhundralapp = växel/500; växel = växel % 500; hundralapp = växel/100;

Osv.

Permalänk
Medlem

För mig så gör modulos ont i huvudet för detta

Modulos visar ju "resten" dvs det som blev kvar när du kollade valören..... Jag hade tittat på liknande mönster

tusenlapp = ( växel / 1000);
växel = växel - (tusenlapp * 1000);

femhundralapp = (växel / 500);
växel = växel - (femhundralapp*500);

hundralapp = (växel / 100);
växel = växel - (hundralapp*100);

Jag föredrar lösningar som är rakt på och inte försvårar det hela

Då dina "lappar" är definierade som INT så kan de endast bli heltal, vilket passar bra i detta läge

mvh Lazze

Permalänk
Medlem
Skrivet av Tea42BBS:

För mig så gör modulos ont i huvudet för detta

Modulos visar ju "resten" dvs det som blev kvar när du kollade valören..... Jag hade tittat på liknande mönster

tusenlapp = ( växel / 1000);
växel = växel - (tusenlapp * 1000);

Det är korrekt, och betyder exakt samma sak som

tusenlapp = (växel/1000);
växel = växel % 1000;

(förutsatt heltalsaritmetik vid division, annars blir bägge varianterna fel)

Det senare är dock lite kortare och enklare att skriva.

Permalänk
Medlem
Skrivet av Erik_T:

Det är korrekt, och betyder exakt samma sak som

tusenlapp = (växel/1000);
växel = växel % 1000;

(förutsatt heltalsaritmetik vid division, annars blir bägge varianterna fel)

Det senare är dock lite kortare och enklare att skriva.

IMHO så är min kod mycket enklare att läsa för någon som inte sett den tidigare.

Permalänk

Tack så mycket för alla kommentarer!

Detta har varit till stor hjälp

Permalänk
Medlem

Tror det ända egentliga problemet med lösningen du lämnade in sker när en valör inte är jämt delbar med nästa.

Ta t.ex. 60kr växel
50lapp:
(60%100)=60 -> korrekt
(60%100)/50=1 -> korrekt, en femtiolapp

20lapp:
(60%50)=10 ->korrekt, vi ska ha kvar 10 efter att ha dragit 50-lappen
(60%50)/20=0 -> korrekt, vi ska inte få någon 20-lapp

10krona:
(60%20)=0 -> fel, vi har ju dragit en 50-lapp och borde ha en rest på 10 efter det, men räknar fortfarande bara bort 20-lappar från det ursprungliga talet, som vi här verkar anta att vi redan gett tillbaka 3 av
(60%20)/10=0 -> STUPID MACHINE STOLE MA MONEYS!

Du kan komma runt det genom att successivt räkna ner växel-variablen (som andra föreslagit, och som jag också spontant hade löst det, då kan du också undvika att använda modulus övh. om du vill). Men du borde fortfarande kunna använda modulus även så som du gjort utan att räkna ner växel-variablen, men du måste göra flera stycken modulus för 10-kronan.

E.g.

10krona:
(60%50%20)=(10%20)=10 -> korrekt, 10 kronor kvar efter att vi dragit 50- och 20-lappar
(60%50%20)/10=1 -> korrekt, det motsvarar en 10-krona

Skrivet av Scratchifyy:

Och när vi kodade på detta viset så körde vi programmet ex antal gånger för att se att vi fick rätt svar. Vilket vi fick.

ex på tal vi använde ( mata in: 32456)
( hur mycket pengar har du: 84345kr)

Vid dem talen så fungerade det galant.

Gjorde det verkligen det? Resten efter 100lappar dragits blir 89kr. Det borde bli 1 50-lapp, 1 20-lapp, 1 10-krona, 1 5-krona, 4 1-kronor.

89/50=1 <- japp, en femtiolapp
(89%50)/20=1 <- japp, en tjuga
(89%20)/10=0 <- nope, fel

(89%50%20)/10 = (39%20)/10 = 19/10 = 1 <- korrekt, en tia

Visa signatur

Redbox: Asrock B650 Lightning ATX, 7800x3D -20CCO, XFX 6950XT, 2x32GB Corsair Vengence 6400 CL32, WD SN770 2TB, Corsair RMe 1000, Lian Li Lancool 216, Peerless Assassin 120 SE
Purpbox: Z87-Pro, I5 4670K@4.2, Sapphire 290 TRI-X, 2x8GB Crucial Tactical@stock, Deep Silence 1
Samsung Evo 250+500GB + QVO 1TB, 2x1TB 7200RPM backup/lagring
Det var bättre förr: E5300 2600MHz -> 3640MHz, Celeron 300A -> 450MHz

Permalänk
Medlem

Liknande kod körs ju för varje möjlig valör, vilket gör det lämpligt att använda en loop för att korta ner koden. Följande kodsnutt ger ett exempel på hur en loop kan användas.

int[] denominations = new int[] {1000,500,200,100,50,20,10,5,2,1}; int amount = 1888; foreach (int i in denominations) { Console.WriteLine(i + ": " + amount/i + "st"); amount %= i; }