Göm meny

Temauppgift 2


I temauppgift 2 ska ni konstruera er egen algoritm som placerar ut grafiska element enligt en specifik heuristik.

Allmänt

Uppgifter: Brons, Silver, Guld

  • Alla uppgifter göras av alla på bronsnivå.
  • För att få Silver på temauppgiften måste du göra alla brons- och silver-delar
  • För att få Guld på temauppgiften måste du göra alla brons-, silver- och guld-delar

Se även examination för information om hur brons, silver och guld påverkar moment- och kursbetyg.

Kodstandard

Er kod ska följa standarderna PEP 8 och PEP 257. Kontrollera detta genom att köra koden genom pep8 och pep257 programmen. pep8 finns installerad för alla, men ni behöver skapa en virtuell miljö (virtualenv) och installera pep257.

Redovisning och komplettering

Uppgiften redovisas på schemalagt redovisningstillfälle. Vid redovisningen visar ni att er kod fungerar korrekt, att den går igenom kontroll för PEP8 och PEP257 samt att ni förstår den kod ni skrivit.

  • Efter redovisningen kommer handledaren bedömma hur väl varje enskild gruppmedlem uppnått kunskapsmålen kopplade till denna uppgift (se ovan).
  • Varje pargrupp har en begränsad tid (ca 10 minuter) att redovisa och diskutera med handledaren.

Anvisad komplettering

Vid behov kommer er redovisningshandledare anvisa om att ni ska lämna in komplettering enligt kompletteringsinstruktionerna ovan. Inga kompletteringar kommer kunna göras under själva redovisningstiden.

Komplettering vid missat redovisningstillfälle

Missat redovisningstillfälle kompletteras genom att skicka in en screencast där ni demonstrerar ovanstående. Screencastkomplettering kan skickas in individuellt eller som par.

Komplettering upp till Silver eller Guld

Om man fått brons och vill få silver eller guld, eller om man fått silver och vill få guld, så kommer ett specifikt tillfälle för kompletteringsredovisningar för att få Silver eller Guld på temauppgiften kommer att hållas i slutet av kursen.

Lärandemål vid redovisning

Precis som alla uppgifter i kursen är det inte att lösa uppgiften i sig som är målet. Uppgiften är konstruerad för att hjälpa er behärska mer generella färdigheter och begrepp och det är dessa som kommer att bockas av vid redovisning.

