Kört fast i programmeringsuppgift (tips och tricks från den erfarne)

Trädvy Permalänk
Medlem
Plats
Stockholm/Nacka
Registrerad
Aug 2010

Kört fast i programmeringsuppgift (tips och tricks från den erfarne)

Hejsan som rubriken lyder skulle jag behöva lite hjälp!

Som bakgrundsinfo har jag som programmeringsuppgift i Python att göra en "Salladsbar". Uppgiften går ut på att en användare ska skriva in vilka ingredienser hen skulle vilja ha. Dessa ska matchas med en färdiggjord sallad och ifall någon ingrediens inte finns där ska det kompletteras.

Algoritmen ser ut som följande:
1. Information från fil läses in
2. Objekt skapas med relevant information
3. Användarens interaktion jämförs med befintlig info
4. Det objekt med som matchas bäst ska väljas
5. De ingredienser som objektet inte innehåller ska kompletteras och ett pris ska presenteras
6. Ett kvitta ska skrivas ut

Det jag har kört fast i är att jag förstår inte hur jag ska göra en funktion som ska jämföra de färdiggjorda salladerna (objekten).
Just nu läses allting in från filen och objekten läggs in i en lista. Funktionen som ska jämföra den har jag tänkt är tre for loops. Dvs först en loop som går igenom listan. Sen en loop som går igenom attributen (listan med ingredienser), och sen en loop som går igenom den lista som användaren skriver in.

Då ser det ut så här (om jag printar):

Dold text

Det jag tänker är att jag ska ha en metod som ska jämföra varje del och sedan ge ett objekt en poäng om det stämmer. Sen det objekt med flest poäng ska väljas. Men jag har ingen aning om hur en sån metod skulle se ut.

Har ni några tips?

Funktionen och programmet lite mer i helhet ser ut så här

Dold text

In the beginning the universe was created.

This has made a lot of people very angry, and has been widely regarded as a bad move!
- Douglas Adam

Trädvy Permalänk
Medlem
Registrerad
Aug 2005

Skulle tipsa om att titta på sets: https://docs.python.org/2/library/stdtypes.html#set-types-set...

Efter du konverterat ingredienserna till sets kan du enkelt verifiera att en given sallad enbart består av en delmängd av den önskade salladen och sedan plussa på ingredienserna som krävs. Borde likna någonting i stil med:

if given_ingredients.issubset(custom_ingredients):
----added_cost = 0
----for ingredient in custom_sallad.difference(given_ingredients):
--------added_cost += cost_for_ingredient(ingredient)

Trädvy Permalänk
Medlem
Plats
Stockholm/Nacka
Registrerad
Aug 2010

Tack för tipset! Set är tyvärr inget jag känner igen från kursen men förhoppningsvis ska det inte för oförståeligt.

Men när du menar med ingredienser så ska "user input" göras om till en så kallad set? Eller ska objekten i sig också göras om till detta?

Skickades från m.sweclockers.com

In the beginning the universe was created.

This has made a lot of people very angry, and has been widely regarded as a bad move!
- Douglas Adam

Trädvy Permalänk
Medlem
Registrerad
Aug 2005

Att skapa ett set av en lista är ingen konst:

Ta den lista du skapar via split:

>>> ny_sallad = [ 'tomat', 'sallad']
>>> set_ingredienser = set(ny_sallad)
>>> set_ingredienser
{'tomat', 'sallad'}

Jag skulle nog se till att indatan i "ny_sallad"
och "ingredienser" i Sallad objekten är sets.

Detta kommer vara sets med strängar, blandar du in din Ingrediens
klass kan det möjligtvis bli lite förvirrande då strängarna och
objekten kommer anses vara olika saker. Sets fungerar dock fint
med objekt om så önskar.

Notera sen också att Python kommer tycka att strängarna "tomat"
och "Tomater" är olika saker. Skulle rekommendera att du antingen
saniterar indata genom att kolla av emot kända ingredienser eller
helt enkelt kollar av detta själv.

