Permalänk
Medlem

Hjälp med simpel python kod.

Jag har kört fast och suttit och stirrat på koden en stund nu och förstår inte riktigt varför det blir fel. Tänkte kanske någon kan peka på var felet skulle kunna vara.

Funktionen på koden:
STEG 1:
Är att den först ska kontrollera om talet (fyrsiffrigt) finns i ett binärt sökträd, gör den det ska den bara gå vidare till den hittar ett tal som inte gör det.
STEG 2:
Här ska den ta den gissningen och se till så att alla siffrorna i talet är unika tex 1023 (inte 1030).
STEG 3:
När den hittat ett tal som uppfyller båda talen ska den helt enkelt returnera detta tal. OBS! Här är felet någonstans.

Koden ser ut enligt följande:

def nygissning(gissning): while tree.exists(gissning): gissning = gissning + 1 print "Gissningen", gissning, "finns redan i tradet" else: tree.insert(gissning) s_giss = [int(i) for i in str(gissning)] print "GISSNING", gissning for i in range(0,3): k = 3 print "-----","i=",i,"-----" while k>i: print "nuvarande gissning:", gissning, "Varv:", k if s_giss[i] == s_giss[k]: s_giss = [int(i) for i in str(gissning)] print "Gissningen",gissning, "har inte unika siffror" gissning = gissning + 1 nygissning(gissning) print else: k = k - 1 if i == 2: print "--- NU HAR JAG HITTAT EN GISSNING ---" return gissning

Utrskriften:

My guess is 1029
Your answer is:

Gissningen 1030 finns redan i tradet
GISSNING 1030
----- i= 0 -----
nuvarande gissning: 1030 Varv: 3
nuvarande gissning: 1030 Varv: 2
nuvarande gissning: 1030 Varv: 1
----- i= 1 -----
nuvarande gissning: 1030 Varv: 3
Gissningen 1030 har inte unika siffror
GISSNING 1031
----- i= 0 -----
nuvarande gissning: 1031 Varv: 3
Gissningen 1031 har inte unika siffror
GISSNING 1032
----- i= 0 -----
nuvarande gissning: 1032 Varv: 3
nuvarande gissning: 1032 Varv: 2
nuvarande gissning: 1032 Varv: 1
----- i= 1 -----
nuvarande gissning: 1032 Varv: 3
nuvarande gissning: 1032 Varv: 2
----- i= 2 -----
nuvarande gissning: 1032 Varv: 3
--- NU HAR JAG HITTAT EN GISSNING ---

----- i= 1 -----
nuvarande gissning: 1032 Varv: 3
nuvarande gissning: 1032 Varv: 2
----- i= 2 -----
nuvarande gissning: 1032 Varv: 3
--- NU HAR JAG HITTAT EN GISSNING ---

----- i= 2 -----
nuvarande gissning: 1031 Varv: 3
--- NU HAR JAG HITTAT EN GISSNING ---
Slutgiltig gissning: 1031

Till problemet:
Problemet är att den inte stannar där jag har satt "return gissning" utan den fortsätter och vad jag inte är varför den börjar på varv 1 och inte 0 igen i for satsen? Hur ska jag lyckas få den att stanna och returnera, i detta fall, 1032 som den hittar?

Tack på förhand // Patrik

Permalänk
Medlem

Kan du inte sätt ett argument i whileloopen, eller sätta k så du avbryter whileloopen, sen retunera?

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem
Skrivet av NoPaiN^:

Kan du inte sätt ett argument i whileloopen, eller sätta k så du avbryter whileloopen, sen retunera?

Min uppfattning var att man med "return" ska avbryta funktionen och returnera men när den inte gjorde det la jag till argumenten att då i == 2, alltså när den gått igenom hela talet. Kollat att alla siffror är unika så är den ju klar så då vill jag bara ha ut det värdet. Förstår alltså inte riktigt hur jag ska kunna lägga till ett till argument? Förslag på argument?

Permalänk
Medlem