Lärandemål: Brons

  • kunna ta fram en egen algoritm för att placera ut en given sekvens fyrkanter av identiska dimensioner på en given yta på ett sätt som följer en given strategi
  • kunna implementera ovan nämnda algoritm i python
  • kunna att kunna använda beskrivande variabelnamn i programkod
  • kunna beskriva egenskriven kod på olika nivåer (t.ex. “den här raden lägger till ett element till listan”, jmf med “den här loopen används för att hitta antalet element som har samma värde som variablen söksträng

Lärandemål: Silver

  • kunna att använda variabler istället för hårdkodade värden i kod för att underlätta både underhåll och utveckling
  • kunna dela upp en funktion i flera mindre funktioner och redogöra för hur de används tillsammans

Lärandemål: Guld

  • förmåga att själv ta fram och implementera en algoritm för att placera ut en given sekvens fyrkanter med olika dimensioner på en given yta givet en strategi
  • kunna implementera ovan nämnda algoritm i python
  • förmågan att formulera bra funktionskommentarer med korrekt abstraktionsnivå som dokumenterar hur funktioner ska användas.

Uppgift

I denna uppgift ska ni skapa en algoritm som får in en lista med tkinter.Label-objekt, samt höjd och bredd på den tkinter.Frame som de placeras ut i. tkinter.Label-objekten ska placeras ut i sekvens, utan att de nuddar varandra. Varje fyrkant ska synas helt och hållet.

OBS! Kontrollera vilken algoritmvariant ni ska implementera. Olika grupper ska implementera olika varianter. Se slutet av sidan.

Kodskelett

När ni ska börja koda hittar ni de filer som hör till labben i ~729G75/kursmaterial/tema2/temauppgift2/. Ett exempel på en algoritm som placerar ut fyrkanterna slumpmässigt hittar ni i random-layout.py. I den ser ni hur en instans av klassen temauppgift2.LayoutTester skapas och får layoutfunktionen som ett argument.

OBS! Läs denna fil och testkör den för att orientera er i kodupplägget.

Ni testkör den med:

$ python3 random-layout.py

Koden till uppgiftens grafiska gränssnitt hittar ni i filen temauppgift2.py. Ni behöver inte ändra i den filen, men titta gärna i den för exempel på hur man kan strukturera kod för grafiska gränssnitt, samt om ni vill se hur och var layoutfunktionen används.

Utplacering av fyrkanterna (tkinter.Label-objekt)

square.place(x=100, y=50)

I ovanstående exempel refererar variabeln square till en tkinter.Label-instans. I exemplet används metoden .place() med de namngivna argumenten x och y för att placera ut instansen 100 enheter från den vänstra kanten och 50 enheter från den övre kanten. Placeringen av en Label mäts från dess övre vänstra hörn. Origo i koordinatsystemet som används ligger alltså högst upp till vänster, med en y-axel som pekar nedåt, och en x-axel som pekar åt höger.

Ni ska inte använda funktionalitet från geometri-hanteraren Place (som t.ex. anchor), utan fyrkanterna ska placeras ut endast med .place(x=xpos, y=ypos).

Fyrkanternas storlek

För att ta reda på hur hög en tkinter-widget är, kan man använda sig av metoden .winfo_height(). För bredden använder man .winfo_width.

# spara fyrkantens höjd och bredd
square_width = square.winfo_height()
square_height = square.winfo_width()

I ovanstående kod är square ett tkinter.Label-objekt.

Argument till layout-funktionen

Er algoritm implementerar ni genom att skriva en funktion som tar in nedanstående argument:

  • squares: Lista som innehåller tkinter.Label-objekt
  • frame_height: Höjden (int) på den Frame som fyrkanterna ligger i.
  • frame_width: Bredden (int) på den Frame som fyrkanterna ligger i.
  • start_left: Värdet True betyder att fyrkanterna ska placeras ut från vänster sida. Värdet False betyder att fyrkanterna ska placeras ut från höger (default: True).
  • start_top: Värdet True betyder att fyrkanterna ska börja placeras ut uppifrån. Värdet False betyder att fyrkanterna ska placeras ut från botten (default: True).

Funktionen skickar ni sedan till den gränssnittsinstans som skapas (se koden i random_layout.py som ni kan utgå ifrån).

När man trycker på knappen i gränssnittet körs skapas fyrkanterna som ska layoutas enligt inställningarna i gränssnittet, sen anropas den layoutfunktion som angavs när gränssnittet när det skapades.

I det funktionsanropet skickar gränssnittet med listan med fyrkanter, höjd och bredd som ni har att jobba med, samt information från checkboxarna i gränssnittet som berättar i vilket hörn er layout-algoritm ska börja.

Brons-del

För att få Brons på temauppgiften ska algoritmen fungera när alla Label-objekt (fyrkanterna) i den givna listan har samma storlek.

Storleken på fyrkanterna kan dock variera mellan olika listor av fyrkanter (dvs att en lista kan innehålla fyrkanter som är 30x30 stora, medan en annan lista kan innehålla fyrkanter som är 60x60 stora, alla alternativ utom random i gränssnittet).

exempel på layout på brons-nivå

Krav på kommentarer i koden för Brons

  1. Inga variabelnamn får bestå av endast en enskild bokstav.
  2. Alla satser som består av fler än en rad ska ha en tillhörande kommentar. Dvs if-satser, loopar, funktioner och metoder. Kommentaren ska inte vara en “innantilläsning” av koden den hör till. Använd rätt kommentarsmarkering (t.ex. """ för funktions- metodkommentarer, # för kommentarer i löpande kod, se PEP8 och PEP257).

Här är icke-godkänd kod:

y = 0
g = 0

# för alla element i listan, lägg till x till y
for x in [19, 21, 24, 20]:
    y += x
g = y/len(x)

Här är en godkänd variant

summa = 0
genomsnittsålder = 0

# räkna ut summan av alla åldrar
for ålder in [19, 21, 24, 20]:
    summa += ålder
genomsnittsålder = summa/len(åldrar)

Ett undantag är där x och y används för x- och y-koordinater. Använder ni olika x- och y-koordinater bör ni dock markera detta:

Ej godkänd kod

x = 100
y = 0
hjältinna.set_position(x, y)
x = 500
y = 0
monster.set_position(x, y)

Godkänd kod

x = 100
y = 0
hjältinna.set_position(x, y)

monsterx = 500
monstery = 0
monster.set_position(monsterx, monstery)

Silver-del

För att att få Silver på denna uppgift ställs ska er kod även uppfylla följande kriterier:

  • Minimera användningen av hårdkodade siffror, använd istället variabler med förklarande namn.
  • Dela upp er kod i delfunktioner vid behov:
    • när ni stöter på kod som ni upprepar, bryt ut koden (lägg koden i en funktion)
    • skicka nödvändig information som argument till funktionen och låt den returnera eventuellt resultat, använd inte globala variabler
    • dela även upp er kod i fler funktioner när den blir för lång

Variabler istället för hårdkodade värden

Som tumregel kan tänka att om ni använder samma siffra på fler än ett ställe i samma syfte, så ska ni ersätta den med en variabel.

En annan anledning att byta ut en hårdkodad siffra mot en variabel är för att enklare kunna experimentera med olika värden genom att ändra variabelvärden som samlats på ett smidigt ställe i koden.

Om att bryta ut funktioner

Som tumregler, försöka se till att era funktioner

  • endast gör en sak
  • inte är längre än 15 rader (gärna kortare) exklusive kommentarer

Exempel på kod som ej får silver

kontosaldo = 2000
att_betala = 500 - (500 * 0.1)
att_betala += 240 - (240 * 0.1)
kontosaldo -= att_betala

Kod som får silver

kontosaldo = 2000
pris_godis = 500
pris_godispåse = 240
rabatt = 0.1
att_betala = pris_godis - (pris_godis * rabatt)
att_betala -= pris_godispåse - (pris_godispåse * rabatt)
kontosaldo -= att_betala

Guld-del

För att få Guld ska algoritmen även fungera för listor som innehåller innehåller fyrkanter av blandad storlek, dvs när man använder alternativet random på fyrkantsstorlek i gränssnittet.

Fyrkanterna ska placeras så att de är centrerade i tänkta rader och kolumner (se bilden nedan).

Era funktionskommentarer ska följa PEP257 och vara på den nivån att de inte beskriver explicita implementationsdetaljer.

En bra funktionskommentar består av en kärnfull mening på en rad, som beskriver resultatet av att använda funktionen och vad den returnerar om den gör det. Vid behov beskrivs funktionens argument på efterföljande rader i funktionskommentaren.

exempel på layout på guld-nivå

Grupptilldelning av algoritmvarianter

Det finns tre olika algoritmvarianter i temauppgift 2. Vilken variant ni ska implementera beror på ert gruppnummer (se gruppindelningen).

Grupp 1: row_layout

Döp er huvudfunktion till row_layout.

row_layout-algoritmen ska placera ut fyrkanterna radvis. Om inga andra argument anges, placeras den första fyrkanten ut i det översta vänstra hörnet. Nästa fyrkant läggs till höger om den första med ett visst mellanrum mellan dem. Algoritmen fortsätter så tills inga fler får plats på den raden. Nästa fyrkant som placeras ut ska ligga under den första fyrkanten, d.v.s. på nästa rad.

Om argumentet start_left är False, ska den första fyrkanten läggas i det högra hörnet istället för det vänstra. Nästa läggs till vänster om den.

Om argumentet start_top är False, ska den första fyrkanten läggas längst ner. Nästa rad är ovanför den första.

row_layout

Grupp 2: column_layout

Döp er huvudfunktion till column_layout.

column_layout-algoritmen ska placera ut fyrkanterna kolumnvis. Om inga andra argument anges, placeras den första fyrkanten ut i det översta vänstra hörnet. Nästa fyrkant läggs nedanför den första med ett visst mellanrum mellan dem. Algoritmen fortsätter så tills inga fler får plats i den kolumnen. Nästa fyrkant som placeras ut ska ligga till höger om den första, d.v.s. i nästa kolumn.

Om argumentet start_left är False, ska den första fyrkanten läggas i det högra hörnet istället för det vänstra. Nästa kolumn ligger till vänster om den.

Om argumentet start_top är False, ska den första fyrkanten läggas längst ner. Nästa fyrkant placeras då ovanför den första.

column_layout

Grupp 3: zigzag_layout

Döp er huvudfunktion till zigzag_layout.

zigzag_layout-algoritmen ska placera ut fyrkanterna radvis, men när den kommer till slutet av en rad ändras riktningen som raderna läggs ut i. Om inga andra argument anges, placeras den första fyrkanten ut i det översta vänstra hörnet. Nästa fyrkant läggs till höger om den första med ett visst mellanrum mellan dem. Algoritmen fortsätter så tills inga fler får plats i den kolumnen. Nästa fyrkant som placeras ut ska ligga under den sista fyrkanten på föregående rad. Resterande fyrkanter på denna rad läggs ut från höger till vänster. Nästa rad läggs ut från vänster till höger osv.

Om argumentet start_left är False, ska den första fyrkanten läggas i det högra hörnet istället för det vänstra. Fyrkanterna på den första raden läggs ut från höger till vänster.

zigzag-layouten ignorerar värdet i start_top och börjar alltid uppifrån.

zigzag_layout

Tips!

Fundera på hur ni ska angripa problemet:

  • Vad för information behöver ni för att kunna räkna ut vilken X- och Y-position som ni ska placera varje enskild fyrkant på.
  • Hur kan ni ta fram den informationen?
  • Testa er strategi på papper först innan ni börjar programmera för att se om den fungerar.
  • Innan ni börjar koda, läs igenom exempelkoden (se avsnittet kodskelett ovan).
  • Skriv ner er algoritm som kommentarer i er fil så att ni kan referera till dem när ni programmerar.

Bilder från lektionen hittar ni under lektionssidan.


Sidansvarig: Jody Foo
Senast uppdaterad: 2018-03-15