Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • itky210x-kurssit/itky2102tp8
  • malmente/itky2121tp7
  • kylmsama/itky2121tp7
3 results
Show changes
Commits on Source (14)
*.db
\ No newline at end of file
# ITKY2121 työpaja 7, tietokannat
# ITKY2102 työpaja 8, tietokannat
Tässä koodivarastossa on neljä tiedostoa:
## Koodivaraston sisältö
Tässä koodivarastossa on ainakin seitsemän tiedostoa:
- README.md, jota luet tällä hetkellä
- data.json, jossa on tarvittava mallidata sovelluksen toimimiseksi
- alusta.py, joka käydään läpi ja ajetaan vain kerran, tietokannan luomiseksi ja asuttamiseksi
- tyopaja.py, jota makustellaan enemmän
- erkaavio.pdf, jossa löytyy data.jsonin rakenne ER-kaaviolla
mallinnettuna
- .GITIGNORE, jota käytetään lisävarmistuksena estämään tietokannan
lisääminen varastoon
- kulku.txt, joka toimii opettajille muistikkaana, miten ja milloin
työpaja on suunniteltu pidettäväksi
Aiemmilta vuosilta voi olla vanhaa dataa ynnä muita.
## Järjestelmävaatimukset
Koodi on testattu toimivaksi GNU/Linux-jakelussa käyttäen Pythonin
versiota 3.12.2. Työpajassa käytettäneen Windows 11 -ympäristöä.
Todennäköisesti vaatii toimiakseen vain Python 3 -jakelun, jossa
paketit json ja sqlite3 sekä f-stringit tuettuna (3.6+).
import json
import sqlite3
with open("data.json") as f:
with open("data.json", encoding="utf-8") as f:
data = json.load(f)
# alustetaan tietokantayhteys ja -kursori
# alustetaan tietokantayhteys ja -kursori
con = sqlite3.connect("tietokanta.db")
cur = con.cursor()
......@@ -19,10 +19,13 @@ for paiva in data["MenusForDays"]:
if len(ruoka['Components']) != 0:
# yhdistetään ruokavaihtoehdon eri komponentit
ruokastring = ' '.join(ruoka['Components'])
# EI näin, SQL injection:
#stmt = f"INSERT INTO ateria (paiva, ruoka) VALUES({pvm}, {ruokastring})"
#cur.execute(stmt)
cur.execute("INSERT INTO ateria (paiva, ruoka) VALUES(?, ?)", (pvm, ruokastring))
con.commit()
# luodaan myös tykkäyksille oma taulu
cur.execute("CREATE TABLE tykkaykset(id integer primary key, ruokaid)")
cur.execute("CREATE TABLE tykkaykset(id integer primary key, ruokaid integer)")
con.commit()
con.close()
{
"RestaurantName": "Ravintola Maija",
"RestaurantUrl": "https://www.semma.fi/ravintolat2/mattilanniemi/maija/",
"RestaurantName": null,
"RestaurantUrl": "https://www.semma.fi/ravintolat/mattilanniemi/ravintola-maija/",
"PriceHeader": null,
"Footer": "Vegaaninen ja gluteeniton vaihtoehto saatavilla päivittäin! Kysy lisätietoja henkilökunnaltamme.\nHyvää ruokahalua!",
"Footer": null,
"MenusForDays": [
{
"Date": "2024-02-26T00:00:00+00:00",
"LunchTime": "10.30-15.00",
"Date": "2025-03-24T00:00:00+00:00",
"LunchTime": "10:30–14:30",
"SetMenus": [
{
"SortOrder": 0,
"SortOrder": 9,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Punajuurikroketteja (*, G, ILM, L, M, Veg)",
"Harissa-jogurttikastiketta (*, A, G, ILM, L)"
"Tomaattista paprikapataa ✈️ (*, A, G, ILM, L, VS)"
]
},
{
"SortOrder": 0,
"SortOrder": 32,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Juustoista juuressosekeittoa (*, A, G, ILM, L)"]
"Price": "2,95 /6,30 /8,60",
"Components": [
"Juustoista riistakeittoa (A, G, L)"
]
},
{
"SortOrder": 0,
"SortOrder": 33,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Jauhelihakebakoita (A, L, M)",
"Ruohosipuli-jogurttikastiketta (*, A, G, ILM, L)"
"Unkarilaista gulassia ✈️ (*, G, L, M, VS)"
]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
"SortOrder": 34,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Rapeita kalapuikkoja\n (*, A, L, M)",
"Tillijogurttia\n (*, A, G, ILM, L)",
"Perunamuusia (*, A, G, ILM, L)"
]
}
]
},
{
"Date": "2024-02-27T00:00:00+00:00",
"LunchTime": "10.30-15.00",
"Date": "2025-03-25T00:00:00+00:00",
"LunchTime": "10:30–14:30",
"SetMenus": [
{
"SortOrder": 0,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"SortOrder": 18,
"Name": "LOUNAS",
"Price": "5,60 / 9,30/9,80",
"Components": [
"Kasvis-soijapapu-nuudelivuokaa (*, A, ILM, L, M, Veg)"
"Pelti Sushi (A, G, L, M) ✈️ ()"
]
},
{
"SortOrder": 0,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"SortOrder": 27,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Uunimakkara sipuli-juustotäytteellä (A, G, L)",
"Perunasosetta (*, A, G, ILM, L)"
"Pinaattiohukaisia (A, G, ILM, L, M, Veg)",
"Pinaattiohukaisia (*, A, ILM, L)",
"Puolukkahilloa (G, L, M, Veg)"
]
},
{
"SortOrder": 0,
"SortOrder": 32,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Meksikolaista chorizo-kasviskeittoa (*, A, G, L, M, VS)"
"Ramen keitto (A, G, L, M) ✈️ ()"
]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
"SortOrder": 34,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Jauheliha-perunasoselaatikkoa (*, A, G, L, M)"
]
}
]
},
{
"Date": "2024-02-28T00:00:00+00:00",
"LunchTime": "10.30-15.00",
"Date": "2025-03-26T00:00:00+00:00",
"LunchTime": "10:30–14:30",
"SetMenus": [
{
"SortOrder": 0,
"SortOrder": 27,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Feta-pinaatti-cashewpähkinäpizzaa (A, VL)"]
"Price": "2,95 /6,30 /8,60",
"Components": [
"Kasvis- couscoustäytettä ✈️ (A, ILM, L)",
"Täysjyvävehnätortillaa ✈️ (A, L, M, Veg)"
]
},
{
"SortOrder": 0,
"SortOrder": 29,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Tonnikalakastiketta (*, A, ILM, L)",
"Luomutäysjyväkierrepastaa (*, A, ILM, L, M, Veg)"
"Pekonilla ja sipulilla täytettyä uunimakkaraa (A, G, L)",
"Perunamuusia (*, A, G, ILM, L)"
]
},
{
"SortOrder": 0,
"SortOrder": 32,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Mausteista broileri-currykeittoa (*, A, G, ILM, L, M)"
"Kalkkuna-kasviskeittoa (*, A, G, ILM, L)"
]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
"SortOrder": 33,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Couscousia ja kasviksia ✈️ (A, L, M)",
"Broileri tagine ✈️ (*, A, G, L, M, VS)"
]
}
]
},
{
"Date": "2024-02-29T00:00:00+00:00",
"LunchTime": "10.30-15.00",
"Date": "2025-03-27T00:00:00+00:00",
"LunchTime": "10:30–14:30",
"SetMenus": [
{
"SortOrder": 0,
"SortOrder": 19,
"Name": "LOUNAS",
"Price": "5,60 / 9,30 /9,80",
"Components": [
"Taco Fried Chicken (A, G, L, M)",
"Soijalla maustettua limemajoneesia (A, G, ILM, L, M)"
]
},
{
"SortOrder": 27,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Paputacoja ja smetanaa (A, L, VS)"]
"Price": "2,95 /6,30 /8,60",
"Components": [
"Tofu Adobo (A, G, L, M, Veg) ✈️ ()"
]
},
{
"SortOrder": 0,
"SortOrder": 29,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Jauheliha-makaronilaatikkoa (*, A, L)"]
"Price": "2,95 /6,30 /8,60",
"Components": [
"Adobong Manok (A, G, L, M) ✈️ ()"
]
},
{
"SortOrder": 0,
"SortOrder": 32,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Aasialaista lohi-seitikeittoa (*, A, G, ILM, L, M)"]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
"Price": "2,95 /6,30 /8,60",
"Components": [
"Perinteistä kalakeittoa (*, A, G, ILM, L)"
]
}
]
},
{
"Date": "2024-03-01T00:00:00+00:00",
"LunchTime": "10.30-14.30",
"Date": "2025-03-28T00:00:00+00:00",
"LunchTime": "10:3014:30",
"SetMenus": [
{
"SortOrder": 0,
"SortOrder": 9,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Soijapala Butter (*, A, ILM, L, Veg, VS)"]
"Price": "2,95 /6,30 /8,60",
"Components": [
"Kasvismoussakaa ✈️ (A, ILM, L, M, Veg)"
]
},
{
"SortOrder": 0,
"SortOrder": 21,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Burgundin broileripataa (*, A, G, ILM, L, M, VS)"]
"Price": "2,95 /6,30 /8,60",
"Components": [
"Gyros -perjantai ✈️ ()"
]
},
{
"SortOrder": 0,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Juustoista riistakeittoa (A, G, L)"]
"SortOrder": 29,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Stifado ✈️ (*, A, G, L, M, VS)"
]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
"SortOrder": 32,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,60",
"Components": [
"Täyteläistä broilerikeittoa\n (*, A, G, ILM, L)"
]
}
]
},
{
"Date": "2024-03-02T00:00:00+00:00",
"Date": "2025-03-29T00:00:00+00:00",
"LunchTime": null,
"SetMenus": []
},
{
"Date": "2024-03-03T00:00:00+00:00",
"Date": "2025-03-30T00:00:00+00:00",
"LunchTime": null,
"SetMenus": []
}
],
"ErrorText": null
}
}
\ No newline at end of file
{
"RestaurantName": "Ravintola Maija",
"RestaurantUrl": "https://www.semma.fi/ravintolat2/mattilanniemi/maija/",
"PriceHeader": null,
"Footer": "Vegaaninen ja gluteeniton vaihtoehto saatavilla päivittäin! Kysy lisätietoja henkilökunnaltamme.\nHyvää ruokahalua!",
"MenusForDays": [
{
"Date": "2024-02-26T00:00:00+00:00",
"LunchTime": "10.30-15.00",
"SetMenus": [
{
"SortOrder": 0,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": [
"Punajuurikroketteja (*, G, ILM, L, M, Veg)",
"Harissa-jogurttikastiketta (*, A, G, ILM, L)"
]
},
{
"SortOrder": 0,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Juustoista juuressosekeittoa (*, A, G, ILM, L)"]
},
{
"SortOrder": 0,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": [
"Jauhelihakebakoita (A, L, M)",
"Ruohosipuli-jogurttikastiketta (*, A, G, ILM, L)"
]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
}
]
},
{
"Date": "2024-02-27T00:00:00+00:00",
"LunchTime": "10.30-15.00",
"SetMenus": [
{
"SortOrder": 0,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": [
"Kasvis-soijapapu-nuudelivuokaa (*, A, ILM, L, M, Veg)"
]
},
{
"SortOrder": 0,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": [
"Uunimakkara sipuli-juustotäytteellä (A, G, L)",
"Perunasosetta (*, A, G, ILM, L)"
]
},
{
"SortOrder": 0,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": [
"Meksikolaista chorizo-kasviskeittoa (*, A, G, L, M, VS)"
]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
}
]
},
{
"Date": "2024-02-28T00:00:00+00:00",
"LunchTime": "10.30-15.00",
"SetMenus": [
{
"SortOrder": 0,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Feta-pinaatti-cashewpähkinäpizzaa (A, VL)"]
},
{
"SortOrder": 0,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": [
"Tonnikalakastiketta (*, A, ILM, L)",
"Luomutäysjyväkierrepastaa (*, A, ILM, L, M, Veg)"
]
},
{
"SortOrder": 0,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": [
"Mausteista broileri-currykeittoa (*, A, G, ILM, L, M)"
]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
}
]
},
{
"Date": "2024-02-29T00:00:00+00:00",
"LunchTime": "10.30-15.00",
"SetMenus": [
{
"SortOrder": 0,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Paputacoja ja smetanaa (A, L, VS)"]
},
{
"SortOrder": 0,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Jauheliha-makaronilaatikkoa (*, A, L)"]
},
{
"SortOrder": 0,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Aasialaista lohi-seitikeittoa (*, A, G, ILM, L, M)"]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
}
]
},
{
"Date": "2024-03-01T00:00:00+00:00",
"LunchTime": "10.30-14.30",
"SetMenus": [
{
"SortOrder": 0,
"Name": "KASVISLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Soijapala Butter (*, A, ILM, L, Veg, VS)"]
},
{
"SortOrder": 0,
"Name": "LOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Burgundin broileripataa (*, A, G, ILM, L, M, VS)"]
},
{
"SortOrder": 0,
"Name": "KEITTOLOUNAS",
"Price": "2,95 /6,30 /8,40",
"Components": ["Juustoista riistakeittoa (A, G, L)"]
},
{
"SortOrder": 0,
"Name": "JÄLKIRUOKA",
"Price": "1,20",
"Components": []
}
]
},
{
"Date": "2024-03-02T00:00:00+00:00",
"LunchTime": null,
"SetMenus": []
},
{
"Date": "2024-03-03T00:00:00+00:00",
"LunchTime": null,
"SetMenus": []
}
],
"ErrorText": null
}
File added
Opettajalle muistiinpanot työpajan kulusta
Keväällä 2024 pituus 3h, edeltävänä työpajana React/frontend Semman datalla
Työpajassa tehdään minimaalinen backend ruokalistasovellukselle
Fiiliskierros
Lyhyt alustus tietokannoista
Semma-datan selitys JSONina ja ER-kaaviona
alusta.py selitys ja ajo
Selataan luotua tietokantaa SQLite Browserilla hetki
Tauko sopii tähän
Käydään läpi tyopaja.py, ajetaan ja varmistutaan toiminnasta
Esitellään kurssit, joilla asiaa käydään (TIEP116 ja ITKA2004)
Esitellään kahvikamera, jossa myös backend
Kannustetaan kokeilemaan itse
3h työpajassa loppuaika käytetään opiskelun haasteiden pohtimiseen ja keskusteluun luokan edessä
Loppukierros
Työpaja vaatii:
-tuoreen Pythonin (f-stringit pitää olla tuettu) (voi ladata Microsoft Storesta)
-SQLite Browserin (voi ladata portablena MyTempiin
TODO:
lisää interaktiivisuutta
saisiko tarvittaessa mahtumaan 2h?
datat suoraan Semmalta? tarvitsee requests-kirjaston
import sqlite3
# alustetaan tietokantayhteys ja -kursori
con = sqlite3.connect("tietokanta.db")
cur = con.cursor()
def tykkaa(id, cur):
cur.execute("INSERT INTO tykkaykset (ruokaid) VALUES (?)", (id,))
con.commit()
def haetykkaykset(id, cur):
res = cur.execute("SELECT COUNT(*) FROM tykkaykset WHERE ruokaid = (?)", (id,))
# data saadaan taas ännikössä
return res.fetchone()[0]
# haetaan tietoja
pvm = '2025-03-24'
#TODO: päivämäärän interpoloiminen lausekkeeseen
paivanruuat = cur.execute("SELECT id, ruoka FROM ateria WHERE paiva LIKE '2025-03-24%'").fetchall()
# [(5, "Pelti Sushi"), (6, "Pinaattiohukaisia"), (7, "Ramenkeitto"), ...]
while True:
valid_ids = []
for ruokatuple in paivanruuat:
# data saadaan änniköissä (engl. tuple)
id = ruokatuple[0]
valid_ids.append(id)
ruoka = ruokatuple[1]
#print(id)
print(f"[{str(id)}] {ruoka}")
print(f"Tykkäyksiä: {str(haetykkaykset(id, cur))}")
tulos = input("Kirjoita q poistuaksesi tai ruuan id tykätäksesi:\n")
if(tulos == "q"):
break
try:
tulos = int(tulos)
except ValueError:
tulos = -1
if(tulos in valid_ids):
tykkaa(tulos, cur)
else:
print("syöte ei ollut validi!")
# lopuksi
con.close()