När du vet att alla siffrorna är unika, kan du tex sätta k = -1 och avbryta loopen?
Varför vill du retunera?
Vill du inte lägga in det unika talet i trädet?
Eller hänger jag inte med vad du är ute efter.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem

Men while satsen ska avbrytas automatiskt är tanken genom "while k>i", alltså när den gjort sista möjliga jämförelse. Alltså: för talet 1023 jämför det sista talet i for satsen(i = 2 => talet[2] = 2) med från while satsen k=3 => talet[3]. Den kan inte gå ett varv till här för att då är inte k>i.

Svårt att förklara och kan tänka mig att det är svårare att försöka hjälpa till men jag tycker det verkar som att det är fel i for satsen för den börjar om på ett nytt varv med en gammal gissning.

Eftersom det är en funktion vill jag returnera gissningen, detta program är bara en liten del i ett större program och därför behöver jag kunna använda programmet som nygissning(gissning).

Du har rätt i att jag vill lägga in det unika talet i trädet iofs, tanken med trädet är bara att jag inte ska få upp en gammal gissning.

Permalänk
Medlem

Bryt ut checken där du kollar om alla nummer är unika till en egen funktion. Då blir koden både lättare att felsöka och mer lättläst.

if unikt_nummer(gissning): return gissning else: nygissning(gissning+1)

Permalänk
Medlem

Kan du inte göra så här typ:

Gör en separat "metod/funktion" som enbart kollar om talet är unikt.
Använd två whileloopar med en "boolean" och index typ while x!=3 and avbryt!=1: och en för den andra whileloopen då
Så fort du får en träff sätt avbryt till 1 och avsluta looparna.
Retunera avbryt.
Gör en whileloop som anropar din "kolla om talet är unikt" metod.
När du får värdet 1 så vet du att värdet är unikt, lägg in talet i trädet?

Hoppas du förstår hur jag menar, kan hända jag är fredagstrött på jobbet

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem

Jag skulle tro att det beror på den rekursion som du gör. När du genomför det rekursiva anropet med ett nytt nummer körs den instansen till dess att den antingen utför en ny rekursion eller returnerar. När den första returen sker kommer de tidigare instanserna av rekursionen rulla vidare och det är förmodligen inte det du vill. Jag har aldrig programmerat python men det du troligtivs behöver göra efter det rekursiva anropet och blankradsprinten måste få stopp på while och for looparna.

Visa signatur

ASUS ROG Strix X570-F, AMD Ryzen 9 5900X, ASUS GTX 1080 Ti Strix Gaming OC, 32GB G.Skill Trident Z Neo CL16 3600MHz, Arctic Freezer II 240, Seasonic Prime Titanium 850W, Phanteks Enthoo Evolv X, 2x Samsung 970 EVO Plus 1TB, Seagate Firecuda 2TB, Seagate Ironwolf 4TB, ASUS PG278Q

ASUS ROG Crosshair VI Hero, AMD Ryzen 9 3900X, ASUS RTX 2060 Dual OC, 16GB G.Skill Flare X CL14 3200 MHz @3200 MHz, Arctic Freezer 240, Seasonic Prime Titanium 850W, Phanteks Eclipse P400S Glass, Samsung 960 Pro 512GB, Samsung 850 Pro 512GB, Seagate Ironwolf 4TB, ASUS PG278Q

ASUS Maximus V GENE, Intel i7 3770K @ 4,6 GHz (1.190 V), EVGA GTX 670 FTW SLi, 8GB G.Skill TridentX CL10 2400 MHz, Samsung 850 Pro 512GB, Samsung 840 Pro 256GB, Corsair Hydro H100i, Corsair AX860i, Fractal Design Define R4W, ASUS PG278Q

Permalänk
Medlem

Som KeyPakt skrev så är det rekursionen som ställer till det för dig. Din for-loop för att kolla om alla element i en lista är unika är extremt krånglig. Du skulle kunna slänga in elementen i ett set istället och kolla om längden på settet blir samma som längden på listan. len(s_guess) == len(set(s_guess))