Loopen i loopen
Hela tabellen på en gång
I Den kända loopen byggde du multiplikationstabellen för ett tal. Vill du ha hela tabellen, alla tal från 1 till 10, kan du köra programmet tio gånger och skriva in ett nytt tal varje gång.
Eller så låter du en loop sköta även det. En loop får nämligen innehålla en annan loop, och det är den enda kod du behöver så fort något ska göras för varje kombination av två saker: varje kolumn i varje rad, varje spelare mot varje motståndare, varje ruta på en spelplan.
En loop inuti en loop
Den yttre loopen bestämmer vilket tal tabellen gäller, den inre skriver ut tabellens tio rader:
Redo.
Läs det inifrån och ut. För varje varv i den yttre loopen körs hela den inre från början till slut. Tio yttre varv gånger tio inre varv blir hundra rader, och det här kallas en Nästlad loop En loop inuti en annan loop. För varje varv i den yttre loopen körs hela den inre från början till slut. Används när något ska göras för varje kombination av två saker, till exempel varje ruta i varje rad. .
Den tomma print() längst ned lägger in en blankrad mellan tabellerna. Lägg märke till var den står: i den yttre loopen, inte i den inre. Flytta in den fyra mellanslag och kör igen, så får du en blankrad efter varje rad i stället för efter varje tabell. Python klagar inte, båda varianterna är korrekt syntax. Det är alltså indraget som avgör vilken loop en rad tillhör, och det är också där felen sitter.
Rutnätet, en rad i taget
Nästlade loopar används sällan bara för att skriva ut fler rader. Den vanligaste formen är ett rutnät, där den yttre loopen räknar raderna och den inre räknar kolumnerna i en rad:
Redo.
Kör koden: tre rader med fem tecken i varje. Den inre loopen skriver inte ut något alls, den bygger upp raden i variabeln rad_text, ett tecken i taget med +=. Först när den inre loopen är klar skrivs raden ut, och det är därför print(rad_text) ligger i den yttre loopen.
Två saker är värda att testa. Flytta print(rad_text) in i den inre loopen och kör: nu får du femton utskrifter, en per tecken, eftersom raden skrivs ut medan den fortfarande byggs. Flytta sedan tillbaka den och ta i stället bort raden rad_text = "" ur den yttre loopen genom att lägga den överst i filen. Varje ny rad fortsätter då på den förra, för variabeln nollställs aldrig. Nollställningen hör hemma i den yttre loopen, en gång per rad.
Uppgift: Turneringen
Skapa filen turnering.py. I en turnering ska varje spelare möta varje annan spelare exakt en gång, och programmet skriver ut spelschemat.
Spelarna har inga namn än, bara nummer. Det räcker: range() ger dig numren.
Fråga efter antalet spelare och gör om svaret till ett heltal.
Skriv en yttre loop över spelarna och en inre loop över deras motståndare. Skriv ut en rad per match, till exempel
Match: spelare 1 mot spelare 2.Ingen ska möta sig själv, och samma par ska inte dyka upp två gånger. Att spelare 2 möter 3 och att 3 möter 2 är samma match. Var den inre loopen börjar räkna är det som avgör båda sakerna.
Kontrollera mot tabellen. Stämmer inte antalet är det nästan alltid startpunkten i den inre loopen som är fel.
| Antal spelare | Antal matcher |
|---|---|
2 | 1 |
4 | 6 |
5 | 10 |
- Gå till Source Control-panelen i VS Code, stagea filen, skriv ett meningsfullt commit-meddelande och pusha.
Vad händer om
Låt den inre loopen börja på 1 i stället, alltså på den första spelaren. Hur många matcher får du med fyra spelare, och vilka av de nya raderna är matcher som redan stod i listan?
Motivera & reflektera
Motivera var din inre loop börjar räkna. Hur vet du att varje par kommer med exakt en gång, utan att räkna raderna för hand?
Nästa nivå
Trianglarna. En triangel där två sidor är a och b med en 60-graders vinkel mellan dem har en tredje sida c som uppfyller c² = a² + b² - a·b. Ibland blir c ett helt tal, oftast inte.
Skriv ett program som frågar efter ett tal N och räknar hur många sådana trianglar det finns där alla tre sidorna är heltal och där a och b är högst N. Använd två loopar och en räknare. Kvadratroten hämtar du med math.sqrt() från Slump & moduler, och c är ett helt tal om c == int(c).
| N | Antal trianglar |
|---|---|
10 | 12 |
100 | 170 |
Får du 14 respektive 240 räknar du varje triangel två gånger, en gång som a, b och en gång som b, a. Det avgörs av var din inre loop börjar räkna.
Uppgiften är en omskrivning av en övning från Programmeringsolympiaden.