Skulle eventuellt tipsa om att skrota ingrediens klassen och köra
en dictionary (även kallad map i andra språk) för att lagra
priser för ingredienser.

Exempelkod med exempeldata:

Resultat:

Trädvy Permalänk
Medlem
Plats
Stockholm/Nacka
Registrerad
Aug 2010

Oj, tackar bugar för hjälpen! Ska försöka få stil på det du skrev så jag kan få in det i min kod!

In the beginning the universe was created.

This has made a lot of people very angry, and has been widely regarded as a bad move!
- Douglas Adam

Trädvy Permalänk
Forumledare
Registrerad
Okt 2002
Skrivet av chrol:

Som en liten notis så finns det en inbyggd syntax för att definiera sets ("mängder") direkt, utan att gå via en lista (eller annan iterabel):

>>> n = set(['tomat', 'gurka', 'äpple']) >>> # är språkligt ekvivalent med: >>> n = {'tomat', 'gurka', 'äpple'} >>> # Bevis, för den tvivlande: >>> set(['tomat', 'gurka', 'äpple']) == {'tomat', 'gurka', 'äpple'} True

dvs som en dictionary med enbart nycklar (vilket också av en händelse var exakt hur mängder först implementerades i Python).

Letar man mikrooptimeringar är senare varianten snabbare då den undviker att skapa en temporär lista och ett funktionsanrop, till förmån för en inbyggd språkkonstruktion. Framför allt är det dock mindre visuellt brus vilket gör det snabbare att parsa i köttrymden (om man antar att läsaren är insatt i språkets grundkonstruktioner, men kan man inte anta det så är slaget redan förlorat!).

En ledtråd till att detta är fallet får man direkt av Pythons representation vid utskrift av en mängd:

>>> print(set(['tomat', 'gurka', 'äpple'])) {'äpple', 'tomat', 'gurka'}

Representationen av inbyggda Pythontyper är generellt och medvetet gjord så att den ska gå att köra direkt som Python-kod för att få tillbaka objektet i fråga.

(Python 2-serien skriver fortfarande ut set([])-formen för kompatibilitet ner till Python 2.4, även om Python 2.7 stöder den nya literala syntaxen.)

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Trädvy Permalänk
Medlem
Registrerad
Aug 2005

@phz: Bra notis. Helt klart bör man använda den inbyggda syntaxen för sets direkt. Tänkte dock att det kunde vara pedagogiskt att presentera det hela så som jag gjorde.

Skrivet av phz:

om man antar att läsaren är insatt i språkets grundkonstruktioner, men kan man inte anta det så är slaget redan förlorat!

Även om jag håller med dig i det generella fallet så känns det som att det här var ett väldigt rimligt antagande i detta fall i och med att trådskaparen skriver rakt ut att han inte vet vad sets är.

Tar och passar på och lämna ett uppdaterat exempel då jag nu ser att det fanns betydligt bättre sätt att presentera kod på:

class Sallad: def __init__(self, namn, pris, ingredienser): self.namn = namn self.pris = pris self.ingredienser = ingredienser def hitta_sallad(ny_sallad, sallader, ingrediens_kostnader): for sallad in sallader: if sallad.ingredienser.issubset(ny_sallad): extra_kostnad = 0 for ingredient in ny_sallad.difference(sallad.ingredienser): extra_kostnad += ingrediens_kostnader[ingredient] print("Med", sallad.namn, "som bas blir kostnaden", sallad.pris + extra_kostnad) else: print(sallad.namn, " fungerar inte som bas") n = {'tomat','gurka', 'äpple'} s = [ Sallad('Rissallad', 200, {'ris', 'tomat'}), Sallad('Gurktomat', 100, {'gurka', 'tomat'}) ] p = { 'äpple' : 30, 'tomat' : 100, 'gurka' : 10, 'ris' : 500 } hitta_sallad(n,s,p)