Din egen chattbot - Marvin - steg 2
Programmering och problemlösning i Python. Strukturera koden i egna funktioner.
Nu ska ni strukturerar upp er Marvinkod i fler filer och funktioner.
#Förkunskaper
Du kan grunderna i Pythons stränghantering och du har gjort den första delen av Marvin.
#Krav
Ni får inte använda listor för att lösa uppgifterna.
Taggarna för varje uppgift motsvarar själva menyvalet. För att testa Menyval 9 kan man då använda --tags=9
, för Menyval b1 --tags=b1
osv.
Kopiera din Marvin från föregående kursmoment och utgå från den koden.
# Flytta till kurskatalogen cd me cp -ri kmom02/marvin1/marvin.py kmom03/marvin2/ cd kmom03/marvin2
Byt namn filen
marvin.py
tillmain.py
och skapa filenmarvin1.py
.main.py
ska innehålla koden för att starta ditt program och while-loopen som som utgör menyn. Skapa funktionenmain
och lägg all kod som var i filen imain()
funktionen. Din main fil skall sedan kalla påmain
funktion i blocket för villkoretif __name__ == "__main__"
som du lägger längst ner imain.py
.Koden för dina menyval ska nu flyttas till olika funktioner i
marvin1.py
. Med “koden för menyval” menas koden som utgör funktionaliteten för ett menyval, t.ex.elif choice == "1": # koden mellan kommentarerna här. Start name = input("What is your name? ") print("\nMarvin says:\n") print(f"Hello {name} - your awesomeness!") print("What can I do you for?!") # Slut elif choice == "2":
Importera
marvin1.py
imain.py
och strukturera om koden för de gamla menyvalen så att de läggs i en varsin funktion, med nedanstående namn. Dessa funktionerna har idbwebb test
utöver sitt menyval som tag också “marvin1” som tag.- Menyval 1 -
greet
- Menyval 2 -
celsius_to_fahrenheit
- Menyval 3 -
points_to_grade
- Menyval 4 -
sum_and_average
- Menyval 5 -
hyphen_string
- Menyval 6 -
compare_numbers
- Menyval 7 -
validate_ssn
- Menyval 8 -
robber_language
Om du har gjort några av extrauppgifterna från föregående kursmoment så kan du döpa dem till ett valfritt namn.
Till exempel för menyval 1 blir det.
#main.py elif choice == "1": marvin1.greet()
#marvin1.py def greet(): name = input("What is your name? ") print("\nMarvin says:\n") print(f"Hello {name} - your awesomeness!") print("What can I do you for?!")
Alla
input()
ochprint()
som används i menyvalen skall ligga i funktionen för menyvalet och inte i main funktionen.
Det är OK att bryta ut din kod till flera mindre funktioner så länge de används i funktionen som efterfrågas.- Tags:
struct
. Det går att användastruct
som tag idbwebb test kmom03 --tags=struct
för att köra testerna som kollar att man har rätt filer på rätt plats.
- Menyval 1 -
Skapa filen
marvin2.py
. Koden för de nya menyvalen nedanför ska du skriva imarvin2.py
. Importera filen imain.py
.För alla nya menyval ska dina
input
anrop ligga i “main.py” filen och du ska skicka dem som argument till de specifika menyvals funktionerna. Varje input anrop för ett menyval motsvarar ett argument till funktionen. Funktionerna ska också returnera resultatet så att utskriften görs imain.py
. Exempel:... elif choice == "11": string = input("Enter a string to randomize: ") print(randomize_string(string))
Menyval 9 -
create_ssn
: Skapa de fyra sista siffrorna till ett födelsedatum. Skapa ett nytt menyval där Marvin ber om en sträng som innehåller ett födelse datum, t.ex."910813"
. Din funktion ska skap de fyra sista siffrorna till det,"910813-NNNN"
. För att skapa dem, använda random modulen och slumpa fram de tre första siffrorna. Använd sen Luhnalgoritmen för att räkna ut den fjärde. Den funkar nästa på samma sätt som i menyval 7.Algoritmen funkar på så sätt att varannan siffra multipliceras med 2 och 1, med start på första siffran i personnumret. Om något tal vid multiplikationen blir större än 9 ersätts det talet med dess siffersumma. Därefter summeras alla tal och här skiljer sig funktionen från menyval 7. Sista siffran erhålls genom att summan subtraheras från närmaste högre tiotal. Exempel med
811218-987
:8 1 1 2 1 8 9 8 7 * 2 1 2 1 2 1 2 1 2 ------------------------- ^ ^ ^ ^ ^ ^ ^ ^ 16 1 2 2 2 8 18 8 14
Vilket blir
1 + 6 + 1 + 2 + 2 + 2 + 8 + 1 + 8 + 8 + 1 + 4 = 44
,50 - 44 = 6
. Personnummret blir då811218-9876
.För att subtrahera från närmsta tiotal kan man använda modulu operatorn,
%
.Som du läst finns det funktionalitet som är samma mellan menyval 7 och 9. Därför ska du skapa en ny funktion som används i koden för menyval 7 och 9. Skapa
create_ssn
som tar emot födelsedatumet och skapar tre siffror. Skapa sencalculate_luhna_sum
som tar emot en sträng med födelsedatumet och de tre siffrorna, utan-
,"811218987"
. Funktionen ska räkna ut summan och returnera den,44
. Icreate_ssn
använd summan och räkna ut sist siffran och returnera hela personnummret, med-
,811218-9876
.Uppdatera sen koden för menyval 7 så att du använder
calculate_luhna_sum
i den koden också, för att räkna ut summan som ska kollas om den är delbar med 10. Koll om talet är delbart med 10 i menyval 7 funktionen, inte icalculate_luhna_sum
. Genom att återanvända funktioner på flera ställen kan vi få mer DYR kod.Exempel:
input: "910813" output: "910813-2201".
Eftersom tre siffror slumpas fram kommer ni inte få samma sista som i exemplet. Men om ni använder det i menyval 7 ska det vara ett giltigt personnummer
Menyval 10 -
get_acronym
: Akronymskapare. Marvin ska be om en sträng och skapa en akronym för den genom att plocka ut alla stora bokstäver och sätta ihop till en ny sträng. Tips, isupper(). Exempel:input: "BRöderna Ivarsson Osby" output: "BRIO" input: "Ingvar Kamprad Elmtaryd Agunnaryd" output: "IKEA"
Menyval 11 -
randomize_string
: Kasta om bokstäver. Marvin ska be dig skriva in ett ord som sedan slumpmässigt kastas om. Funktionenrandomize_string
ska bara returnera det nya slumpade ordet, inte ha med<orginal sträng> -->
. Svaret ska sedan skrivas ut i formatet<orginal sträng> --> <slumpad sträng>
, frånmain.py
. Lösningen ska vara case-sensitive, med andra ordA != a
. Tips random modulen.input: "Hej" output: "Hej --> jHe" input: "Borde inte bli samma igen" output: "Borde inte bli samma igen --> eel gn rtm dBmibo saiiane"
Menyval 12 -
find_all_indexes
: Hitta alla index. Marvin ska be om två strängar, där den andra strängen är en del-sträng av den första. Funktionen ska returnera en kommaseparerad sträng med alla indexplatser där den andra strängen finns med i den första. Det ska inte vara ett kommatecken på slutet av strängen. Om strängen som skickas in som andra argument inte finns i första argumentet ska funktionen returnera en tom sträng.Använd sträng funktionen funktionen index() för att hitta indexplatser, notera att
index()
returnerar bara ett index åt gången, så även om en sträng finns med på två ställen returneras bara den första. För att komma runt detta och hitta alla index behöver ni anropaindex()
flera gånger och skicka med ett extra argument,start
.start
markera vilken index position funktionen ska börja leta från. Notera också attindex
funktionen lyfter ettValueError
om en söksträngen inte finns. Ni ska använda er av try-except i er funktion för att förhindra programmet från att krascha när det inträffar.Exempel:
input: "axaaczaa44aa4", "a" output: "0,2,3,6,7,10,11" input: "axaaczaa33aa3", "aa" output: "2,6,10" input: "axaaczaa55aa5", "y" output: ""
Testa, validera och publicera din kod enligt följande.
# Flytta till kurskatalogen dbwebb test marvin2 dbwebb validate marvin2 dbwebb publish marvin2
Rätta eventuella fel som dyker upp och publicera igen. När det ser grönt ut så är du klar.
#Extrauppgift
För att inkludera dina extrauppgifter i testerna behöver du skicka med option -e
eller --extra
.
Menyval b1 -
has_strings
: Gör så Marvin kan ta emot fyra strängar, den första strängen ska jämföras med de andra tre. Kolla om den första strängen börjar med den andra, innehåller den tredje och slutar med den sista. Lösningen ska vara case-sensitive, med andra ordA != a
. Tips, startswith(), endswith() Exempel:input: "anagram" input: "ana" input: "agr" input: "am" output: "Match" input: "isogram" input: "is" input: "gra" input: "m" output: "Match" input: "Palindrom" input: "par" input: "ind" input: "rom" output: "No match"
Menyval b2 -
ssn extended
: I Sverige finns det två juridiska kön, kvinna och man, som registreras för varje individ vid födsel. Det påverkar den näst sista siffran i ens personnummer. Marvin ska kunna generera de 4 sista siffrorna i ett personnummer där tredje siffran i den avslutande delen av personnumret (NNXN) ska anpassas efter könet på personen. Siffran ska fortfarande slumpas men med tilläggskravet att om det är en kvinna ska den tredje siffra vara jämn och om det är en man ska den istället vara udda.
Ändra parameterlistan tillcreate_ssn
så att det förutom födelsedatum (som är första parametern) även har en andra parameter för kön med default-argumentetNone
. Denna parameter har värdet"M"
eller"m"
om födelsedatumet tillhör en man och"K"
eller"k"
om det tillhör en kvinna. Observera att all inmatning sker i main.Exempel:
input: "910813" input: "M" output: "910813-5531". input: "661204" input: "K" output: "661204-9247".
Eftersom tre siffror slumpas fram (med kravet på udda/jämnt beroende på kön för tredje siffran) kommer ni inte få samma sista som i exemplet. Men om ni använder det i menyval 7 ska det vara ett giltigt personnummer
#Tips från coachen
Felsöka med debuggern/Thonny och komplettera med utskrifter av print()
.
Validera ofta. Så slipper du en massa valideringsfel i slutet av övningen.
Lycka till och hojta till i forumet om du behöver hjälp!
#Revision history
- 2023-06-22: (C, aar) FLytta runt på menyval och la till create_ssn.
- 2022-08-26: (B, aar) Delade upp marvin koden i marvin1 och marvin2 moduler.
- 2021-03-30: (A, moc) Ny version för att introducerar automaträttning.