{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Kennsluefni þetta var samið af Valborgu Sturludóttur og er gefið út undir leyfi CC 3.0, heimilt er að afrita, nota, deila og vinna áfram með efnið ef vísað er í höfund, óheimilt er að hagnast á efninu. \n", "Kennsluefni þetta fylgir bókinni Python fyrir byrjendur - inngangur að forritun sem kom út í fyrstu útgáfu í ágúst 2022. \n", "Þetta er fyrsta útgáfan af þessari verkefnabók, gefin út í ágúst 2022." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Gagnavinnsla\n", "\n", "Í þessari vinnubók kynnumst við því að vinna með mismunandi gögn, laga til gögn og sýna gögn.\n", "\n", "Gagnavinnsla er gríðarlega mikilvæg í hinum tæknivædda heimi. Í dag til aragrúi gagna, til þess að eitthvað vitrænt fáist úr þeim þarf sérfræðinga.\n", "Það sem við ætlum að gera í þessari vinnubók er fyrst að skoða lista af listum sem geyma fyrir okkur gögn sem virðast vera ótengd en við ætlum að draga fram mikilvægustu hlutana svo að þau séu augljósari og auðveldari að vinna með.\n", "\n", "Næsta sem við ætlum að gera er að sækja gögn upp úr listanum okkar eftir inntaki frá notanda.\n", "\n", "Við viljum fá að vinna með gögn sem eru raunveruleg, því ætlum við að sækja gögn yfir netið og skoða þau.\n", "\n", "Að síðustu ætlum við að skoða kóðasafnið matplotlib til þess að sýna þessi gögn okkar einhvern veginn myndrænt." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Búum til gögn til að vinna með\n", "\n", "Við viljum kunna að búa til eitthvað til að gera prófanir á.\n", "Hér er gagnalisti sem er mjög sérkennilegur, öll gögnin eru alveg eins.\n", "\n", "Öll gögnin eru sem sagt endurtekning á hausnum og við þurfum að laga það." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gagnalisti = [\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"],\n", " [\"auðkenni\", \"nafn\", \"skóstærð\", \"fjöldi skópara\", \"hæð\", \"hárlengd\", \"augnlitur\", \"símanúmer\", \"ofnæmi\"]\n", "]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "import random\n", "from pprint import pprint # fyrir fallegri útprentun, þessu má sleppa, en það er notað seinna í vinnubókinni\n", "\n", "# Hér er grunnurinn að handahófskenndinni, \n", "nofn = [\"Anna\", \"Bjarni\", \"Charlie\", \"Dagbjört\", \"Emil\", \"Friðrik\", \"Gréta\", \"Halldóra\", \"Ingvi\", \"Ísabella\", \"Jökull\", \"Kolbeinn\", \"Lísa\", \"Magnús\", \"Númi\", \"Oktavía\", \"Ólavía\", \"Pétur\", \"Rúnar\", \"Stefanía\", \"Trausti\", \"Una\", \"Úlla\", \"Viktoría\", \"Yngvi\", \"Þór\", \"Ævar\", \"Örlygur\"]\n", "augu = [\"blár\", \"grænn\", \"grár\", \"brúnn\", \"ljós\", \"blágrár\", \"grænbrúnn\"]\n", "simi = [\"6\", \"7\", \"8\"]\n", "ofnaemi = [\"já\", \"nei\"]\n", "\n", "# Við viljum setja inn gögn í allar línur nema hausinn, þess vegna byrjum við í 1 en ekki 0\n", "for i in range(1,len(gagnalisti)):\n", " gagnalisti[i][0] = i\n", " gagnalisti[i][1] = nofn[i-1]\n", " gagnalisti[i][2] = random.randint(35, 45)\n", " gagnalisti[i][3] = random.randint(1, 50)\n", " gagnalisti[i][4] = str(1.5 + (2.1-1.5)*random.random())[0:4]\n", " gagnalisti[i][5] = int(random.uniform(0, 100))\n", " gagnalisti[i][6] = random.choice(augu)\n", " gagnalisti[i][7] = random.choice(simi) + str(random.randint(100000, 999999))\n", " gagnalisti[i][8] = random.choice(ofnaemi)\n", " \n", "pprint(gagnalisti)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Það vantar gögn!\n", "\n", "Við sjáum nú að fólkið í listanum hefur ekkert eftirnafn.\n", "\n", "Þetta má bæta með for-lykkju og insert aðferðinni á lista.\n", "\n", "Búið fyrst til lista sem þið getið sótt eða búið til eftirnöfn úr til að setja handahófskennd eftirnöfn á fólkið okkar.\n", "\n", "Eftirfarandi er beinagrind til að koma ykkur af stað:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "eftirnofn = [??]\n", "\n", "for ?? in ??:\n", " # hér er verið að troða inn nýju staki í listann, fyrsta viðfangið er sætisnúmer staksins í gagnalistanum \n", " # hitt viðfangið er stakið sem á að setja inn\n", " gagnalisti[??].insert(??, ??)\n", " \n", "pprint(gagnalisti)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Of mikið af gögnum!\n", "\n", "Kemur í ljós að við megum alls ekki geyma viðkvæmar upplýsingar um heilsufar fólks (ofnæmi), eitthvað um að gagnagrunnurinn okkar uppfyllir ekki næga öryggisstaðla svo við verðum að henda þeim upplýsingum.\n", "\n", "Við þurfum að henda dálkinum úr hausnum líka, til þess að uppfylla kröfur um persónuvernd.\n", "\n", "Þetta má gera með for-lykkju og remove aðferðinni eða pop aðferðinni" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for ?? in ??:\n", " gagnalisti[??].pop(??)\n", " \n", "pprint(gagnalisti)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Tilbúið til notkunar\n", "\n", "Gagnasafnið okkar er tilbúið og við bjóðum upp á að fletta upp í gagnasafninu okkar, það er hægt að gera með ýmsum hætti en við skulum byrja á að bjóða notandanum að velja einhvern dálk til að skoða.\n", "\n", "Við viljum beita input skipun og vera viss um að inntakið passi við það sem við búumst við því annars fáum við villu.\n", "Við viljum halda áfram að spyrja sömu spurningarinn á meðan við höfum ekki fengið svar sem passar." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "osk = input(\"Hvaða gögn viltu sjá? auðkenni, nafn, skóstærð, fjöldi skópara, hæð, hárlengd, augnlitur, símanúmer, ofnæmi \")\n", "while (?? in gagnalisti[0]):\n", " print('vinsamlegst skrifaðu eitt af eftirfarandi')\n", " osk = ??\n", "visir = gagnalisti[0].index(osk)\n", "for stak in gagnalisti:\n", " print(stak[??])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Þá erum við tilbúin fyrir raunheiminn\n", "\n", "Alvöru gögn sem fundust á netinu! Við erum hér með í höndunum skrá, sem inniheldur gögn um dýr aðskilin með kommu (*comma separated values* eða CSV).\n", "\n", "Þetta eru tölulegar staðreyndir um hin ýmsu dýr sem við ætlum að skoða, þetta skjal er gagnagrunnur fyrir stokkaspil. Spilið má nálgast á sama stað og grunninn en við ætlum ekki að fara að spila, við ætlum að skoða gögnin.\n", "\n", "Skoðið gögnin hérna" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Töfrar\n", "\n", "Hér koma smá töfrar. Við sjáum hérna eina leið til þess að lesa gögn upp úr .csv skjali. Gögnin eru fengin með fyrirspurn (e. request) á slóðina, svo eru þau lesin á máta sem við getum notað upp úr fyrirspurninni og þá síðast búum við til orðabók fyrir hverja línu í skjalinu.\n", "Í skjalinu var haus og við notum hausinn sem lykla í orðabókinni.\n", "\n", "Keyrið næstu sellu til að sjá hvernig gögnin líta núna út í Python týpu, annað en hrá textagögn úr hlekknum að ofan." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Ef gögnin spillast eða týnast, keyrið þá þessa sellu aftur\n", "import csv\n", "import requests\n", "\n", "url = 'https://raw.githubusercontent.com/valborg/statimals-deck-game/147ab658b2ad7e8d3cae9f8f71bff84a000dc345/gagnasafn.csv'\n", "r = requests.get(url)\n", "textinn = r.iter_lines(decode_unicode=True)\n", "lesari = csv.DictReader(textinn, delimiter=',')\n", "dyra_baekur = list(lesari)\n", "\n", "DYR_TIL_AD_PRENTA = 2\n", "pprint(dyra_baekur[DYR_TIL_AD_PRENTA])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Hvað viljum við gera?\n", "\n", "Nú er ekkert vandamál í raun sem þarf að leysa en við getum búið okkur til ansi fjöldbreytt verkefni.\n", "\n", "Sjáið hvort þið getið:\n", "
  • Náð í þyngsta dýrið - svarið er Steypireyðurin
  • \n", "
  • Náð í hversu mörg dýr eignast 1 og aðeins 1 afkvæmi - svarið er 22
  • \n", "
  • Náð í hversu mörg dýr geta eignast fleiri en 10 afkvæmi (1-20 telst með t.d.) - svarið er 26
  • \n", "
  • Náð í léttasta dýrið og þyngd þess - svarið er stóra húsflugan 0,000002 kg.
  • \n", "\n", "Og svo margt fleira, prófið ykkur áfram." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Sella til að gera prófanir á gagnaverkefnunum" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nú viljum við teikna!\n", "\n", "Þá þurfum við annað kóðasafn, sem við ætlum að skoða almennilega en ekki bara kynna sem töfra og tala ekkert meira um.\n", "\n", "Matplotlib, það sem við ætlum að gera við matplotlib er að láta það teikna fyrir okkur einhverjar upplýsingar um dýrasafnið okkar.\n", "\n", "Byrjum á skýru verkefni, teikna stöplarit sem sýnir hversu mörg dýr eru í fyrifram ákveðnum þyngdarflokkum.\n", "Hljómar nógu einfalt en við verðum að vinna með gögnin því þau eru skv íslenskum staðli og ekki hægt að vinna með þau beint, og við þurfum að finna leið til þess að komast að því hvað eru mörg dýr í hverjum flokki." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", "# Skiptum í fimm þyngdarhópa og gerum hérna lista sem heldur utan um fjöldann í hverjum hópi\n", "fjoldi_dyra = [0,0,0,0,0]\n", "\n", "# til að endurtaka ekki sama kóðann aftur\n", "# Hér eru þyngdarflokkarnir skilgreindir\n", "# Fallið skilar hvaða flokki dýrið tilheyrir og þá er hægt að hækka töluna í þeim flokki\n", "# Hér má að sjálfsögðu endurskoða skiptinguna og fjöldann, það þarf þá að passa við listann að ofan.\n", "def flokka_dyr(thyngd):\n", " if(thyngd <= 1):\n", " return 0\n", " elif(1 < thyngd <= 5 ):\n", " return 1\n", " elif(5 < thyngd <= 50):\n", " return 2\n", " elif(50 < thyngd <= 500):\n", " return 3\n", " elif(500 < thyngd):\n", " return 4\n", " \n", "# Hvert fer dýr sem er 2 - 6 kíló? Tökum bara meðaltalið\n", "for dyr in dyra_baekur:\n", " # svona gáum við hvort við erum með min max dýr eða meðaldýr, getum ekki gert float('') \n", " if(dyr['Þyngd min'] != ''):\n", " # mismunandi staðlar fyrir . og kommur \n", " dyr['Þyngd min'] = dyr['Þyngd min'].replace('.','')\n", " dyr['Þyngd max'] = dyr['Þyngd max'].replace('.','')\n", " # viljum ekki lenda í villu með að kasta milli taga, í enskum staðli eru . á milli fleytitalna en , í íslenskum\n", " minni = float(dyr['Þyngd min'].replace(',','.')) \n", " meiri = float(dyr['Þyngd max'].replace(',','.')) \n", " medalthyngd = ( minni + meiri )/2\n", " flokkur = flokka_dyr(medalthyngd)\n", " fjoldi_dyra[flokkur] += 1 #hér bætum við dýrinu í réttan flokk í listanum fyrir dýr með min max þyng\n", " \n", " # ef við förum hér inn erum við með meðaldýr, sem hefur bara eina tölu skráða\n", " else:\n", " dyr['Þyngd avg'] = dyr['Þyngd avg'].replace('.','')\n", " medalthyngd = float(dyr['Þyngd avg'].replace(',','.'))\n", " flokkur = flokka_dyr(medalthyngd)\n", " fjoldi_dyra[flokkur] += 1 #hér bætum við dýrinu í réttan flokk í listanum fyrir avg þyngdar dýr\n", " data_check[dyr['Nafn Dýrs']] = (flokkur, medalthyngd)\n", "# Til að merkja x ásinn\n", "labels = ['Undir 1 kg', '1 - 5 kg', '5 - 50 kg', '50 - 500 kg', '500+ kg']\n", "\n", "width = 0.5 # breiddin á stöplunum\n", "\n", "fig, ax = plt.subplots() # hér gerast töfrar, við fáum tvo hluti til baka frá subplots() aðferðinni \n", "\n", "ax.bar(labels, fjoldi_dyra, width, label='Þyngd dýra') # hér er sett inn hvað á að vera hvar eins og bar() aðferðin vill\n", "ax.set_ylabel('Fjöldi') # nafnið á y ásnum\n", "ax.set_title('Fjöldi dýra í hverjum þyngdarhóp') # Nafnið á merkimiðanum inni í myndinni stillt\n", "ax.legend() # Setja inn merkimiðann\n", "\n", "plt.show() # myndin svo sýnd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Höldum áfram !\n", "Takið nú þennan sama kóða, afritið í nýja sellu og klárið eftirfarandi verkefni:\n", " \n", "Komist að því hver skiptingin er á milli einhverra líftímaflokka, lengdarflokka, afkvæmafjöldaflokka og fótafjöldaflokka." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Sella fyrir líftímateikningu, hér er komin beinagrind að skiptingu í flokka\n", "\n", "fjoldi_dyra = [0,0,0,0,0,0]\n", "\n", "def flokka_dyr(liftimi):\n", " if(liftimi <= 1):\n", " return 0\n", " elif(1 < liftimi <= 5 ):\n", " return 1\n", " elif(5 < liftimi <= 15):\n", " return 2\n", " elif(15 < liftimi <= 30):\n", " return 3\n", " elif(30 < liftimi <= 50):\n", " return 4\n", " elif(50 < liftimi):\n", " return 5" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Sella fyrir lengdarteikningu, hér er komin beinagrind að skiptingu í flokka\n", "\n", "fjoldi_dyra = [0,0,0,0,0,0,0]\n", "\n", "def flokka_dyr(lengd):\n", " if(lengd <= 0.01):\n", " return ??\n", " elif(0.01 < lengd <= 0.1 ):\n", " return ??\n", " elif(0.1 < lengd <= 1.0):\n", " return ??\n", " elif(1.0 < lengd <= 2.0):\n", " return ??\n", " elif(2.0 < lengd <= 3.0):\n", " return ??\n", " elif(3.0 < lengd <= 5.0):\n", " return ??\n", " elif(5.0 < lengd ):\n", " return ??" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "# Sella fyrir afkvæmafjöldateikningu, hér er komin beinagrind að skiptingu í flokka\n", "\n", "fjoldi_dyra = [0,0,0,0,??]\n", "\n", "def flokka_dyr(afkv):\n", " if(afkv <= ??):\n", " return ??\n", " elif(?? < afkv <= ??):\n", " return ??\n", " elif(?? < afkv <= ??):\n", " return ??\n", " elif(?? < afkv <= ??):\n", " return ??\n", " # fleiri flokka? Ath að fjoldi_dyra listinn þarf að passa" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Sella fyrir fótafjöldateikningar, hér er hugmynd að sleppa flokkun með falli \n", "# Þess í stað að nota bara fjöldann sem sætisnúmer í listanum \n", "# Þá verða nokkrir stöplar 0 að hæð því engin dýr eru með 3 fætur eða 5\n", "# Takið sérstaklega á tilfellinu fleiri en 10 fætur samt því að annars verður afríska risafætlan ykkur til ama\n", "\n", "fjoldi_dyra = [0,0,0,0,0,0,0,0,0,0,0,0]\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.3" } }, "nbformat": 4, "nbformat_minor": 4 }