From 90327481bc349dbc90ccc7255b7379b993ab997d Mon Sep 17 00:00:00 2001 From: rouhani <majid.rouhani@ntnu.no> Date: Mon, 18 Sep 2023 19:04:00 +0200 Subject: [PATCH] upd --- lectures/chap2/lab/lab-2.zip | Bin 0 -> 11708 bytes lectures/chap2/notes/codes/fl_uke_36.zip | Bin 0 -> 31685 bytes .../chap4/lab/generelt_om_filbehandling.ipynb | 473 ++++++ lectures/chap4/lab/generelt_om_sets.ipynb | 806 ---------- lectures/chap4/lab/lister_og_lokker.ipynb | 41 - lectures/chap4/lab/lister_og_tupler.ipynb | 148 -- .../chap4/notes/codes/data/grunnstoff.txt | 10 + .../chap4/notes/codes/data/nye_grunnstoff.txt | 11 + .../notes/codes/tekstfil_grunnstoff.ipynb | 192 +++ .../innlevering/adams/.DS_Store" | Bin 0 -> 6148 bytes .../adams/intro_til_jupyter.ipynb" | 376 +++++ .../innlevering/adams/lab-1.md" | 14 + .../adams/tall_og_typekonvertering.ipynb" | 1251 ++++++++++++++++ .../innlevering/adams/variabler.ipynb" | 602 ++++++++ .../anastasia/intro_til_jupyter.ipynb" | 370 +++++ .../anastasia/tall_og_typekonvertering.ipynb" | 1101 ++++++++++++++ .../innlevering/anastasia/variabler.ipynb" | 566 ++++++++ .../innlevering/anna/intro_til_jupyter.ipynb" | 370 +++++ .../\303\270ving_1/innlevering/anna/lab-1.md" | 14 + .../anna/tall_og_typekonvertering.ipynb" | 1232 ++++++++++++++++ .../innlevering/anna/variabler.ipynb" | 603 ++++++++ .../audun/intro_til_jupyter.ipynb" | 343 +++++ .../audun/tall_og_typekonvertering.ipynb" | 1013 +++++++++++++ .../innlevering/audun/variabler.ipynb" | 574 ++++++++ .../benjamin/intro_til_jupyter.ipynb" | 370 +++++ .../benjamin/tall_og_typekonvertering.ipynb" | 1205 +++++++++++++++ .../innlevering/benjamin/variabler.ipynb" | 584 ++++++++ .../innlevering/sten/intro_til_jupyter.ipynb" | 335 +++++ .../\303\270ving_1/innlevering/sten/lab-1.md" | 14 + .../sten/tall_og_typekonvertering.ipynb" | 1073 ++++++++++++++ .../innlevering/sten/variabler.ipynb" | 572 ++++++++ .../stud1/intro_til_jupyter.ipynb" | 370 +++++ .../stud1/tall_og_typekonvertering.ipynb" | 1101 ++++++++++++++ .../innlevering/stud1/variabler.ipynb" | 566 ++++++++ .../stud10/intro_til_jupyter.ipynb" | 370 +++++ .../innlevering/stud10/lab-1.md" | 14 + .../stud10/tall_og_typekonvertering.ipynb" | 1291 +++++++++++++++++ .../innlevering/stud10/variabler.ipynb" | 593 ++++++++ .../stud11/intro_til_jupyter.ipynb" | 362 +++++ .../innlevering/stud11/lab-1.md" | 14 + .../stud11/tall_og_typekonvertering.ipynb" | 1092 ++++++++++++++ .../innlevering/stud11/variabler.ipynb" | 616 ++++++++ .../stud12/intro_til_jupyter.ipynb" | 343 +++++ .../innlevering/stud12/lab-1.md" | 14 + .../stud12/tall_og_typekonvertering.ipynb" | 1228 ++++++++++++++++ .../innlevering/stud12/variabler.ipynb" | 549 +++++++ .../stud13/intro_til_jupyter.ipynb" | 370 +++++ .../innlevering/stud13/lab-1.md" | 14 + .../stud13/tall_og_typekonvertering.ipynb" | 1177 +++++++++++++++ .../innlevering/stud13/variabler.ipynb" | 579 ++++++++ .../stud14/intro_til_jupyter.ipynb" | 359 +++++ .../stud14/tall_og_typekonvertering.ipynb" | 1220 ++++++++++++++++ .../innlevering/stud14/variabler.ipynb" | 576 ++++++++ .../stud15/intro_til_jupyter.ipynb" | 335 +++++ .../innlevering/stud15/lab-1.md" | 14 + .../stud15/tall_og_typekonvertering.ipynb" | 1248 ++++++++++++++++ .../innlevering/stud15/variabler.ipynb" | 601 ++++++++ .../stud2/intro_til_jupyter.ipynb" | 374 +++++ .../innlevering/stud2/lab-1.md" | 14 + .../stud2/tall_og_typekonvertering.ipynb" | 1264 ++++++++++++++++ .../innlevering/stud2/variabler.ipynb" | 605 ++++++++ .../stud3/intro_til_jupyter.ipynb" | 370 +++++ .../innlevering/stud3/lab-1.md" | 14 + .../\303\270ving_1/innlevering/stud3/lab.zip" | Bin 0 -> 16284 bytes .../stud3/tall_og_typekonvertering.ipynb" | 1245 ++++++++++++++++ .../innlevering/stud3/variabler.ipynb" | 587 ++++++++ .../stud4/intro_til_jupyter.ipynb" | 370 +++++ .../innlevering/stud4/lab-1.md" | 14 + .../stud4/tall_og_typekonvertering.ipynb" | 1254 ++++++++++++++++ .../innlevering/stud4/variabler.ipynb" | 592 ++++++++ .../stud5/intro_til_jupyter.ipynb" | 405 ++++++ .../innlevering/stud5/lab-1.md" | 14 + .../stud5/tall_og_typekonvertering.ipynb" | 1249 ++++++++++++++++ .../innlevering/stud5/variabler.ipynb" | 531 +++++++ .../stud6/Intro til Jupyter.ipynb" | 341 +++++ .../stud6/Tall og Typekonvertering.ipynb" | 1231 ++++++++++++++++ .../innlevering/stud6/Variabler.ipynb" | 593 ++++++++ .../stud7/intro_til_jupyter.ipynb" | 370 +++++ .../innlevering/stud7/lab-1.md" | 14 + .../stud7/tall_og_typekonvertering.ipynb" | 1212 ++++++++++++++++ .../innlevering/stud7/variabler.ipynb" | 589 ++++++++ .../stud8/aritmetiske_uttrykk.ipynb" | 424 ++++++ .../stud8/intro_til_jupyter.ipynb" | 385 +++++ .../innlevering/stud8/lab-1.md" | 14 + .../stud8/tall_og_typekonvertering.ipynb" | 1257 ++++++++++++++++ .../innlevering/stud8/variabler.ipynb" | 581 ++++++++ .../stud9/intro_til_jupyter.ipynb" | 370 +++++ .../innlevering/stud9/lab-1.md" | 14 + .../stud9/tall_og_typekonvertering.ipynb" | 1190 +++++++++++++++ .../innlevering/stud9/variabler.ipynb" | 582 ++++++++ .../innlevering/zip_for_download.ipynb" | 86 ++ 91 files changed, 46439 insertions(+), 995 deletions(-) create mode 100644 lectures/chap2/lab/lab-2.zip create mode 100644 lectures/chap2/notes/codes/fl_uke_36.zip create mode 100644 lectures/chap4/lab/generelt_om_filbehandling.ipynb delete mode 100644 lectures/chap4/lab/generelt_om_sets.ipynb delete mode 100644 lectures/chap4/lab/lister_og_tupler.ipynb create mode 100644 lectures/chap4/notes/codes/data/grunnstoff.txt create mode 100644 lectures/chap4/notes/codes/data/nye_grunnstoff.txt create mode 100644 lectures/chap4/notes/codes/tekstfil_grunnstoff.ipynb create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/adams/.DS_Store" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/adams/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/adams/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/adams/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/adams/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/anastasia/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/anastasia/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/anastasia/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/anna/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/anna/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/anna/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/anna/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/audun/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/audun/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/audun/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/benjamin/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/benjamin/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/benjamin/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/sten/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/sten/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/sten/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/sten/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud1/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud1/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud1/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud10/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud10/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud10/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud10/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud11/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud11/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud11/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud11/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud12/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud12/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud12/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud12/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud13/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud13/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud13/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud13/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud14/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud14/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud14/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud15/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud15/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud15/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud15/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud2/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud2/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud2/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud2/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud3/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud3/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud3/lab.zip" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud3/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud3/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud4/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud4/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud4/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud4/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud5/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud5/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud5/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud5/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud6/Intro til Jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud6/Tall og Typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud6/Variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud7/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud7/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud7/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud7/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud8/aritmetiske_uttrykk.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud8/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud8/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud8/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud8/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud9/intro_til_jupyter.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud9/lab-1.md" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud9/tall_og_typekonvertering.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/stud9/variabler.ipynb" create mode 100644 "\303\270vinger/\303\270ving_1/innlevering/zip_for_download.ipynb" diff --git a/lectures/chap2/lab/lab-2.zip b/lectures/chap2/lab/lab-2.zip new file mode 100644 index 0000000000000000000000000000000000000000..458923d4a2b7e958d6acd28d7325c5295a598d47 GIT binary patch literal 11708 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 literal 0 HcmV?d00001 diff --git a/lectures/chap2/notes/codes/fl_uke_36.zip b/lectures/chap2/notes/codes/fl_uke_36.zip new file mode 100644 index 0000000000000000000000000000000000000000..ff17bd5f8aeea55999e84c0c816202a2f6dcbf35 GIT binary patch literal 31685 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�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 literal 0 HcmV?d00001 diff --git a/lectures/chap4/lab/generelt_om_filbehandling.ipynb b/lectures/chap4/lab/generelt_om_filbehandling.ipynb new file mode 100644 index 0000000..a561c66 --- /dev/null +++ b/lectures/chap4/lab/generelt_om_filbehandling.ipynb @@ -0,0 +1,473 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Generelt om filbehandling\n", + "\n", + "**Læringsmål:**\n", + "- Filbehandling\n", + "\n", + "I denne oppgaven skal vi skrive til en fil og lese fra en fil." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Generelt om filer\n", + "Det kan være lurt å lese dette før du går videre" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er ofte nyttig å kunne lagre data til en fil, eller lese data fra en fil når man skriver et program i Python. De mest brukte funksjonene er for åpning, redigering og lukking av eksterne filer. \n", + "\n", + "Når du åpner filen må du spesifisere hvordan du skal bruke filen. Det er derfor viktig å åpne filen på riktig måte. Måten dette gjøres på er som inn-parameter i `open()`-funksjonen, noen eksempler er:\n", + "\n", + "- **'r'** - for lesing av filen (default)\n", + "- **'w'** - for skriving til filen\n", + "- **'a'** - for å legge til data (**a**ppend) til den eksisterende filen\n", + "\n", + "I denne oppgaven skal vi bli bedre kjent med hvordan dette fungerer:\n", + "\n", + "- For å åpne en fil i Python kan vi skrive: `f = open('filename', Bruksmåte)`. Bruksmåte er enten `'r'`, `'w'` eller `'a'` avhengig av hva hvordan filen skal brukes.\n", + "- For å lese data fra en fil kan vi bruke: `innhold = f.read()`\n", + "- For å legge til data til en fil kan vi skrive: `f.write(data)`\n", + "\n", + "Filer lukkes på følgende måte: `f.close()`" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "### Lesing av fil" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Eksempelet under viser lesing av en fil. **Kjør koden under og test det ut da vel!**" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er en eksempelfil.\n", + "\n", + "Her kan man skrive hva man vil.\n", + "\n", + "Men helst ikke for mange hatefulle ytringer.\n" + ] + } + ], + "source": [ + "# LESING AV FIL\n", + "f = open('example_file1.txt','r') #r spesifiserer at man skal lese fra en fil\n", + "innhold = f.read()\n", + "print(innhold)\n", + "f.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Når man leser en fil slik som over, må man lagre innholdet i en variabel (her bruker vi `innhold`). **Husk alltid å lukke filen!**\n", + "\n", + "Den filen som ble lest fra finner dere her: [example_file1.txt](example_file1.txt). Prøv å endre på filen, lagre den med `file -> save` i toppmenyen for så å kjøre kodeblokken over på nytt. Kodeblokken burde da skrive ut det nye innholdet i filen!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "### Skriving av fil" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "For å skrive til en fil kan man gjøre slik som under. **Kjør koden under og test!**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "f = open('example_file1.txt','w') #w spesifiserer at filen skal skrives til\n", + "f.write('En hatefull ytring')\n", + "f.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Etter at du har kjørt koden over vil du kunne se at innholdet i [example_file1.txt](example_file1.txt) har endret seg. Hvis du vil kan du bytte ut `'w'` over med `'a'` og se hva som da skjer." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Context managers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Det er generelt foretrukket i python å bruke _context managers_ når man gjør operasjoner som å skrive til og lese fra fil. De tar hånd om lukking av fila når du er ferdig, og passer på å lukke også dersom koden crasher underveis i en operasjon. Da kan vi være trygge på at vi ikke får korrupte filer.\n", + "\n", + "Åpning og lukking av filer med context managere gjøres som følger" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "En hyggelig kommentar\n" + ] + } + ], + "source": [ + "with open('example_file.txt', 'w') as writefile:\n", + " writefile.write(\"En hyggelig kommentar\")\n", + "\n", + "with open('example_file.txt', 'r') as readfile:\n", + " innhold = readfile.read()\n", + " print(innhold)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Man kan også åpne og lukke flere filer i gangen" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "En hyggelig kommentar\n", + "---\n", + "Dette er en eksempelfil.\n", + "\n", + "Her kan man skrive hva man vil.\n", + "\n", + "Men helst ikke for mange hatefulle ytringer.\n" + ] + } + ], + "source": [ + "with open('example_file.txt', 'r') as file_0, open('example_file1.txt', 'r') as file_1:\n", + " innhold_0 = file_0.read()\n", + " innhold_1 = file_1.read()\n", + " print(innhold_0, innhold_1, sep=\"\\n---\\n\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `write_to_file(data)` som tar inn strengen `data` og legger denne inn i en fil **my_file.txt**\n", + "\n", + "***Skriv din kode i kodeblokken under***" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du lurer på om du gjorde riktig kan du kalle på funksjonen og sjekke innholdet i filen her:\n", + "[my_file.txt](my_file.txt)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "#### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Her skal du skrive til fil og må derfor benytte deg av\n", + "\n", + "```python\n", + "f = open('my_file.txt', 'w')\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `read_from_file(filename)` som tar inn strengen `filename` med filnavnet og skriver ut innholdet.\n", + "\n", + "***Skriv koden i kodeblokken under***" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Du kan teste ut funksjonen ved å kalle den med `'my_file.txt'` som argument." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "#### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Her skal du lese fra fil og må derfor benytte deg av\n", + "```python\n", + "f = open('my_file.txt', 'r')\n", + "```" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10.6 64-bit", + "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.10.6" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lectures/chap4/lab/generelt_om_sets.ipynb b/lectures/chap4/lab/generelt_om_sets.ipynb deleted file mode 100644 index 5fcdb99..0000000 --- a/lectures/chap4/lab/generelt_om_sets.ipynb +++ /dev/null @@ -1,806 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "run_control": { - "frozen": true - } - }, - "source": [ - "# Generelt om sets\n", - "\n", - "**Læringsmål:**\n", - "- Sets\n", - "- Lister" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "heading_collapsed": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "## Generelt om sets\n", - "Det kan være lurt å lese gjennom dette før du går videre" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Et set inneholder en samling av unike verdier og fungerer på samme måte som et set i matematikken. Forskjellen på et set og en liste er at en liste kan inneholde flere like elementer, for eksempel:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "liste = [1,2,3,1,2,3]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Altså kan vi finne alle tallene to ganger. Dette går ikke i et set ettersom alle elementene i et set er ulike. Tilsvarende set ser slik ut:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "my_set = set([1,2,3])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "På samme måte som vi kunne opprette en dictionary ved å skrive `my_dict = dict()`, kan vi opprette et set ved å skrive:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "my_set = set()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "For å legge til et element i et set kan vi benytte oss av `add()`. **Husk å kjøre koden over før du kjører koden under**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "my_set.add(1)\n", - "my_set.add(2)\n", - "my_set.add(3)\n", - "my_set.add(3)\n", - "my_set.add(3)\n", - "print(my_set)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "For å legge til flere elementer på samme gang, kan `update()` benyttes." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "For å fjerne et element kan vi benytte oss av `remove()` eller `discard()`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "my_set.remove(2)\n", - "print(my_set)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "De fleste ting fungerer likt mellom sets og lister, og her er noen eksempler:\n", - "- iterering gjennom setet/listen\n", - "- sjekke om et element er i setet/listen\n", - "- finne lengden til setet/listen" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Dersom du har hatt sannsynlighet er du kanskje godt kjent med venndiagram. Da har du sikkert hørt om union og snitt. Dersom vi har to sets" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "set1 = set([1,2,3,4,5,6,7,8])\n", - "set2 = set([0,2,4,6,8,10,12])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "kan vi se at begge setene inneholder 2, 4, 6 og 8. Dette er det som kalles intersection, eller snitt. På figuren under kan vi se at snittet er det feltet hvor sirklene overlapper.\n", - "\n", - "\n", - "\n", - "For å finne snittet av set1 og set2 kan vi skrive som under. **Kjør kun koden under dersom du har kjørt forrige kodeblokk som initialiserer set1 og set2**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "set3 = set1.intersection(set2)\n", - "set3 = set2.intersection(set1)\n", - "set3 = set1&set2\n", - "print(set3)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Alle de tre første linjene i kodeblokken over er ekvivalente.\n", - "\n", - "Union er et annet nyttig ord, og det vil si tallene som enten er i set1 eller set2 eller begge, dvs. alle tallene som er med. For å finne unionen av set1 og set2 kan vi skrive:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "set3 = set1.union(set2)\n", - "set3 = set2.union(set1)\n", - "set3 = set1 | set2\n", - "print(set3)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Her gjør også alle de tre øverste kodelinjene akkurat det samme." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Tallene som er i set1, men ikke i set2, dvs. 1, 3, 5 og 7 kan vi finne ved å skrive" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "set3 = set1.difference(set2)\n", - "set3 = set1-set2 # denne linja og linja over gjør akkurat det samme\n", - "print(set3)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "For å finne elementene som er i set2 men ikke set1 er det bare å bytte om på set1 og set2 i koden over." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Symmetric difference vil si alle tallene som er i set1 eller set2 (dvs. unionen) minus snittet (tallene som er i begge setene). I dette tilfelle er det 0,1,3,5,7,10 og 12.\n", - "\n", - "Dette finner vi slik:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "set3 = set1.symmetric_difference(set2)\n", - "set3 = set2.symmetric_difference(set1)\n", - "set3 = set1^set2 #set3 = (0,1,3,5,7,10,12)\n", - "print(set3)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Her gjør også de tre første linjene akkurat det samme." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "heading_collapsed": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "## a)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Lag et tomt set som heter `my_set`, legg til alle oddetallene opp til 20 i setet ved å bruke en for-løkke og print setet\n", - "\n", - "***Skriv koden i kodeblokken under***" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Har du gjort det riktig skal output være\n", - "```\n", - "{1, 3, 5, 7, 9, 11, 13, 15, 17, 19}\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "heading_collapsed": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "## b)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Lag et nytt set som heter `my_set2` og inneholder alle oddetallene frem til 10.\n", - "\n", - "***Skriv din koden i kodeblokken under***" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Har du gjort det riktig skal kodeblokken under printe `{1, 3, 5, 7, 9}`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "print(my_set2)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "heading_collapsed": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "## c)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Lag et setet `my_set3` som inneholder alle tallene som er i setet fra a) men ikke i setet fra b) \n", - "\n", - "***Skriv koden i kodeblokken under***" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Har du gjort det riktig skal kodeblokken under printe `{11, 13, 15, 17, 19}`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "print(my_set3)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "heading_collapsed": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "## d)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Dersom du tar snittet av setet fra b) og setet fra c), hva forventer du å få da? Hva med a) og c)?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hidden": true - }, - "source": [ - "**Svar:**<dobbeltklikk her\\>" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "heading_collapsed": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "## e)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Bruk de innebygde funksjonene `len()` og `set()` til å lage en funksjon `allUnique(lst)`, som returnerer `True` om listen `lst` inneholder unike elementer og ellers returnerer `False`.\n", - "\n", - "***Skriv koden i kodeblokken under***" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Har du gjort det riktig kan du teste med koden under (etter å ha kjørt din egen kodeblokk)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "print(allUnique([1,3,2,6,8]))\n", - "print(allUnique([1,3,5,2,3,7]))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Output fra denne burde være:\n", - "```python\n", - "True\n", - "False\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "heading_collapsed": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "## f)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Bruk de innebygde funksjonene `list()` og `set()` til å lage en funksjon `removeDuplicates(lst)`, som fjerner duplikater fra listen `lst` og returner den modifiserte listen.\n", - "\n", - "***Skriv koden i kodeblokken under***" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Du kan teste koden din med koden under (etter å ha kjørt din egen kodeblokk)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hidden": true - }, - "outputs": [], - "source": [ - "print(removeDuplicates([1,3,5,2,3,7]))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "hidden": true, - "run_control": { - "frozen": true - } - }, - "source": [ - "Har du gjort alt riktig skal output fra denne være:\n", - "```python\n", - "[1, 2, 3, 5, 7]\n", - "```" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "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.9.10" - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": false, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/lectures/chap4/lab/lister_og_lokker.ipynb b/lectures/chap4/lab/lister_og_lokker.ipynb index 1c3f058..7337dee 100644 --- a/lectures/chap4/lab/lister_og_lokker.ipynb +++ b/lectures/chap4/lab/lister_og_lokker.ipynb @@ -273,47 +273,6 @@ "***Skriv svaret ditt i boksen under.***" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "run_control": { - "frozen": true - } - }, - "source": [ - "### d)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": false, - "editable": false, - "run_control": { - "frozen": true - } - }, - "source": [ - "Lag en ny liste **reversed_list** som inneholder elementene i **number_list** i motsatt rekkefølge. (Merk: uten å bruke innebygde funksjoner i Python)\n", - "\n", - "Dersom du nå printer listen skal du få:\n", - " \n", - "```python\n", - "[98, 99, 96, 97, 94, 95, 92, 93, 90, 91, 88, 89, 86, 87, 84, 85, 82, 83, 80, 81, 78, 79, 76, 77, 74, 75, 72, 73, 70, 71, 68, 69, 66, 67, 64, 65, 62, 63, 60, 61, 58, 59, 56, 57, 54, 55, 52, 53, 50, 51, 48, 49, 46, 47, 44, 45, 42, 43, 40, 41, 38, 39, 36, 37, 34, 35, 32, 33, 30, 31, 28, 29, 26, 27, 24, 25, 22, 23, 20, 21, 18, 19, 16, 17, 14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1]\n", - "```\n", - "\n", - "***Skriv svaret ditt i boksen under.***" - ] - }, { "cell_type": "code", "execution_count": null, diff --git a/lectures/chap4/lab/lister_og_tupler.ipynb b/lectures/chap4/lab/lister_og_tupler.ipynb deleted file mode 100644 index ce10a24..0000000 --- a/lectures/chap4/lab/lister_og_tupler.ipynb +++ /dev/null @@ -1,148 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Lister og tupler\n", - "\n", - "**Læringsmål:**\n", - "\n", - "* Lister\n", - "* Tupler\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Denne oppgaven handler om *muterende* endringer av lister, samt forskjellen mellom tupler og lister. Hovedpoenget med muterende endringer er at dette er endringer, f.eks i en funksjon som skal være permanente *etter* at funksjonen avsluttes. Eksempelet under illustrerer en vanlig fallgruve knyttet til dette:\n", - "\n", - "```python\n", - "lis1 = [1,2,3]\n", - "lis2 = lis1\n", - "lis3 = lis1[:]\n", - "lis1[0] = 2\n", - "print(lis2)\n", - "print(lis3)\n", - " \n", - "Out: [2, 2, 3]\n", - " [1, 2, 3]\n", - "```\n", - "Her peker lis1 og lis2 til *samme* referanse i minnet, og begge vil endres hvis et av objektene endres. lis3 derimot er en (shallow) kopi av originalliste og endres derfor ikke. Hvis vi bruker funksjonen id(), så ser vi at lis1 og lis2 har samme id, men at lis3 har ulik id. \n", - "\n", - "\n", - "Dette er overførbart til et annet type problem. Eksempelvis, hvis man skal fjerne serieduplikater i en liste (tall som kommer rett etter hverandre), kan man skrive følgende kode:\n", - "\n", - "```python\n", - "def fjern_dup(liste):\n", - " ny_liste = [liste[0]] # Oppretter en ny liste hvor første element er det samme som i input\n", - " for tall in liste: # Går gjennom tallene i input-listen\n", - " if tall != ny_liste[-1]: # Hvis tallet ikke er lik det siste elementet i ny_liste\n", - " ny_liste.append(tall) #legg tallet bakerst i den nye listen\n", - " liste[:] = ny_liste # setter liste lik en ny versjon av ny_liste\n", - "\n", - "```\n", - "Merk spesielt tilordningen liste[:]. Dette gjør at liste-variabelen peker til samme sted i minnet *etter* tilordningen, og variabelen blir dermed endret. Hvis vi derimot hadde skrevet \n", - "```python\n", - "liste = ny_liste \n", - "```\n", - "så hadde referansen (id-en) endret seg, altså blitt lagret et nytt sted og hvis vi hadde kalt på liste etter funksjonen hadde kjørt hadde vi ikke sett noen endring i printout. \n", - "\n", - "Dette er nokså intrikat, men hovedbudskapet er å passe på og sette riktig tilordning. Dette kan dere teste i de følgende oppgavene." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### a)\n", - "\n", - "Lag en funksjon som tar inn en liste og fjerner elementene som er høyere enn gjennomsnittet. Merk at dette skal gjelde duplikater også. Eksempelvis skal list = [1,2,3,4,5,5,6,7] remove_larger_than_average(list) gjøre at listen etter funksjonskallet ser slik ut: [1, 2, 3, 4]. Merk at funksjonen ikke skal returnere noe." - ] - }, - { - "cell_type": "code", - "execution_count": 105, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### b) \n", - "\n", - "\n", - "Lag en funksjon som tar inn en liste endrer listen slik at elementet ved siden av det opprinnelige elementet er kvadratet (tallet ^2). F.eks skal input [1,2,3,4] resultere i at listen ser slik ut etter kallet: [1,1,2,4,3,9,4,16]. Merk at funksjonen ikke skal returnere noe." - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 1, 2, 4, 3, 9, 4, 16]\n" - ] - } - ], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Videre er det viktig å være obs på forskjellen mellom lister og tupler. Hovedforskjellen er at tupler er ikke-muterbare, altså at de ikke kan endres når de er opprettet. Du skal nå skrive om funksjonen larger_than_average(liste) slik at denne fungerer *både* for lister og tupler. Du kan nå returnere resultatet, i stedet for å endre inputargumentet slik som i a). I denne oppgaven er det *ikke* lov å konvertere input-argumentet til en liste hvis det er en tuppel." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Hint**: Du kan bruke funksjonen isinstance(argument,type) for å sjekke om et argument er av typen type. Husk også at hvis du skal initialisere en tuppel med ett element, så må du ha komma bak elemenetet, (1,) f.eks " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "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.7.4" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/lectures/chap4/notes/codes/data/grunnstoff.txt b/lectures/chap4/notes/codes/data/grunnstoff.txt new file mode 100644 index 0000000..7a8fdef --- /dev/null +++ b/lectures/chap4/notes/codes/data/grunnstoff.txt @@ -0,0 +1,10 @@ +1 Hydrogen H 1.008 +2 Helium He 4.003 +3 Litium Li 6.939 +4 Beryllium Be 9.012 +5 Bor B 10.811 +6 Karbon C 12.011 +7 Nitrogen N 14.007 +8 Oksygen O 15.998 +9 Fluor F 18.998 +10 Neon Ne 20.183 \ No newline at end of file diff --git a/lectures/chap4/notes/codes/data/nye_grunnstoff.txt b/lectures/chap4/notes/codes/data/nye_grunnstoff.txt new file mode 100644 index 0000000..bd33238 --- /dev/null +++ b/lectures/chap4/notes/codes/data/nye_grunnstoff.txt @@ -0,0 +1,11 @@ +1 Hydrogen H 1.008 +2 Helium He 4.003 +3 Litium Li 6.939 +4 Beryllium Be 9.012 +5 Bor B 10.811 +6 Karbon C 12.011 +7 Nitrogen N 14.007 +8 Oksygen O 15.998 +9 Fluor F 18.998 +10 Neon Ne 20.183 +36 Krypton Kr 83.8 diff --git a/lectures/chap4/notes/codes/tekstfil_grunnstoff.ipynb b/lectures/chap4/notes/codes/tekstfil_grunnstoff.ipynb new file mode 100644 index 0000000..6963fc0 --- /dev/null +++ b/lectures/chap4/notes/codes/tekstfil_grunnstoff.ipynb @@ -0,0 +1,192 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "16ff22ce", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "# Lesing og skriving av tekstfil i Python\n", + "Eksempel her:\n", + "- starter med tekstfil med data om grunnstoff\n", + "- leser data fra fil og lagrer i en liste\n", + "- skriver ut data på skjerm\n", + "- skriver endrer data og skriver tilbake til fil\n", + "\n", + "## Del 1: Lesing fra tekstfil" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "c13dd67c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[]\n" + ] + } + ], + "source": [ + "def les_grunnstoff_fra_fil(filnavn):\n", + " '''Leser tekstfil med data om grunnstoff:\n", + " atomnr navn symbol atomvekt\n", + " returnerer liste med data fra fil på formen:\n", + " [(atomnr, navn, symbol, atomvekt)]\n", + " '''\n", + " data = [] # oppretter tom liste\n", + " with open(filnavn) as fil:\n", + " pass # TO BE DONE, erstatt dette med riktig kode\n", + " ## Plan for resten av koden:\n", + " # Gå i løkke, for hver linje i fila\n", + " # splitt linja\n", + " # konverter atomnr med int()\n", + " # konverter atomvekt med float()\n", + " # lag tuppel (atomnr, navn, symbol, atomvekt)\n", + " # legg til element data[]\n", + " # Returner ferdig data\n", + " return data\n", + "\n", + "# Kode for å teste\n", + "grunnstoff = les_grunnstoff_fra_fil('data/grunnstoff.txt')\n", + "print(grunnstoff)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "6a1e7ea0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(1, 'Hydrogen', 'H', 1.008), (2, 'Helium', 'He', 4.003), (3, 'Litium', 'Li', 6.939), (4, 'Beryllium', 'Be', 9.012), (5, 'Bor', 'B', 10.811), (6, 'Karbon', 'C', 12.011), (7, 'Nitrogen', 'N', 14.007), (8, 'Oksygen', 'O', 15.998), (9, 'Fluor', 'F', 18.998), (10, 'Neon', 'Ne', 20.183)]\n" + ] + } + ], + "source": [ + "def les_grunnstoff_fra_fil(filnavn):\n", + " '''Leser tekstfil med data om grunnstoff:\n", + " atomnr navn symbol atomvekt\n", + " returnerer liste med data fra fil på formen:\n", + " [(atomnr, navn, symbol, atomvekt)]\n", + " '''\n", + " data = [] # oppretter tom liste\n", + " with open(filnavn) as fil:\n", + " for linje in fil:\n", + " liste = linje.split()\n", + " atomnr, navn, symbol, atomvekt = int(liste[0]), liste[1], liste[2], float(liste[3])\n", + " atomvekt = float(liste[3])\n", + " data.append((atomnr,navn,symbol,atomvekt))\n", + " return data\n", + "\n", + "grunnstoff = les_grunnstoff_fra_fil('data/grunnstoff.txt')\n", + "print(grunnstoff)" + ] + }, + { + "cell_type": "markdown", + "id": "df78b994", + "metadata": {}, + "source": [ + "## Del 2: Skrive tekstfil\n", + "Motsatt eksempel:\n", + "- starter med data i en ordbok (dictionary)\n", + "- går gjennom ordboka og skriver til tekstfil\n", + "- (men gidder ikke her å stokke om rekkefølga)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "5b3ed0d3", + "metadata": {}, + "outputs": [], + "source": [ + "def skriv_grunnstoff_til_fil(filnavn, data):\n", + " '''Får inn et filnavn og en liste\n", + " Skriver dataene til tekstfil separert med mellomrom\n", + " med nøkkel som venstre kolonne, resten av verdiene deretter'''\n", + " with open(filnavn, 'w') as fil: # åpner fil for skriving\n", + " pass # TO BE DONE, erstatt dette med riktig kode\n", + " ## Plan for resten av koden:\n", + " # Gå i løkke gjennom ordboka\n", + " # konverter atomnr til str()\n", + " # konverter atomvekt til str()\n", + " # lag lista [symbol, navn, atomnr, atomvekt]\n", + " # join lista med mellomrom\n", + " # skriv linja med \\n bakerst\n", + "\n", + "\n", + "# Kode for å teste\n", + "skriv_grunnstoff_til_fil('data/nye_grunnstoff.txt', grunnstoff)\n", + "# Må deretter se på fila om det har blitt rett" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "df89f911", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "1774ca3c", + "metadata": {}, + "outputs": [], + "source": [ + "def skriv_grunnstoff_til_fil(filnavn, data):\n", + " '''Får inn et filnavn og en liste\n", + " Skriver dataene til tekstfil separert med mellomrom\n", + " med nøkkel som venstre kolonne, resten av verdiene deretter'''\n", + " with open(filnavn, 'w') as fil: # åpner fil for skriving\n", + " for elm in data:\n", + " atomnr = str(elm[0])\n", + " navn = elm[1]\n", + " symbol = elm[2]\n", + " atomvekt = str(elm[3])\n", + " tekstlinje = ' '.join([atomnr, navn, symbol, atomvekt])\n", + " fil.write(tekstlinje + '\\n')\n", + "\n", + "# Legger til et nytt grunnstoff\n", + "grunnstoff.append((36,'Krypton', 'Kr', 83.800))\n", + "# Kode for å teste\n", + "skriv_grunnstoff_til_fil('data/nye_grunnstoff.txt', grunnstoff)\n", + "# Må deretter se på fila om det har blitt rett" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/adams/.DS_Store" "b/\303\270vinger/\303\270ving_1/innlevering/adams/.DS_Store" new file mode 100644 index 0000000000000000000000000000000000000000..2050b4a70160277369ed3fed8e4f8cf1cb364056 GIT binary patch literal 6148 zcmZQzU|@7AO)+F(5MW?n;9!8zOq>i@0Z1N%F(jFwBCH_uz-AaSC@^F)<T2zi<Ur*{ zslgorptuuc@L@<~NMcZ6K#spuhBAg!h9Yo$rl%Aq=OpFlgJYEl<vHnw!O8i#1xS7; zLRW6Si%U{YeiA56F8}sc_<ZnDM+OE4qI9N^sk0yh!=*@$9%YV(z-S1JhQRO)0Y-?o zIJhD7C^;GeqaiRF0`L$3l@AJ#wmpLblx~2~ASnh$1_p2!fRTZL1*VA++z(&?$$_+j zXpmMA4bsZM2x5WF0BdDnglc63cSAt>KwT0L4c5-U2(}r-2Ww|w1l!EOzzEUKzzDUO z5!ypxglK1AglK1A1ltaC-6%a80;3@S3jt;bLjY9&yD~7~>i<Jjjgq4wFd72GG6Wb| zT!LMkz?Cv~|AFdSP<@&Jl?K(ppz4?rR4*gMz*R95WI#~@Dh#UbL0UmHxGH93U;t?y QZ3w^uXp|lefdL2s0M#5sd;kCd literal 0 HcmV?d00001 diff --git "a/\303\270vinger/\303\270ving_1/innlevering/adams/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/adams/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..1273df3 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/adams/intro_til_jupyter.ipynb" @@ -0,0 +1,376 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første program i jupyter\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Vince\n", + "Da er du 30 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første program i jupyter\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow, Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow, Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Vince\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <Programmering er gøy\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "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.11.5 (v3.11.5:cce6ba91b3, Aug 24 2023, 10:50:31) [Clang 13.0.0 (clang-1300.0.29.30)]" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/adams/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/adams/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/adams/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/adams/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/adams/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..8075f90 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/adams/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1251 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a * b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: True\n" + ] + } + ], + "source": [ + "gjort_oving = True\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [5, 6, 7, 8]\n" + ] + } + ], + "source": [ + "liste_med_tall = [5, 6, 7, 8]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n" + ] + }, + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[44], line 12\u001b[0m\n\u001b[1;32m 8\u001b[0m alder_mor \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39m37\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[1;32m 10\u001b[0m sum_alder \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(alder) \u001b[39m+\u001b[39m \u001b[39mint\u001b[39m(alder_mor)\n\u001b[0;32m---> 12\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39;49m\u001b[39mGratulerer, til sammen er dere \u001b[39;49m\u001b[39m'\u001b[39;49m \u001b[39m+\u001b[39;49m sum_alder \u001b[39m+\u001b[39m \u001b[39m'\u001b[39m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n", + "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "def legg_til_landskode (telefonnummer,landskode):\n", + " return \"+\" + str(landskode) + \" \" + str(telefonnummer)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = '1.5'\n", + "e = '2.45'\n", + "\n", + "# Skriv koden din her\n", + "a = int(a)\n", + "b = int(b)\n", + "c = int(c)\n", + "d = int(float(d))\n", + "e = int(float(e))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'liste' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mc:\\Users\\rouhani\\gitlab\\lbas2002-1\\øvinger\\øving_1\\innlevering\\adams\\tall_og_typekonvertering.ipynb Cell 60\u001b[0m line \u001b[0;36m6\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/rouhani/gitlab/lbas2002-1/%C3%B8vinger/%C3%B8ving_1/innlevering/adams/tall_og_typekonvertering.ipynb#Y113sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mmult_list_with_x\u001b[39m(l, x):\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/rouhani/gitlab/lbas2002-1/%C3%B8vinger/%C3%B8ving_1/innlevering/adams/tall_og_typekonvertering.ipynb#Y113sZmlsZQ%3D%3D?line=4'>5</a>\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mlist\u001b[39m(result)\n\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/rouhani/gitlab/lbas2002-1/%C3%B8vinger/%C3%B8ving_1/innlevering/adams/tall_og_typekonvertering.ipynb#Y113sZmlsZQ%3D%3D?line=5'>6</a>\u001b[0m arr1 \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39marray(liste)\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/rouhani/gitlab/lbas2002-1/%C3%B8vinger/%C3%B8ving_1/innlevering/adams/tall_og_typekonvertering.ipynb#Y113sZmlsZQ%3D%3D?line=6'>7</a>\u001b[0m result \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39mmultiply(arr1,skalar)\n", + "\u001b[1;31mNameError\u001b[0m: name 'liste' is not defined" + ] + } + ], + "source": [ + "# Skriv koden din her\n", + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " return list(result)\n", + "arr1 = np.array(liste)\n", + "result = np.multiply(arr1,skalar)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'result' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mc:\\Users\\rouhani\\gitlab\\lbas2002-1\\øvinger\\øving_1\\innlevering\\adams\\tall_og_typekonvertering.ipynb Cell 62\u001b[0m line \u001b[0;36m4\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/rouhani/gitlab/lbas2002-1/%C3%B8vinger/%C3%B8ving_1/innlevering/adams/tall_og_typekonvertering.ipynb#Y115sZmlsZQ%3D%3D?line=0'>1</a>\u001b[0m liste \u001b[39m=\u001b[39m [\u001b[39m1\u001b[39m, \u001b[39m1.5\u001b[39m, \u001b[39m2\u001b[39m, \u001b[39m2.5\u001b[39m, \u001b[39m3\u001b[39m]\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/rouhani/gitlab/lbas2002-1/%C3%B8vinger/%C3%B8ving_1/innlevering/adams/tall_og_typekonvertering.ipynb#Y115sZmlsZQ%3D%3D?line=1'>2</a>\u001b[0m skalar \u001b[39m=\u001b[39m \u001b[39m2\u001b[39m\n\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/rouhani/gitlab/lbas2002-1/%C3%B8vinger/%C3%B8ving_1/innlevering/adams/tall_og_typekonvertering.ipynb#Y115sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m mult_list_with_x(liste, skalar)\n", + "\u001b[1;32mc:\\Users\\rouhani\\gitlab\\lbas2002-1\\øvinger\\øving_1\\innlevering\\adams\\tall_og_typekonvertering.ipynb Cell 62\u001b[0m line \u001b[0;36m5\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/rouhani/gitlab/lbas2002-1/%C3%B8vinger/%C3%B8ving_1/innlevering/adams/tall_og_typekonvertering.ipynb#Y115sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mmult_list_with_x\u001b[39m(l, x):\n\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/rouhani/gitlab/lbas2002-1/%C3%B8vinger/%C3%B8ving_1/innlevering/adams/tall_og_typekonvertering.ipynb#Y115sZmlsZQ%3D%3D?line=4'>5</a>\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mlist\u001b[39m(result)\n", + "\u001b[1;31mNameError\u001b[0m: name 'result' is not defined" + ] + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er:1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er:{1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "def rund_av(tall, desimaler):\n", + " return round(tall, desimaler)\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/adams/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/adams/variabler.ipynb" new file mode 100644 index 0000000..c42a1ae --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/adams/variabler.ipynb" @@ -0,0 +1,602 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "10 = 10\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'{5 * 2} = {2 * 5}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn = 'Ada'\n", + "fag = 'LBAS2002'\n", + "\n", + "print(f'Hei, {navn}')\n", + "print(f'{fag} - interessant!')\n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {fag}')\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + " \n", + "r = 5.4\n", + "h = 7.9\n", + "omkrets = math.tau * r\n", + "areal = np.pi * r**2\n", + "print(\"Har en sirkel med radius\", r, \"som er grunnflate i en sylinder med høyde\", h)\n", + "print(\"Omkrets av sirkelen:\", omkrets) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", areal)\n", + "print(\"Areal av sylinderen:\", omkrets * h + 2 * math.pi * r ** 2)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "antall = 1 # variabelen må stå på venstre side\n", + "#antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "kamp10 = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy_hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkoholPros = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "ideal_alder = 42\n", + "kundensAlder = 37\n", + "differanse = ideal_alder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/anastasia/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/anastasia/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..a4d550c --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/anastasia/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er et mitt første jupyter\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Erik\n", + "Da er du 25 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er et mitt første jupyter\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, \n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <dobbelklikk programmering er gøy\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/anastasia/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/anastasia/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..75e4e85 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/anastasia/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1101 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "-1.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / c) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'd' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[7], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[39mprint\u001b[39m(d \u001b[39m+\u001b[39m e) \u001b[39m# Samme som 1.2 + (-4.2)\u001b[39;00m\n\u001b[0;32m 2\u001b[0m \u001b[39mprint\u001b[39m(c \u001b[39m-\u001b[39m e) \u001b[39m# Samme som 1.2 - (-4.2)\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[39mprint\u001b[39m(f \u001b[39m*\u001b[39m e) \u001b[39m# Samme som 0.0 * (4.2)\u001b[39;00m\n", + "\u001b[1;31mNameError\u001b[0m: name 'd' is not defined" + ] + } + ], + "source": [ + "print(d + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall (10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "def legg_til_landskode(telefonnummer, landskode):\n", + " p_string = \"+\"\n", + " t_string = str(telefonnummer)\n", + " l_string = str(landskode)\n", + " m_strin = \" \"\n", + " return (str(p_string + t_string + m_strin + l_string))\n", + "\n", + "print(legg_til_landskode(47, 12345678))\n", + "\n", + "print(legg_til_landskode(46, 87654321))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = '1.5'\n", + "e = '2,45'\n", + "\n", + "# Skriv koden din her\n", + "a = int(\"1\")\n", + "b = int(True)\n", + "c = int(False)\n", + "d = int(float(\"1.5\"))\n", + "e = int(float(\"2.35\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " return list(x * np.array(l))\n", + "print(mult_list_with_x([1, 1.5, 2, 2.5, 3],2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "def rund_av(base_number, decimals):\n", + " multiply = 10**decimals\n", + " return int(base_number * multiply) / multiply\n", + "\n", + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/anastasia/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/anastasia/variabler.ipynb" new file mode 100644 index 0000000..8b069dd --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/anastasia/variabler.ipynb" @@ -0,0 +1,566 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 5}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "ITGK = \"LBAS2002\"\n", + "Navn = \"Ada\"\n", + "print('Hei, Ada')\n", + "print(f'{ITGK} - interessant!')\n", + "print(f'Ha en fin dag, {Navn}')\n", + "print('- og lykke til med LBAS2002')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + "\n", + "radius = 5.4\n", + "høyde = 7.9\n", + "omkrets = math.tau * radius\n", + "areal_sirkel = np.pi * radius*2\n", + "areal_sylinder = (omkrets*høyde) + (2 * areal_sirkel)\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "idealalder = 42\n", + "kundensAlder = 37\n", + "differanse = idealalder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/anna/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/anna/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..72a7fb5 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/anna/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første Jupyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Anna\n", + "Da er du 26 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første Jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!)\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Jupyter er kult!)\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Anna\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <Programmering er gøy\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/anna/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/anna/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/anna/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/anna/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/anna/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..bc519f9 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/anna/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1232 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 224, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 1\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 225, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-9\n", + "-9\n", + "-100\n", + "10\n", + "-10.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 226, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 227, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 228, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 229, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 230, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 231, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 232, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 233, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 234, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 235, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 236, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 237, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n" + ] + }, + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[237], line 9\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mGratulerer, til sammen er dere \u001b[39m\u001b[39m{\u001b[39;00msum_alder\u001b[39m}\u001b[39;00m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m 7\u001b[0m sum_alder \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(alder) \u001b[39m+\u001b[39m \u001b[39mint\u001b[39m(alder_mor)\n\u001b[1;32m----> 9\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39;49m\u001b[39mGratulerer, til sammen er dere \u001b[39;49m\u001b[39m'\u001b[39;49m \u001b[39m+\u001b[39;49m sum_alder \u001b[39m+\u001b[39m \u001b[39m'\u001b[39m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n", + "\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "\n", + "def legg_til_landskode(telefonnummer, landskode):\n", + " return '+' + str(landskode) + ' ' + str(telefonnummer)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = int(1)\n", + "b = int(True)\n", + "c = int(False)\n", + "d = int(1.5)\n", + "e = int(2.45)\n", + "\n", + "# Skriv koden din her\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "import numpy as np\n", + "\n", + "def mult_list_with_x(en, x):\n", + " return(np.array(liste) * skalar)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]" + ] + }, + "execution_count": 114, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "list(mult_list_with_x(liste, skalar))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "\n", + "\n", + "def rund_av(tall, desimaler):\n", + " return (round(tall, desimaler))\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/anna/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/anna/variabler.ipynb" new file mode 100644 index 0000000..1f0db17 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/anna/variabler.ipynb" @@ -0,0 +1,603 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn = 'Ada' \n", + "favorittfag = 'LBAS2002'\n", + "\n", + "\n", + "print(f'Hei, {navn}')\n", + "print(f'{favorittfag} - interessant!')\n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {favorittfag}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.9\n", + "Areal av sirkelen: 91.6\n", + "Areal av sylinderen: 451.3\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + " \n", + "\n", + "\n", + "r = 5.4\n", + "h = 7.9\n", + "os = math.tau * 5.4\n", + "asi = np.pi * 5.4**2\n", + "asy = math.tau * 5.4 * 7.9 + 2 * math.pi *5.4 ** 2\n", + "\n", + "\n", + "print(\"Har en sirkel med radius\", r, \"som er grunnflate i en sylinder med høyde\", h)\n", + "print(\"Omkrets av sirkelen:\", round(os,1)) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", round(asi,1))\n", + "print(\"Areal av sylinderen:\", round(asy,1))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid decimal literal (1274524858.py, line 12)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m Cell \u001b[1;32mIn[47], line 12\u001b[1;36m\u001b[0m\n\u001b[1;33m 10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid decimal literal\n" + ] + } + ], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "ideal_alder = 42\n", + "kundensAlder = 37\n", + "differanse = ideal_alder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.2" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/audun/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/audun/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..aa335db --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/audun/intro_til_jupyter.ipynb" @@ -0,0 +1,343 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Dette er mitt første Jupter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow, Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow, Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** Programmering er gøy.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/audun/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/audun/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..fe5c1ca --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/audun/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1013 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(d + e) # Samme som 1.2 + (-4.2) #endret fra c til d\n", + "print(d - e) # Samme som 1.2 - (-4.2) #endret fra c til d\n", + "print(f * e) # Samme som 0.0 * (4.2) # " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [3, 4, 1, 5]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "def legg_til_landskode(telefonnummer, landskode):\n", + " return print(f'+{landskode} {telefonnummer}')\n", + "legg_til_landskode(telefonnummer1, landskode1)\n", + "legg_til_landskode(telefonnummer2, landskode2)\n", + "\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = 1.5\n", + "e = 2.45\n", + "\n", + "# Skriv koden din her\n", + "a = int(a)\n", + "b = int(b)\n", + "c = int(c)\n", + "d = int(d)\n", + "e = int(e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " return list(x * np.array(l))\n", + " \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def rund_av(tall, desimaler):\n", + " return round(tall, desimaler)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/audun/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/audun/variabler.ipynb" new file mode 100644 index 0000000..b3e8e3f --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/audun/variabler.ipynb" @@ -0,0 +1,574 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 5}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Navn?, Ada\n", + "Hei, Ada\n", + "Favorittfag?, LBAS2002\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn = \"Ada\"\n", + "fav_fag = \"LBAS2002\"\n", + "print(f'Navn?, {navn}')\n", + "print(f'Hei, {navn}')\n", + "print(f'Favorittfag?, {fav_fag}')\n", + "print(f'{fav_fag} - interessant!') \n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {fav_fag}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + "\n", + "r = 5.4\n", + "h = 7.9\n", + "O = 33.929200658769766\n", + "A_sirkel = 91.60884177867838\n", + " \n", + "print(\"Har en sirkel med radius\", r, \"som er grunnflate i en sylinder med høyde\", h)\n", + "print(\"Omkrets av sirkelen:\", math.tau * r) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * r**2)\n", + "print(\"Areal av sylinderen:\", O * h + 2 * A_sirkel)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "_4navn = \"Per\"\n", + "ideal_alder = 42\n", + "kundens_Alder = 37 \n", + "differanse = ideal_alder - kundens_Alder\n", + "print(f'{_4navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/benjamin/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/benjamin/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..d8b3395 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/benjamin/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første Jupyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Benjamin\n", + "Da er du 26 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første Jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, \n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Mitt svar:** Programmering er gøy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.9.7" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/benjamin/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/benjamin/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..2e15310 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/benjamin/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1205 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'a' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[1], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[39mprint\u001b[39m(a \u001b[39m+\u001b[39m b) \u001b[39m# Samme som å si -10 + 0\u001b[39;00m\n\u001b[0;32m 2\u001b[0m \u001b[39mprint\u001b[39m(b \u001b[39m-\u001b[39m c) \u001b[39m# Samme som 0 - 10\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[39mprint\u001b[39m(a \u001b[39m*\u001b[39m c) \u001b[39m# Samme som -10 * 10\u001b[39;00m\n", + "\u001b[1;31mNameError\u001b[0m: name 'a' is not defined" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "c = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-3.0\n", + "5.4\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: True\n" + ] + } + ], + "source": [ + "gjort_oving = True\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n" + ] + }, + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[30], line 10\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mGratulerer, til sammen er dere \u001b[39m\u001b[39m{\u001b[39;00msum_alder\u001b[39m}\u001b[39;00m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m 8\u001b[0m sum_alder \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(alder) \u001b[39m+\u001b[39m \u001b[39mint\u001b[39m(alder_mor)\n\u001b[1;32m---> 10\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39;49m\u001b[39mGratulerer, til sammen er dere \u001b[39;49m\u001b[39m'\u001b[39;49m \u001b[39m+\u001b[39;49m sum_alder \u001b[39m+\u001b[39m \u001b[39m'\u001b[39m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n", + "\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "def legg_til_landskode(telefonnummer, landskode):\n", + " telefonnummer_str = str(telefonnummer)\n", + " landskode_str = str(landskode)\n", + " return \"+\" + landskode_str + \" \" + telefonnummer_str\n", + "\n", + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "resultat1 = legg_til_landskode(telefonnummer1, landskode1)\n", + "resultat2 = legg_til_landskode(telefonnummer2, landskode2)\n", + "\n", + "print(resultat1)\n", + "print(resultat2)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = int('1')\n", + "b = int(True)\n", + "c = int(False)\n", + "d = int(float('1.5'))\n", + "e = int(float('2.45'))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]\n" + ] + } + ], + "source": [ + "import numpy as np #sliter veldig med å få lasta ned numpy, pip install numpy funker ikke for meg?\n", + "\n", + "def mult_list_with_x(l, x):\n", + " return list(x * np.array(l))\n", + "print(mult_list_with_x([1, 1.5, 2, 2.5, 3],2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "'int' object is not iterable", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[61], line 4\u001b[0m\n\u001b[0;32m 1\u001b[0m liste \u001b[39m=\u001b[39m [\u001b[39m1\u001b[39m, \u001b[39m1.5\u001b[39m, \u001b[39m2\u001b[39m, \u001b[39m2.5\u001b[39m, \u001b[39m3\u001b[39m]\n\u001b[0;32m 2\u001b[0m skalar \u001b[39m=\u001b[39m \u001b[39m2\u001b[39m\n\u001b[1;32m----> 4\u001b[0m mult_list_with_x(liste, skalar)\n", + "Cell \u001b[1;32mIn[59], line 2\u001b[0m, in \u001b[0;36mmult_list_with_x\u001b[1;34m(l, x)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mmult_list_with_x\u001b[39m(l, x):\n\u001b[1;32m----> 2\u001b[0m \u001b[39mreturn\u001b[39;00m [element \u001b[39m*\u001b[39m x \u001b[39mfor\u001b[39;00m element \u001b[39min\u001b[39;00m \u001b[39m1\u001b[39m]\n", + "\u001b[1;31mTypeError\u001b[0m: 'int' object is not iterable" + ] + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "def rund_av(tall, desimaler):\n", + " multiplier = 10**desimaler\n", + " return round(tall * multiplier) / multiplier\n", + "\n", + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.9.7" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/benjamin/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/benjamin/variabler.ipynb" new file mode 100644 index 0000000..076003b --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/benjamin/variabler.ipynb" @@ -0,0 +1,584 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 5 = 10\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 5 = {2 * 5}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn = 'Ada'\n", + "favorittfag = 'LBAS2002'\n", + "\n", + "print(f'Hei, {navn}')\n", + "print(f'{favorittfag} - interessant!')\n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {favorittfag}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + "\n", + "radius = 5.4\n", + "hoyde = 7.9\n", + "\n", + "omkrets_sirkel = math.tau * radius\n", + "areal_sirkel = np.pi * radius**2\n", + "areal_sylinder = omkrets_sirkel * hoyde + 2\n", + "np.pi * radius**2\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "idealalder = 42\n", + "kundensAlder = 37\n", + "differanse = 5\n", + "differanse - idealalder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.9.7" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/sten/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/sten/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..4cc3c60 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/sten/intro_til_jupyter.ipynb" @@ -0,0 +1,335 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Dette er et program i jupyter\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Dette var kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <dobbelklikk her for å svare\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.9.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/sten/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/sten/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/sten/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/sten/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/sten/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..7cbf469 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/sten/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1073 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n" + ] + } + ], + "source": [ + "def legg_til_landskode(telefonnummer, landskode):\n", + " return \"+\" + str(landskode) + \" \" + str(telefonnummer)\n", + "\n", + "print (legg_til_landskode(12345678, 47))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = '1.5'\n", + "e = '2,45'\n", + "\n", + "# Skriv koden din her\n", + "a = int(1)\n", + "b = int(True)\n", + "c = int(False)\n", + "d = int(1.5)\n", + "e = int(2.45)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "import numpy as np\n", + "def mult_list_with_x(l, x):\n", + " l = np.multiply(l, x) \n", + " print (l)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2. 3. 4. 5. 6.]\n" + ] + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true, + "tags": [] + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "def rund_av(tall, desimaler):\n", + " return round(tall, desimaler)\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "hidden": true, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/sten/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/sten/variabler.ipynb" new file mode 100644 index 0000000..c331572 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/sten/variabler.ipynb" @@ -0,0 +1,572 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn = 'Ada'\n", + "favorittfag = 'LBAS2002'\n", + "print('Hei, ' + navn)\n", + "print(favorittfag + ' - interessant!')\n", + "print('Ha en fin dag, ' + navn)\n", + "print('- og lykke til med ' + favorittfag)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + "\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "radius = 5.4\n", + "høyde = 7.9\n", + "omkrets = (math.tau * 5.4)\n", + "print(\"Omkrets av sirkelen:\", omkrets) #tau er det samme som 2 pi\n", + "arealSirkel = (np.pi * radius**2)\n", + "print(\"Areal av sirkelen:\", arealSirkel)\n", + "arealSylinder = math.tau * radius * høyde + math.tau * radius ** 2\n", + "print(\"Areal av sylinderen:\", arealSylinder)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid decimal literal (2066608501.py, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m Cell \u001b[0;32mIn[10], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m 4navn = \"Per\"\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid decimal literal\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "ideal_alder = 42\n", + "kundensAlder = 37\n", + "differanse = ideal_alder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud1/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud1/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..a4d550c --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud1/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er et mitt første jupyter\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Erik\n", + "Da er du 25 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er et mitt første jupyter\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, \n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <dobbelklikk programmering er gøy\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud1/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud1/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..75e4e85 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud1/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1101 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "-1.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / c) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'd' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[7], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[39mprint\u001b[39m(d \u001b[39m+\u001b[39m e) \u001b[39m# Samme som 1.2 + (-4.2)\u001b[39;00m\n\u001b[0;32m 2\u001b[0m \u001b[39mprint\u001b[39m(c \u001b[39m-\u001b[39m e) \u001b[39m# Samme som 1.2 - (-4.2)\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[39mprint\u001b[39m(f \u001b[39m*\u001b[39m e) \u001b[39m# Samme som 0.0 * (4.2)\u001b[39;00m\n", + "\u001b[1;31mNameError\u001b[0m: name 'd' is not defined" + ] + } + ], + "source": [ + "print(d + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall (10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "def legg_til_landskode(telefonnummer, landskode):\n", + " p_string = \"+\"\n", + " t_string = str(telefonnummer)\n", + " l_string = str(landskode)\n", + " m_strin = \" \"\n", + " return (str(p_string + t_string + m_strin + l_string))\n", + "\n", + "print(legg_til_landskode(47, 12345678))\n", + "\n", + "print(legg_til_landskode(46, 87654321))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = '1.5'\n", + "e = '2,45'\n", + "\n", + "# Skriv koden din her\n", + "a = int(\"1\")\n", + "b = int(True)\n", + "c = int(False)\n", + "d = int(float(\"1.5\"))\n", + "e = int(float(\"2.35\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " return list(x * np.array(l))\n", + "print(mult_list_with_x([1, 1.5, 2, 2.5, 3],2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "def rund_av(base_number, decimals):\n", + " multiply = 10**decimals\n", + " return int(base_number * multiply) / multiply\n", + "\n", + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud1/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud1/variabler.ipynb" new file mode 100644 index 0000000..8b069dd --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud1/variabler.ipynb" @@ -0,0 +1,566 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 5}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "ITGK = \"LBAS2002\"\n", + "Navn = \"Ada\"\n", + "print('Hei, Ada')\n", + "print(f'{ITGK} - interessant!')\n", + "print(f'Ha en fin dag, {Navn}')\n", + "print('- og lykke til med LBAS2002')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + "\n", + "radius = 5.4\n", + "høyde = 7.9\n", + "omkrets = math.tau * radius\n", + "areal_sirkel = np.pi * radius*2\n", + "areal_sylinder = (omkrets*høyde) + (2 * areal_sirkel)\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "idealalder = 42\n", + "kundensAlder = 37\n", + "differanse = idealalder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud10/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud10/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..c02b1ea --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud10/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første Jypyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Ada\n", + "Da er du 25 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første Jypyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow, Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow, Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** programmering er gøy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud10/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud10/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud10/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud10/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud10/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..3b3e14a --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud10/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1291 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "-1.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / c) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-3.0\n", + "5.4\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(d + e) # Samme som 1.2 + (-4.2)\n", + "print(d - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: (1, 2, 3, 4, 5)\n" + ] + } + ], + "source": [ + "liste_med_tall = (1, 2, 3, 4, 5)\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n" + ] + }, + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[9], line 9\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mGratulerer, til sammen er dere \u001b[39m\u001b[39m{\u001b[39;00msum_alder\u001b[39m}\u001b[39;00m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m 7\u001b[0m sum_alder \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(alder) \u001b[39m+\u001b[39m \u001b[39mint\u001b[39m(alder_mor)\n\u001b[1;32m----> 9\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39;49m\u001b[39mGratulerer, til sammen er dere \u001b[39;49m\u001b[39m'\u001b[39;49m \u001b[39m+\u001b[39;49m sum_alder \u001b[39m+\u001b[39m \u001b[39m'\u001b[39m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n", + "\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "25\n" + ] + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return str(a) + str(b)\n", + "sum= int(a) + int(b)\n", + "legg_sammen_to_tall(10, 15)\n", + "print( sum)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "def legg_til_landskode(telefonnummer, landskode):\n", + " return \"+\" + str(landskode) + \" \" + str(telefonnummer)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = +47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = +46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = int(1)\n", + "b = int(1)\n", + "c = int(0)\n", + "d = int (1.5)\n", + "e = int (2.45)\n", + "\n", + "\n", + "\n", + "# Skriv koden din her" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting matplotlib\n", + " Obtaining dependency information for matplotlib from https://files.pythonhosted.org/packages/4d/9c/65830d4a56c47f5283eaa244dc1228c5da9c844a9f999ebcc2e69bf6cc65/matplotlib-3.7.2-cp311-cp311-win_amd64.whl.metadata\n", + " Downloading matplotlib-3.7.2-cp311-cp311-win_amd64.whl.metadata (5.8 kB)\n", + "Collecting contourpy>=1.0.1 (from matplotlib)\n", + " Obtaining dependency information for contourpy>=1.0.1 from https://files.pythonhosted.org/packages/16/09/989b982322439faa4bafffcd669e6f942b38fee897c2664c987bcd091dec/contourpy-1.1.0-cp311-cp311-win_amd64.whl.metadata\n", + " Downloading contourpy-1.1.0-cp311-cp311-win_amd64.whl.metadata (5.7 kB)\n", + "Collecting cycler>=0.10 (from matplotlib)\n", + " Downloading cycler-0.11.0-py3-none-any.whl (6.4 kB)\n", + "Collecting fonttools>=4.22.0 (from matplotlib)\n", + " Obtaining dependency information for fonttools>=4.22.0 from https://files.pythonhosted.org/packages/95/b6/9a5133deb5838c4dbe3ea27e8dba123622aa5112d43a079e9587636b4faf/fonttools-4.42.1-cp311-cp311-win_amd64.whl.metadata\n", + " Downloading fonttools-4.42.1-cp311-cp311-win_amd64.whl.metadata (154 kB)\n", + " ---------------------------------------- 0.0/154.1 kB ? eta -:--:--\n", + " -- ------------------------------------- 10.2/154.1 kB ? eta -:--:--\n", + " --------- --------------------------- 41.0/154.1 kB 991.0 kB/s eta 0:00:01\n", + " -------------------------------------- 154.1/154.1 kB 1.8 MB/s eta 0:00:00\n", + "Collecting kiwisolver>=1.0.1 (from matplotlib)\n", + " Obtaining dependency information for kiwisolver>=1.0.1 from https://files.pythonhosted.org/packages/1e/37/d3c2d4ba2719059a0f12730947bbe1ad5ee8bff89e8c35319dcb2c9ddb4c/kiwisolver-1.4.5-cp311-cp311-win_amd64.whl.metadata\n", + " Downloading kiwisolver-1.4.5-cp311-cp311-win_amd64.whl.metadata (6.5 kB)\n", + "Requirement already satisfied: numpy>=1.20 in c:\\users\\eilee\\appdata\\local\\programs\\python\\python311\\lib\\site-packages (from matplotlib) (1.25.2)\n", + "Requirement already satisfied: packaging>=20.0 in c:\\users\\eilee\\appdata\\roaming\\python\\python311\\site-packages (from matplotlib) (23.1)\n", + "Collecting pillow>=6.2.0 (from matplotlib)\n", + " Obtaining dependency information for pillow>=6.2.0 from https://files.pythonhosted.org/packages/66/d4/054e491f0880bf0119ee79cdc03264e01d5732e06c454da8c69b83a7c8f2/Pillow-10.0.0-cp311-cp311-win_amd64.whl.metadata\n", + " Downloading Pillow-10.0.0-cp311-cp311-win_amd64.whl.metadata (9.6 kB)\n", + "Collecting pyparsing<3.1,>=2.3.1 (from matplotlib)\n", + " Downloading pyparsing-3.0.9-py3-none-any.whl (98 kB)\n", + " ---------------------------------------- 0.0/98.3 kB ? eta -:--:--\n", + " ---------------------------------------- 98.3/98.3 kB 5.5 MB/s eta 0:00:00\n", + "Requirement already satisfied: python-dateutil>=2.7 in c:\\users\\eilee\\appdata\\roaming\\python\\python311\\site-packages (from matplotlib) (2.8.2)\n", + "Requirement already satisfied: six>=1.5 in c:\\users\\eilee\\appdata\\roaming\\python\\python311\\site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n", + "Downloading matplotlib-3.7.2-cp311-cp311-win_amd64.whl (7.5 MB)\n", + " ---------------------------------------- 0.0/7.5 MB ? eta -:--:--\n", + " -- ------------------------------------- 0.5/7.5 MB 14.5 MB/s eta 0:00:01\n", + " ----- ---------------------------------- 1.0/7.5 MB 13.3 MB/s eta 0:00:01\n", + " -------- ------------------------------- 1.7/7.5 MB 13.4 MB/s eta 0:00:01\n", + " ------------ --------------------------- 2.4/7.5 MB 15.3 MB/s eta 0:00:01\n", + " -------------- ------------------------- 2.8/7.5 MB 13.7 MB/s eta 0:00:01\n", + " ------------------- -------------------- 3.7/7.5 MB 15.0 MB/s eta 0:00:01\n", + " ----------------------- ---------------- 4.5/7.5 MB 16.0 MB/s eta 0:00:01\n", + " ---------------------------- ----------- 5.4/7.5 MB 15.6 MB/s eta 0:00:01\n", + " ------------------------------- -------- 6.0/7.5 MB 16.0 MB/s eta 0:00:01\n", + " ------------------------------------ --- 6.9/7.5 MB 16.2 MB/s eta 0:00:01\n", + " --------------------------------------- 7.5/7.5 MB 16.5 MB/s eta 0:00:01\n", + " ---------------------------------------- 7.5/7.5 MB 15.5 MB/s eta 0:00:00\n", + "Downloading contourpy-1.1.0-cp311-cp311-win_amd64.whl (470 kB)\n", + " ---------------------------------------- 0.0/470.9 kB ? eta -:--:--\n", + " --------------------------------------- 470.9/470.9 kB 14.4 MB/s eta 0:00:00\n", + "Downloading fonttools-4.42.1-cp311-cp311-win_amd64.whl (2.1 MB)\n", + " ---------------------------------------- 0.0/2.1 MB ? eta -:--:--\n", + " ------------ --------------------------- 0.7/2.1 MB 21.5 MB/s eta 0:00:01\n", + " ----------------------------- ---------- 1.5/2.1 MB 19.6 MB/s eta 0:00:01\n", + " ---------------------------------------- 2.1/2.1 MB 15.0 MB/s eta 0:00:00\n", + "Downloading kiwisolver-1.4.5-cp311-cp311-win_amd64.whl (56 kB)\n", + " ---------------------------------------- 0.0/56.1 kB ? eta -:--:--\n", + " ---------------------------------------- 56.1/56.1 kB ? eta 0:00:00\n", + "Downloading Pillow-10.0.0-cp311-cp311-win_amd64.whl (2.5 MB)\n", + " ---------------------------------------- 0.0/2.5 MB ? eta -:--:--\n", + " --------- ------------------------------ 0.6/2.5 MB 12.0 MB/s eta 0:00:01\n", + " ------------------- -------------------- 1.2/2.5 MB 15.5 MB/s eta 0:00:01\n", + " -------------------------------- ------- 2.1/2.5 MB 16.5 MB/s eta 0:00:01\n", + " --------------------------------------- 2.5/2.5 MB 16.0 MB/s eta 0:00:01\n", + " ---------------------------------------- 2.5/2.5 MB 14.6 MB/s eta 0:00:00\n", + "Installing collected packages: pyparsing, pillow, kiwisolver, fonttools, cycler, contourpy, matplotlib\n", + "Successfully installed contourpy-1.1.0 cycler-0.11.0 fonttools-4.42.1 kiwisolver-1.4.5 matplotlib-3.7.2 pillow-10.0.0 pyparsing-3.0.9\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install matplotlib" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "import numpy as np \n", + "\n", + "def multi_list_with_x(en, *x):\n", + " return (np.array(liste) * skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "list(multi_list_with_x(liste, skalar))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "rund_av=round" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud10/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud10/variabler.ipynb" new file mode 100644 index 0000000..631e607 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud10/variabler.ipynb" @@ -0,0 +1,593 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn=input(\"Hva heter du?\")\n", + "fag=input(\"Hva er favorittfaget ditt?\")\n", + "\n", + "print(f'Hei, {navn}')\n", + "print(f'{fag} - interessant!')\n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {fag}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "cannot assign to literal here. Maybe you meant '==' instead of '='? (219688234.py, line 10)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m Cell \u001b[1;32mIn[18], line 10\u001b[1;36m\u001b[0m\n\u001b[1;33m 1 = antall # variabelen må stå på venstre side\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m cannot assign to literal here. Maybe you meant '==' instead of '='?\n" + ] + } + ], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "ideal_alder = 42\n", + "kundensAlder= 37\n", + "differanse = ideal_alder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud11/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud11/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..28631f2 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud11/intro_til_jupyter.ipynb" @@ -0,0 +1,362 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første Jupyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Mari\n", + "Da er du 41 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første Jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <dobbelklikk Programmering er gøy\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud11/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud11/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud11/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud11/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud11/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..c37b1ce --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud11/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1092 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a + b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "gjort_oving = True\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [12, 2, 134, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a , b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "def legg_til_landskode(telefonnummer, landskode):\n", + " telefonnummer = str(telefonnummer)\n", + " landskode = str(landskode)\n", + "\n", + " kode_nummer = '+' + landskode + ' ' + telefonnummer\n", + " \n", + " return kode_nummer\n", + "\n", + "telefonnummer1 = 12345678\n", + "telefonnummer2 = 87654321\n", + "\n", + "landskode1 = 47\n", + "landskode2 = 46\n", + "\n", + "nummer1 = legg_til_landskode(telefonnummer1, landskode1)\n", + "nummer2 = legg_til_landskode(telefonnummer2, landskode2)\n", + "\n", + "print(nummer1)\n", + "print(nummer2)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = '1.5'\n", + "e = '2,45'\n", + "\n", + "# Skriv koden din her\n", + "\n", + "a = int(a)\n", + "b = int(b == 'true' or 1)\n", + "c = int(c == 'false')\n", + "d = int(1.5)\n", + "e= int(2.45)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2. 3. 4. 5. 6.]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "def mult_list_with_x(start_liste, x):\n", + " input_array = np.array(start_liste)\n", + "\n", + " result_array = input_array * x\n", + "\n", + " return result_array\n", + "\n", + "start_liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "ferdig_liste = mult_list_with_x(start_liste, skalar)\n", + "\n", + "print(ferdig_liste)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "def rund_av(tall, desimaler):\n", + " tall = round(tall, desimaler)\n", + " return tall\n", + "\n", + "\n", + "rundt_tall = rund_av(tall, desimaler)\n", + "\n", + "tall = 1.23456\n", + "desimaler = 2\n", + "\n", + "print(rundt_tall)\n", + "\n", + "tall2 = 1234.5432\n", + "desimaler2 = -3\n", + "\n", + "rundt_tall2 = rund_av(tall2, desimaler2)\n", + "\n", + "print(rundt_tall2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'rund_av' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[50], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[39mprint\u001b[39m(rund_av(\u001b[39m1.23456\u001b[39m, \u001b[39m2\u001b[39m))\n\u001b[0;32m 2\u001b[0m \u001b[39mprint\u001b[39m(rund_av(\u001b[39m1234.5432\u001b[39m, \u001b[39m-\u001b[39m\u001b[39m3\u001b[39m))\n", + "\u001b[1;31mNameError\u001b[0m: name 'rund_av' is not defined" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud11/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud11/variabler.ipynb" new file mode 100644 index 0000000..276faa6 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud11/variabler.ipynb" @@ -0,0 +1,616 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei Mari\n", + "javvist er LBAS2002 interessant!\n", + "Ha en fin dag Mari\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn = input('hva heter du: ')\n", + "fav_fag = \"LBAS2002\"\n", + "\n", + "print('Hei' , navn)\n", + "print(f'javvist er {fav_fag}' , 'interessant!')\n", + "print('Ha en fin dag', navn)\n", + "print('- og lykke til med', fav_fag)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4, som er grunnflate i en sylinder med høyde, 7.9\n", + "Sirkelens omkrets er, 33.929200658769766\n", + "Areal av sirkelen er 91.60884177867838\n", + "Sylinderens areal er 451.25836876163794\n" + ] + } + ], + "source": [ + "\n", + "radius = \"5.4\"\n", + "høyde = \"7.9\"\n", + "omkrets = (math.tau * 5.4)\n", + "sir_areal = (np.pi * 5.4**2)\n", + "syl_areal = (math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 **2)\n", + "\n", + "print(f'Har en sirkel med radius {radius}, som er grunnflate i en sylinder med høyde, {høyde}')\n", + "print(f'Sirkelens omkrets er, {omkrets}')\n", + "print(f'Areal av sirkelen er {sir_areal}')\n", + "print(f'Sylinderens areal er {syl_areal}')\n", + " \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "ideal_alder = 42\n", + "kundensAlder = 37\n", + "differanse = ideal_alder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud12/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud12/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..8512c75 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud12/intro_til_jupyter.ipynb" @@ -0,0 +1,343 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Dette er mitt første Jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter var kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, ewi\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Programmering er såkalt gøy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud12/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud12/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud12/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud12/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud12/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..a9c2eb3 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud12/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1228 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "-1.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / c) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: True\n" + ] + } + ], + "source": [ + "gjort_oving = True\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n" + ] + }, + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[20], line 9\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[39mprint\u001b[39m (\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mGratulerer, til sammen er dere \u001b[39m\u001b[39m{\u001b[39;00msum_alder\u001b[39m}\u001b[39;00m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[1;32m 7\u001b[0m sum_alder \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(alder) \u001b[39m+\u001b[39m \u001b[39mint\u001b[39m(alder_mor)\n\u001b[0;32m----> 9\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39;49m\u001b[39mGratulerer, til sammen er dere \u001b[39;49m\u001b[39m'\u001b[39;49m \u001b[39m+\u001b[39;49m sum_alder \u001b[39m+\u001b[39m \u001b[39m'\u001b[39m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n", + "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print (f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def legg_til_landskode(telefonnummer, landskode):\n", + " return \"+\" + str(landskode) + \" \" + str(telefonnummer) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = '1.5'\n", + "e = '2.45'\n", + "\n", + "# Skriv koden din her\n", + "a = int(a)\n", + "b = int(b)\n", + "c = int(c)\n", + "d = int(float(d))\n", + "e = int(float(e))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "\n", + "import numpy as np\n", + "\n", + "\n", + "def mult_list_with_x(l,x):\n", + " return list(result)\n", + "l = np.array(liste)\n", + "x = skalar\n", + "result=np.multiply(l,x)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "def rund_av(tall,desimaler):\n", + " return round(tall, desimaler)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.9.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud12/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud12/variabler.ipynb" new file mode 100644 index 0000000..3f5dd61 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud12/variabler.ipynb" @@ -0,0 +1,549 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 5}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print('Hei, Ada')\n", + "print('LBAS2002 - interessant!')\n", + "print('Ha en fin dag, Ada')\n", + "print('- og lykke til med LBAS2002')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid decimal literal (1274524858.py, line 12)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m Cell \u001b[0;32mIn[2], line 12\u001b[0;36m\u001b[0m\n\u001b[0;31m 10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid decimal literal\n" + ] + } + ], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "ideal_alder = 42\n", + "kundensAlder = 37\n", + "differanse = ideal_alder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud13/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud13/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..27bd6dd --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud13/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første Jupyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Runa\n", + "Da er du 30 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første Jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow, Jupyter er råkult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow, Jupyter er råkult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Runa\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <hghgjghjkghjk\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud13/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud13/lab-1.md" new file mode 100644 index 0000000..016417f --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud13/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +## Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud13/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud13/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..5a367d8 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud13/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1177 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "1\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a // a) # Samme som -10 : -10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 123456\n" + ] + } + ], + "source": [ + "tall = 123456\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med kule tall: [1, 2, 3, 4, 6, 7, 8, 8, 10]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4,6,7,8,8,10]\n", + "print(f'Her har du en liste med kule tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4,]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 50 år!\n" + ] + }, + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[68], line 9\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mGratulerer, til sammen er dere \u001b[39m\u001b[39m{\u001b[39;00msum_alder\u001b[39m}\u001b[39;00m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[1;32m 7\u001b[0m sum_alder \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(alder) \u001b[39m+\u001b[39m \u001b[39mint\u001b[39m(alder_mor)\n\u001b[0;32m----> 9\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39;49m\u001b[39mGratulerer, til sammen er dere \u001b[39;49m\u001b[39m'\u001b[39;49m \u001b[39m+\u001b[39;49m sum_alder \u001b[39m+\u001b[39m \u001b[39m'\u001b[39m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n", + "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "alder = int('13')\n", + "alder_mor = int('37')\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = int('13')\n", + "alder_mor = int('37')\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "25\n" + ] + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " str(a) + str(b)\n", + " print (a+b)\n", + "\n", + "legg_sammen_to_tall(10,15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+ 47 12345678\n", + "+ 46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print('+' , str(landskode1), str(telefonnummer1))\n", + "print('+', str(landskode2), str(telefonnummer2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = 1.5\n", + "e = 2.45\n", + "\n", + "print(f'a er nå {int(a)}')\n", + "print(f'b er nå {int(b)}')\n", + "print(f'c er nå {int(c)}')\n", + "print(f'd er nå {int(d)}')\n", + "print(f'e er nå {int(e)}')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[20. 30. 40. 50. 60.]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " return l*x\n", + "\n", + "liste = [1,1.5,2, 2.5, 3]\n", + "skalar = 20\n", + "\n", + "print(mult_list_with_x(np.array(liste),skalar))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 134, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "# Skriv koden din her\n", + "def rund_av(tall,desimaler):\n", + " return round(tall,desimaler)\n", + "\n", + "print(rund_av(1.23456,2))\n", + "print(rund_av(1234.5432, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud13/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud13/variabler.ipynb" new file mode 100644 index 0000000..c6f4d27 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud13/variabler.ipynb" @@ -0,0 +1,579 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 5}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "print('Hei, Ada')\n", + "print('LBAS2002 - interessant!')\n", + "print('Ha en fin dag, Ada')\n", + "print('- og lykke til med LBAS2002')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid decimal literal (2464945294.py, line 12)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m Cell \u001b[0;32mIn[9], line 12\u001b[0;36m\u001b[0m\n\u001b[0;31m 10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid decimal literal\n" + ] + } + ], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1= antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna ideal_alderen\n" + ] + } + ], + "source": [ + "navn = 'Per'\n", + "ideal_alder = 42\n", + "kundens_alder = 37\n", + "differanse = ideal_alder - kundens_alder\n", + "print(f'{navn} er {differanse} år unna ideal_alderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud14/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud14/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..ebab61e --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud14/intro_til_jupyter.ipynb" @@ -0,0 +1,359 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Dette er mitt første Jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "message= \"Jeg elsker koding 100%\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg elsker koding 100%\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, kk\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <Programmering er gøy\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud14/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud14/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..64a625c --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud14/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1220 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "136\n" + ] + } + ], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10\n", + "print(a**2+c-b+26)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a * b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-3.0\n", + "5.4\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(d + e) # Samme som 1.2 + (-4.2)\n", + "print(d - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (-4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 50 år\n", + "Gratulerer, til sammen er dere, 50 år!\n", + "Gratulerer, til sammen er dere, 50, år\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) +' år')\n", + "print(f'Gratulerer, til sammen er dere, {sum_alder} år!')\n", + "\n", + "alder = '13'\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print(f'Gratulerer, til sammen er dere, {sum_alder}, år')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def f(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "f(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 213, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def legg_til_landskode(landskode, telefonnummer):\n", + " return '+' + str(telefonnummer), str(landskode)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 212, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('+47', '12345678')\n", + "('+46', '87654321')\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = 1\n", + "b = int(True)\n", + "c = int(False)\n", + "d = int(1.5)\n", + "e = int(2.45)\n", + "\n", + "# Skriv koden din her" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 266, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " return list(x * np.array(l)) \n", + " \n", + " \n", + " \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 267, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]" + ] + }, + "execution_count": 267, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def rund_av(a, b):\n", + " return round(a, b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud14/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud14/variabler.ipynb" new file mode 100644 index 0000000..ae9986b --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud14/variabler.ipynb" @@ -0,0 +1,576 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, mox\n", + "koding - interessant!\n", + "Ha en fin dag, mox\n", + "- og lykke til med koding\n" + ] + } + ], + "source": [ + "\n", + "navn = input('Hva heter du? ')\n", + "print(f'Hei, {navn}')\n", + "favorittfag = input('Favorittfag?')\n", + "print(f'{favorittfag} - interessant!')\n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {favorittfag}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius {5.4} som er grunnflate i en sylinder med høyde {7.9}\n", + "Omkrets av sirkelen: {33.929200658769766}\n", + "Areal av sirkelen: {91.60884177867838}\n", + "('Areal av sylinderen:', {451.25836876163794})\n" + ] + } + ], + "source": [ + "import math as m\n", + "r = 5.4\n", + "h = 7.9\n", + " \n", + "print(f\"Har en sirkel med radius\", {r}, \"som er grunnflate i en sylinder med høyde\", {h})\n", + "print(f\"Omkrets av sirkelen:\", {m.tau * r}) #tau er det samme som 2 pi\n", + "print(f\"Areal av sirkelen:\", {m.pi * r**2})\n", + "print(f\"Areal av sylinderen:\", {m.tau * r * h + 2 * m.pi * r ** 2})" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "ideal_alder = 42\n", + "kundens_alder = 37\n", + "differanse = ideal_alder - kundens_alder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud15/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud15/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..c982078 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud15/intro_til_jupyter.ipynb" @@ -0,0 +1,335 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Dette er mitt første Jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** Programmering er gøy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud15/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud15/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud15/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud15/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud15/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..178b494 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud15/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1248 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 1\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-9\n", + "-9\n", + "-100\n", + "10\n", + "-10.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 10]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 10]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10 , 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(f'+{landskode1} {telefonnummer1}')\n", + "print(f'+{landskode2} {telefonnummer2}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12345678\n", + "46\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(telefonnummer1)\n", + "print(landskode2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "a = int(1)\n", + "b = int(1)\n", + "c = int(0)\n", + "d = int(1.5)\n", + "e = int(2.45)\n", + "\n", + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]\n" + ] + } + ], + "source": [ + "liste = [2.0 , 3.0 , 4.0 , 5.0 , 6.0]\n", + "skalar = 1\n", + "\n", + "print (liste* skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1. , 1.5, 2. , 2.5, 3. , 1. , 1.5, 2. , 2.5, 3. ])" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np\n", + "\n", + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "np.array(liste* skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(round(1.23456, 2))\n", + "print(round(1234.5432, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(round(1.23456, 2))\n", + "print(round(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud15/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud15/variabler.ipynb" new file mode 100644 index 0000000..84f5256 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud15/variabler.ipynb" @@ -0,0 +1,601 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Navn? Kjersti\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei Kjersti\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Favorittfag? Informatikk\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Informatikk - interessant!\n", + "Ha en fin dag, Kjersti\n", + "- og lykke til med Informatikk\n" + ] + } + ], + "source": [ + "Navn = input(\"Navn?\")\n", + "print(\"Hei\", Navn)\n", + "Fag = input(\"Favorittfag?\")\n", + "print(f'{Fag} - interessant!')\n", + "print(f'Ha en fin dag, {Navn}')\n", + "print(f'- og lykke til med {Fag}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + "\n", + "r = 5.4\n", + "h = 7.9\n", + "\n", + "print(\"Har en sirkel med radius\", r, \"som er grunnflate i en sylinder med høyde\", h)\n", + "print(\"Omkrets av sirkelen:\", math.tau * r) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * r **2)\n", + "print(\"Areal av sylinderen:\", math.tau * r * h + 2 * math.pi * r ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 8 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn4 = \"Per\"\n", + "ideal_alder = 42\n", + "kundens_Alder= 34\n", + "differanse = ideal_alder - kundens_Alder\n", + "print(f'{navn4} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud2/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud2/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..9693bb7 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud2/intro_til_jupyter.ipynb" @@ -0,0 +1,374 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første Jupyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Pia\n", + "Da er du 28 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første Jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Pia\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)\n", + "# Skjønner ikke hva Kernel er, men finner både Restart og Clear All Outputs i menyen over. \n", + "# Ser ikke stjernetegn ved blokkene\n", + "# Clear all outputs virker mindre skummelt enn Restart, alle outputs forsvant, men jeg gjennomgikk dem igjen\n", + "# Prøvde å trykke restart - beskjed om at 'All variables will be lost', men de er her fortsatt - ingenting forsvant!\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <Programmering er gøy\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud2/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud2/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud2/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud2/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud2/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..1509cf2 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud2/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1264 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forskjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "0.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(b / c) # Samme som 0 : 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2), stemmer ikke, det er det samme som 10 + (-4.2) og da stemmer svaret i output\n", + "print(c - e) # Samme som 1.2 - (-4.2), stemmer ikke, det er det samme som 10 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)\n", + "# Her brukes ikke variablen d som er ovenfor, men variablen c lenger opp som gir verdien 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)\n", + "# Det utgjør ingen forskjell om det brukes enkelt- eller dobbeltfnutter, med trippelfnutter er det mulig å skrive på flere linjer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)\n", + "# Da kommer sifrene ut etter hverandre uten mellomrom, tallene oppfattes som tekst og ikke heltall (integers)\n", + "# Leser under at det heter at strengene blir konkatinert" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = int('13')\n", + "alder_mor =int('37')\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 116, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " #return str(a) + str(b)\n", + " return int(a) +int(b)\n", + "legg_sammen_to_tall (10, 15)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "# legg_til_landskode int(telefonnummer, landskode)\n", + "\n", + "# name=legg_til_landskode\n", + "\n", + "def legg_til_landskode(telefonnummer, landskode):\n", + " return '+' + str(landskode) + ' ' + (str)(telefonnummer)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<class 'int'>\n", + "<class 'int'>\n", + "<class 'int'>\n", + "<class 'int'>\n", + "<class 'int'>\n" + ] + } + ], + "source": [ + "#a = '1'\n", + "#b = True\n", + "#c = False\n", + "#d = '1.5'\n", + "#e = '2,45'\n", + "#print(type(a))\n", + "#print(type(b))\n", + "# Skriv koden din her\n", + "a = int('1')\n", + "b = int(True)\n", + "c = int(False)\n", + "d = int(float('1.5'))\n", + "e = int(float('2.45')) #endret til punktum istedet for komma\n", + "print(type(a))\n", + "print(type(b))\n", + "print(type(c))\n", + "print(type(d))\n", + "print(type(e))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 40 80 120 160]\n" + ] + } + ], + "source": [ + "# Skriv koden din her\n", + "import numpy as np\n", + "#def mult_list_with_x(liste, skalar):\n", + "# return np.array(liste) * skalar\n", + "#print(type(skalar))\n", + "\n", + "def mult_list_whit_x(l,x): \n", + " resultat = l*x\n", + " return resultat\n", + "\n", + "l = np.array([10,20,30,40])\n", + "print(mult_list_whit_x(l,4))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([2., 3., 4., 5., 6.])" + ] + }, + "execution_count": 137, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#liste =[1, 1.5, 2, 2.5, 3]\n", + "#skalar = 2\n", + "\n", + "#mult_list_whit_x(liste,skalar)\n", + "\n", + "\n", + "l = np.array([1, 1.5, 2, 2.5, 3])\n", + "x = 2\n", + "\n", + "# print(liste * skalar)\n", + "\n", + "\n", + "mult_list_with_x(l, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "def rund_av(tall, desimaler):\n", + " return round(tall, desimaler)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud2/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud2/variabler.ipynb" new file mode 100644 index 0000000..31480cd --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud2/variabler.ipynb" @@ -0,0 +1,605 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}') #{pi} er variabel og peker tilbake på tallet - kan gjenbrukes flere ganger\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp? #rettet opp gangestykket slik at det ble rett svar." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Monica\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Monica\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "#print('Hei, Ada')\n", + "#print('LBAS2002 - interessant!')\n", + "#print('Ha en fin dag, Ada')\n", + "#print('- og lykke til med LBAS2002')\n", + "\n", + "navn = input('Navn?')\n", + "print('Hei, ' + navn)\n", + "fag = input('Favorittfag?')\n", + "print(fag + ' - interessant!')\n", + "print('Ha en fin dag, ' + navn)\n", + "print('- og lykke til med ' + fag)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "33.928200000000004\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.9\n", + "Areal av sirkelen: 92\n", + "Areal av sylinderen: 451\n" + ] + } + ], + "source": [ + "#import numpy as np #feilmelding No module named 'numpy'\n", + "import math\n", + " \n", + "#print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "#print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "#print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "#print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)\n", + "\n", + "r = 5.4\n", + "\n", + "pi = math.pi \n", + "h_sylinder = 7.9\n", + "o_sirkel = 2 * pi * r\n", + "a_sirkel = pi * r ** 2\n", + "print(o)\n", + "print(\"Har en sirkel med radius \" + str(r) + \" som er grunnflate i en sylinder med høyde \" + str(h_sylinder)) \n", + "print(\"Omkrets av sirkelen: \" + str(round(o_sirkel,1))) \n", + "print(\"Areal av sirkelen: \" + str(round(a_sirkel)))\n", + "print(\"Areal av sylinderen: \" + str(round(o_sirkel * h_sylinder + 2 * a_sirkel)))\n", + "#mente jeg kunne bestemme desimaler ved å skrive :0.1f, men det ga bare feilmelding.\n", + "\n", + "#forsøkte etterpå å bruke round for å ta bort desimaler, det virket" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "#1 = antall # variabelen må stå på venstre side\n", + "#10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "#antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "#happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "#alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall\n", + "\n", + "# satte alle dysfunksjonelle tilordninger som merknad" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn4 = \"Per\"\n", + "ideal_alder = 42\n", + "kundensAlder = 37\n", + "differanse = ideal_alder - kundensAlder\n", + "print(f'{navn4} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud3/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud3/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..fcdd1bc --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud3/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første Jupyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Jannicke\n", + "Da er du 31 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første Jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Nå lærer jeg noe nytt!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Nå lærer jeg noe nytt!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Jannicke\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <Programmering er gøy!\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud3/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud3/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud3/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud3/lab.zip" "b/\303\270vinger/\303\270ving_1/innlevering/stud3/lab.zip" new file mode 100644 index 0000000000000000000000000000000000000000..d9ce5eb6d06bc549c66c7088cd79c1f779305c42 GIT binary patch literal 16284 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 literal 0 HcmV?d00001 diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud3/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud3/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..a64cf53 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud3/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1245 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 1\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-9\n", + "-9\n", + "-100\n", + "10\n", + "-10.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: True\n" + ] + } + ], + "source": [ + "gjort_oving = True\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [33, 6783, 1, 238]\n" + ] + } + ], + "source": [ + "liste_med_tall = [33, 6783, 1, 238]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n" + ] + }, + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[18], line 9\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mGratulerer, til sammen er dere \u001b[39m\u001b[39m{\u001b[39;00msum_alder\u001b[39m}\u001b[39;00m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m 7\u001b[0m sum_alder \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(alder) \u001b[39m+\u001b[39m \u001b[39mint\u001b[39m(alder_mor)\n\u001b[1;32m----> 9\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39;49m\u001b[39mGratulerer, til sammen er dere \u001b[39;49m\u001b[39m'\u001b[39;49m \u001b[39m+\u001b[39;49m sum_alder \u001b[39m+\u001b[39m \u001b[39m'\u001b[39m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n", + "\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+ 47 12345678\n", + "+ 46 87654321\n" + ] + } + ], + "source": [ + "# Skriv koden din her\n", + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print('+' , str(landskode1) , str(telefonnummer1))\n", + "print('+' , str(landskode2) , str(telefonnummer2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = 1.5\n", + "e = 2.45\n", + "\n", + "# Skriv koden din her\n", + "print(f'a er nå {int(a)}')\n", + "print(f'b er nå {int(b)}')\n", + "print(f'c er nå {int(c)}')\n", + "print(f'd er nå {int(d)}')\n", + "print(f'e er nå {int(e)}')\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'a' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[23], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39ma er nå \u001b[39m\u001b[39m{\u001b[39;00ma\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m)\n\u001b[0;32m 2\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mb er nå \u001b[39m\u001b[39m{\u001b[39;00mb\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m)\n\u001b[0;32m 3\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mc er nå \u001b[39m\u001b[39m{\u001b[39;00mc\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m)\n", + "\u001b[1;31mNameError\u001b[0m: name 'a' is not defined" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2. 3. 4. 5. 6.]\n" + ] + } + ], + "source": [ + "# Skriv koden din her\n", + "\n", + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " resultat = l*x\n", + " return resultat\n", + "l = np.array([1, 1.5, 2, 2.5, 3])\n", + "\n", + "print(mult_list_with_x(l,2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)\n", + "list() \n", + "import numpy as np\n", + "np.array()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "# Skriv koden din her\n", + "def rund_av(tall, desimaler):\n", + " return round(tall, desimaler)\n", + "\n", + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud3/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud3/variabler.ipynb" new file mode 100644 index 0000000..d8e2ec4 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud3/variabler.ipynb" @@ -0,0 +1,587 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS1002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS1002\n" + ] + } + ], + "source": [ + "navn= 'Ada'\n", + "fag= 'LBAS1002'\n", + "\n", + "print(f'Hei, {navn}')\n", + "print(f'{fag} - interessant!')\n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {fag}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60882272000002\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import math \n", + "\n", + "pi = 3.141592\n", + "r = 5.4 \n", + "h = 7.9\n", + "\n", + "print(f\"Har en sirkel med radius {r} som er grunnflate i en sylinder med høyde {h}\")\n", + "print(f\"Omkrets av sirkelen: {math.tau * r}\")\n", + "print(f\"Areal av sirkelen: {pi * r**2}\")\n", + "print(f\"Areal av sylinderen: {math.tau * r * h + 2 * math.pi * r ** 2}\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = 'Per'\n", + "ideal_alder = 42\n", + "kunde_alder = 37\n", + "differanse = ideal_alder - kunde_alder\n", + "print(f'{navn} er {differanse} år unna idealalderen')\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud4/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud4/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..cfdc033 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud4/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første jupyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Aurora\n", + "Da er du 37 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, \n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <Programmering er gøy>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud4/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud4/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud4/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud4/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud4/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..24ca13e --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud4/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1254 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"bool\") to str", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[75], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[39mprint\u001b[39m(a \u001b[39m+\u001b[39;49m b) \u001b[39m# Samme som å si -10 + 0\u001b[39;00m\n\u001b[0;32m 2\u001b[0m \u001b[39mprint\u001b[39m(b \u001b[39m-\u001b[39m c) \u001b[39m# Samme som 0 - 10\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[39mprint\u001b[39m(a \u001b[39m*\u001b[39m c) \u001b[39m# Samme som -10 * 10\u001b[39;00m\n", + "\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"bool\") to str" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "25\n" + ] + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return str(a) + str(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)\n", + "s1 = (10) + (15)\n", + "print(s1)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "47 12345678\n" + ] + } + ], + "source": [ + "telefonnummer = 12345678\n", + "landskode = 47\n", + "print(landskode, telefonnummer)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'legg_til_landskode' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[1], line 7\u001b[0m\n\u001b[0;32m 4\u001b[0m telefonnummer2 \u001b[39m=\u001b[39m \u001b[39m87654321\u001b[39m\n\u001b[0;32m 5\u001b[0m landskode2 \u001b[39m=\u001b[39m \u001b[39m46\u001b[39m\n\u001b[1;32m----> 7\u001b[0m \u001b[39mprint\u001b[39m(legg_til_landskode(telefonnummer1, landskode1))\n\u001b[0;32m 8\u001b[0m \u001b[39mprint\u001b[39m(legg_til_landskode(telefonnummer2, landskode2))\n", + "\u001b[1;31mNameError\u001b[0m: name 'legg_til_landskode' is not defined" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå True\n", + "c er nå False\n", + "d er nå 2\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = '2'\n", + "e = '2'\n", + "\n", + "\n", + "# Skriv koden din her\n", + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå True\n", + "c er nå False\n", + "d er nå 2\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 50 100 150]\n" + ] + } + ], + "source": [ + "# Skriv koden din her\n", + "import numpy as np \n", + "\n", + "def mult_list_with_x(l, x):\n", + " resultat = l * x \n", + " return resultat\n", + "\n", + "min_liste = np.array([10,20,30])\n", + "x=5\n", + "\n", + "print(mult_list_with_x(min_liste, x))\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'mult_list_with_x' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[77], line 4\u001b[0m\n\u001b[0;32m 1\u001b[0m liste \u001b[39m=\u001b[39m [\u001b[39m1\u001b[39m, \u001b[39m1.5\u001b[39m, \u001b[39m2\u001b[39m, \u001b[39m2.5\u001b[39m, \u001b[39m3\u001b[39m]\n\u001b[0;32m 2\u001b[0m skalar \u001b[39m=\u001b[39m \u001b[39m2\u001b[39m\n\u001b[1;32m----> 4\u001b[0m mult_list_with_x(liste, skalar)\n", + "\u001b[1;31mNameError\u001b[0m: name 'mult_list_with_x' is not defined" + ] + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2\n" + ] + } + ], + "source": [ + "print(round(1.234, 1))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(round(1.23456, 2))\n", + "print(round(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud4/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud4/variabler.ipynb" new file mode 100644 index 0000000..64ec783 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud4/variabler.ipynb" @@ -0,0 +1,592 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 5 = 10\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 5 = {2 * 5}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei Ada\n", + "Favorittfag? LBAS2002\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn = ('Ada')\n", + "fag = ('LBAS2002')\n", + "print('Hei', navn)\n", + "print('Favorittfag?', fag)\n", + "print('Ha en fin dag,', navn)\n", + "print('- og lykke til med', fag)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid decimal literal (1274524858.py, line 12)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m Cell \u001b[1;32mIn[42], line 12\u001b[1;36m\u001b[0m\n\u001b[1;33m 10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid decimal literal\n" + ] + } + ], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "idealAlder = 42\n", + "kundensAlder = 37\n", + "differanse = idealAlder - kundensAlder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud5/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud5/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..72b41a4 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud5/intro_til_jupyter.ipynb" @@ -0,0 +1,405 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hello world\n" + ] + } + ], + "source": [ + "print(\"hello world\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første jupyter-program\n", + "Nå skal programmet stille et spørsmål\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Hva heter du? Sindre\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei Sindre\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Hvor gammel er du? 27\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Da er du 32 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Dette var kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'message' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mmessage\u001b[49m)\n", + "\u001b[0;31mNameError\u001b[0m: name 'message' is not defined" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Hva heter du? \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, \n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** <Programering er gøy\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud5/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud5/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud5/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud5/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud5/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..69fea1f --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud5/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1249 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 2\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-8\n", + "-8\n", + "-100\n", + "20\n", + "-5.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n" + ] + }, + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[22], line 9\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mGratulerer, til sammen er dere \u001b[39m\u001b[38;5;132;01m{\u001b[39;00msum_alder\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m år!\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 7\u001b[0m sum_alder \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(alder) \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mint\u001b[39m(alder_mor)\n\u001b[0;32m----> 9\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mGratulerer, til sammen er dere \u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43msum_alder\u001b[49m \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m år!\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", + "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "47 12345678\n", + "47 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "telefonnummer2 = 87654321\n", + "\n", + "landskode1 = 47\n", + "landskode2 = 48\n", + "\n", + "print(landskode1, telefonnummer1)\n", + "print(landskode1, telefonnummer2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "46 87654321\n", + "47 12345678\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(landskode2, telefonnummer2)\n", + "print(landskode1, telefonnummer1)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = '1.5'\n", + "e = '2,45'\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå True\n", + "c er nå False\n", + "d er nå 1.5\n", + "e er nå 2,45\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2.0, 3.0, 5.0, 6.0] [[2.0, 3.0, 5.0, 6.0], 1]\n" + ] + } + ], + "source": [ + "liste =[2.0, 3.0, 5.0, 6.0]\n", + "skala = [l,1]\n", + " \n", + "print(liste, skala)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<built-in function array> 2\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "np.array([2.0, 3.0, 5.0, 6.0])\n", + "\n", + "skalar = 2\n", + "\n", + "print(np.array, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345: 12345.00\n", + "1000: 1000.0\n" + ] + } + ], + "source": [ + "print(f'1.2345: {12345:.2f}')\n", + "\n", + "print(f'1000: {1000:.1f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23456: 1.23\n", + "1234.5432: 1234.543200\n" + ] + } + ], + "source": [ + "print(f'1.23456: {1.23456:.2f}')\n", + "\n", + "print(f'1234.5432: {1234.5432:-3f}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud5/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud5/variabler.ipynb" new file mode 100644 index 0000000..cab1102 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud5/variabler.ipynb" @@ -0,0 +1,531 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.riabelnavnet **ikke** skal ha fn\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at vautter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 3 = 4\n", + "2 * 80 = 160\n" + ] + } + ], + "source": [ + "print(f'1 + 3 = {1 + 3}')\n", + "print(f'2 * 80 = {2 * 80}') " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid decimal literal (2066608501.py, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m Cell \u001b[0;32mIn[2], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m 4navn = \"Per\"\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid decimal literal\n" + ] + } + ], + "source": [ + "4navn = \"Per\"\n", + "ideal alder = 42\n", + "37 = kundensAlder\n", + "differanse = ideal alder - kundensAlder\n", + "print(f'{4navn} er {Differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud6/Intro til Jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud6/Intro til Jupyter.ipynb" new file mode 100644 index 0000000..cd8116f --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud6/Intro til Jupyter.ipynb" @@ -0,0 +1,341 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt program i jupyter\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Silje Melhus\n", + "Da er du 33 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt program i jupyter\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Svaret ditt:** <dobbelklikk her for å svare\\>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud6/Tall og Typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud6/Tall og Typekonvertering.ipynb" new file mode 100644 index 0000000..d629f42 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud6/Tall og Typekonvertering.ipynb" @@ -0,0 +1,1231 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "-10\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * -10\n", + "print(a - b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-3.0\n", + "5.4\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(d + e) # Samme som (1.2) + (-4.2)\n", + "print(d - e) # Samme som (1.2) - (-4.2)\n", + "print(f * e) # Samme som (0.0) * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "\n", + "def legg_til_landskode(telefonnummer, landskode):\n", + " return '+' + str(landskode) + ' ' + str(telefonnummer)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = 'True'\n", + "c = 'False'\n", + "d = '1.5'\n", + "e = '2.45'\n", + "\n", + "# Skriv koden din her\n", + "a = int(a)\n", + "b = int(True)\n", + "c = int(False)\n", + "d = int(1.5)\n", + "e = int(2.45)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 40 80 120 160 200]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " resultat = l*x\n", + " return resultat\n", + "\n", + "l = np.array([10,20,30,40,50])\n", + "\n", + "print(mult_list_with_x(l,4))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liste = [2.0, 3.0, 4.0, 5.0, 6.0]\n", + "skalar = 1\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23456 avrundet til 2 desimaler er: 1.23\n" + ] + } + ], + "source": [ + "# Skriv koden din her\n", + "def rund_av(tall, desimaler):\n", + " avrundet_tall = round(tall, desimaler)\n", + " return avrundet_tall\n", + "\n", + "print(f'1.23456 avrundet til 2 desimaler er: {1.23456:.2f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud6/Variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud6/Variabler.ipynb" new file mode 100644 index 0000000..8b080e6 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud6/Variabler.ipynb" @@ -0,0 +1,593 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 5 = 10\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 5 = {2 * 5}') # Her er det noe feil. Kan du fikse opp?\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn = 'Ada'\n", + "favorittfag = 'LBAS2002'\n", + "\n", + "print(f'Hei, {navn}')\n", + "print(f'{favorittfag} - interessant!')\n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {favorittfag}')\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2 \n", + "round\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.9\n", + "Areal av sirkelen: 91.6\n", + "Areal av sylinderen: 451.3\n" + ] + } + ], + "source": [ + "import math\n", + "import numpy as np\n", + "\n", + "r = 5.4\n", + "h = 7.9\n", + "\n", + "omkrets_sirkel = round(math.tau * r, 1)\n", + "areal_sirkel = round(np.pi * r**2, 1)\n", + "\n", + "areal_sylinder = round(math.tau * r * h + 2 * math.pi * r**2, 1)\n", + "\n", + "print(\"Har en sirkel med radius\", r, \"som er grunnflate i en sylinder med høyde\", h)\n", + "print(\"Omkrets av sirkelen:\", omkrets_sirkel)\n", + "print(\"Areal av sirkelen:\", areal_sirkel)\n", + "print(\"Areal av sylinderen:\", areal_sylinder)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid decimal literal (1274524858.py, line 12)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m Cell \u001b[1;32mIn[17], line 12\u001b[1;36m\u001b[0m\n\u001b[1;33m 10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid decimal literal\n" + ] + } + ], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn4 = \"Per\"\n", + "idealalder = 42\n", + "kundensAlder = 37\n", + "differanse = idealalder - kundensAlder\n", + "print(f'{navn4} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud7/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud7/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..59a22e8 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud7/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første jupyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Julie\n", + "Da er du 42 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Julie\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Programmering er gøy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud7/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud7/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud7/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud7/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud7/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..c5c1d8a --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud7/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1212 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "-1.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / c) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-3.0\n", + "5.4\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(d + e) # Samme som 1.2 + (-4.2)\n", + "print(d - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: True\n" + ] + } + ], + "source": [ + "gjort_oving = True\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = int(13)\n", + "alder_mor = int(37)\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print(f'Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = int(13)\n", + "alder_mor = int(37)\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def legg_til_landskode(telefonnummer, landskode):\n", + " return str(f'+') + str(landskode) + (' ') + str(telefonnummer)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = int(1)\n", + "b = int(True)\n", + "c = int(False)\n", + "d = int(1.5)\n", + "e = int(2.45)\n", + "\n", + "# Skriv koden din her" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2. 3. 4. 5. 6.]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " resultat = l*x\n", + " return resultat\n", + "\n", + "l = np.array([1, 1.5, 2, 2.5, 3])\n", + "print(mult_list_with_x(l,2))\n", + " \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 1.5, 2, 2.5, 3, 1, 1.5, 2, 2.5, 3]" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.2345 avrundet til 2 desimaler er: 1.23\n", + "5.4321 avrundet til 0 desimaler er: 5\n" + ] + } + ], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def rund_av(tall, desimaler):\n", + " return round(tall, desimaler)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud7/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud7/variabler.ipynb" new file mode 100644 index 0000000..ea3d6a9 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud7/variabler.ipynb" @@ -0,0 +1,589 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Julie\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Julie\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn = input('Hva heter du?')\n", + "fag = input('Hva er ditt favorittfag?')\n", + "\n", + "print(f'Hei, {navn}')\n", + "print(f'{fag} - interessant!')\n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {fag}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 16.964600329384883\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 317.23802615949734\n" + ] + } + ], + "source": [ + "import math\n", + "\n", + "radius = 5.4\n", + "hoyde = 7.9\n", + "o_sirkel = math.pi * radius\n", + "a_sirkel = math.pi * radius**2\n", + "a_sylinder = math.pi * radius * hoyde + 2 * math.pi * radius ** 2\n", + " \n", + "print(\"Har en sirkel med radius\", radius, \"som er grunnflate i en sylinder med høyde\", hoyde)\n", + "print(\"Omkrets av sirkelen:\", o_sirkel) \n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "print(\"Areal av sylinderen:\", a_sylinder)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "ideal_alder = 42\n", + "kundens_alder = 37\n", + "differanse = ideal_alder - kundens_alder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud8/aritmetiske_uttrykk.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud8/aritmetiske_uttrykk.ipynb" new file mode 100644 index 0000000..1b84685 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud8/aritmetiske_uttrykk.ipynb" @@ -0,0 +1,424 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "4aadc21c", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Aritmetiske uttrykk\n", + "\n", + "Motivasjon\n", + "- Datamaskiner er gode til å regne raskt\n", + " - kan også regne veldig mye _feil_ veldig raskt\n", + " - hvis vi skriver feilaktige aritmetiske uttrykk" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "d38d3327", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "__Viktig å skrive aritmetiske uttrykk riktig!__" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "be0de705", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "Disposisjon\n", + "- Skrive tall i Python\n", + "- Vanlige regneoperatorer\n", + "- Presedens (regnerekkefølge) og parentesbruk\n", + "- Uttrykk med variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "15d3717a", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Tall i Python\n", + "|Type tall|Eksempel|Python|Merknad|\n", + "|:-------|:----------|:------|:-------|\n", + "|Desimaltall|$3,25$ |3.25| __.__ før desimal|\n", + "|Lange heltall|1.000.000 |1000000|~oppdeling~|\n", + "||1,000,000 |1000000|~oppdeling~|\n", + "|Vitsk.notasjon|$$1.6 \\cdot 10^{12}$$ |1.6e12|1600000000000|\n", + "||$$1.6 \\cdot 10^{-9}$$ |1.6e-9|0.0000000016|\n", + "|Komplekse tall|2+3i|(2+3j)|$$2+3\\sqrt{-1}$$|" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7649c678", + "metadata": { + "scrolled": true, + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "3.25" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5145893e", + "metadata": {}, + "outputs": [], + "source": [ + "3e2" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "937cc562", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Vanlige regneoperatorer\n", + "\n", + "|Operator|Eksempel|Python|Merknad|\n", + "|:-------|----------|------|-------|\n", + "|Addisjon|$3+2.5$|3 + 2.5| |\n", + "|Subtraksjon|$3-2.5$|3 - 2.5| bindestrek |\n", + "|Multiplikasjon|$3\\cdot2.5$|3 \\* 2.5| \\*|\n", + "||$(-3)2$|(-3) * 2|Gangetegn _må_ med|\n", + "|Potens|$2^3$|2 \\*\\* 3|2\\*2\\*2 blir 8|\n", + "|Divisjon|$7\\colon2$ eller $\\frac{7}{2}$|7 / 2|Blir 3.5|\n", + "|Heltallsdivisjon|$7\\colon2$|7 // 2|Blir 3|\n", + "|Modulo|rest av $7\\colon2$|7 % 2|Blir 1|\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bab7fcaf", + "metadata": {}, + "outputs": [], + "source": [ + "-2**2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34aa32d0", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "523 // 100" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "907b587c", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "523 % 100" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "9313ef4e", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Bruk av mellomrom i aritmetiske uttrykk\n", + "- valgfritt å ha mellomrom _rundt_ aritmetiske operatorer\n", + " - ofte anbefalt for bedre lesbarhet\n", + "- forbudt med mellomrom _i_ aritmetiske operatorer\n", + " - ** og // må skrives med symbolene kloss sammen" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b1c97c9", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "5//2, 5 // 2, 2**3, 2 ** 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d99e626e", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "5/ /2, 2* *3" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "8f5c98f5", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Operatorpresedens, parentesbruk\n", + "(Regnerekkefølge)\n", + "\n", + "|Operatorer|Presedens|\n", + "|:-----|:------|\n", + "|\\*\\*|høy|\n", + "|\\* / // %|middels|\n", + "|+ -|lav|" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "4dcd2135", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Som i matematikken: bruk parentes for å endre rekkefølge:\n", + "\n", + "|Uttrykk|Resultat|Fordi|\n", + "|:-----|:------|:-----|\n", + "|5 + 2 \\* 3 |11|ganger først, plusser etterpå|\n", + "|(5 + 2) \\* 3|21|plusser først, ganger etterpå|\n", + "|5 \\* 3 \\*\\* 2|45|potenserer først, ganger etterpå|\n", + "|(5 \\* 3) \\*\\* 2|225|ganger først, potenserer etterpå|\n", + "|(6 - (5-2) // 3) \\* 4|20|innerste parentes først, // før -|" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "97808599", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "(-3)**2" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "070c1d63", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Parentesbruk, forskjell matematikk - Python\n", + "Det meste er likt, men\n", + "- Python: kun én type parentes ()\n", + " - \\{ \\} og \\[ \\] brukes til andre formål i Python\n", + " - kan __ikke__ brukes til å endre regnerekkefølge\n", + "- Python trenger () noen flere sted enn matte-uttrykk\n", + " - f.eks. hvor () unødig i matte-uttrykk pga layout\n", + "\n", + "|Matematikk |Python |Merknad |\n", + "|:-------------------------|:--------------------------|:--------------------------------|\n", + "|$5^{2+3}$|5 \\*\\* (2 + 3)|parentes i Python|\n", + "|$\\frac{5+2}{3-2}$|(5 + 2) / (3 - 2)|parentes i Python|\n", + "|$3\\{2+[0.5-0.7(1+3)+5]-2\\}$|3\\*(2 + (0.5 - 0.7 \\* (1 + 3) + 5) - 2)|kun () i Python|" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3066cd87", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "(5 + 2) / (3 - 2)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "aef631ef", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Uttrykk med variable\n", + "\n", + "|Matematikk |Python|\n", + "|:-----------------|:----------------------------|\n", + "|$2x + 3$ |2 \\* x + 3 |\n", + "|$5^{a+b}$ |5 \\*\\* (a + b) |\n", + "\n", + "Operatorer og presedens som før. \n", + "\n", + "Variable __MÅ__ få verdi før uttrykk kan kjøres i Python" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3d01ee0a", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "x = 2.5\n", + "2 * x + 3" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "411e2ce9", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Oppsummering\n", + "- Tall\n", + " - 1000000 (~oppdeling~)\n", + " - 2.35 (desimalpunktum)\n", + " - 3.25e-15 (vitsk.notasjon)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "7cd265d4", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "- Operatorer: + - * / // % **\n", + " - ikke utelate *" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "26acfc5e", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "- Uttrykk med variable\n", + " - Variable __må__ ha fått verdi før kjøring" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "68fd6020", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "- Presedens og parentesbruk\n", + " - som i matematikken\n", + " - Kun én type () \n", + " - Ekstra parenteser f.eks. horisontal brøkstrek" + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.6" + }, + "rise": { + "scroll": true, + "start_slideshow_at": "beginning", + "theme": "sky" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud8/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud8/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..db82813 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud8/intro_til_jupyter.ipynb" @@ -0,0 +1,385 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er et program i jupyter\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Ane\n", + "Da er du 27 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er et program i jupyter\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow! Dette var kult!\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow! Dette var kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ane\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** Programmering er gøy." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud8/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud8/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud8/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud8/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud8/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..8b38b4f --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud8/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1257 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-10\n", + "-10\n", + "-100\n", + "0\n", + "-1.0\n" + ] + } + ], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / c) # Samme som -10 : 10" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5.8\n", + "14.2\n", + "-0.0\n" + ] + } + ], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n" + ] + }, + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[27], line 9\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mGratulerer, til sammen er dere \u001b[39m\u001b[39m{\u001b[39;00msum_alder\u001b[39m}\u001b[39;00m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m 7\u001b[0m sum_alder \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(alder) \u001b[39m+\u001b[39m \u001b[39mint\u001b[39m(alder_mor)\n\u001b[1;32m----> 9\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39;49m\u001b[39m'\u001b[39;49m\u001b[39mGratulerer, til sammen er dere \u001b[39;49m\u001b[39m'\u001b[39;49m \u001b[39m+\u001b[39;49m sum_alder \u001b[39m+\u001b[39m \u001b[39m'\u001b[39m\u001b[39m år!\u001b[39m\u001b[39m'\u001b[39m)\n", + "\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return a + b\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "def legg_til_landskode(telefonnummer, landskode):\n", + " return '+' + str(landskode) + ' ' + str(telefonnummer)\n", + " #alternativ løsning: return f'+{landskode} {telefonnummer}'" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+47 12345678\n", + "+46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode(telefonnummer1, landskode1))\n", + "print(legg_til_landskode(telefonnummer2, landskode2))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = 1.5\n", + "e = 2.45\n", + "\n", + "# Skriv koden din her\n", + "a = int(a)\n", + "b = int(b)\n", + "c = int(c)\n", + "d = int(d)\n", + "e = int(e)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "# Skriv koden din her\n", + "def mult_list_with_x(l, x):\n", + " return list(x * np.array(l))\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Skriv koden din her\n", + "def rund_av(tall, desimaler):\n", + " return round (tall, desimaler)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.23\n", + "1000.0\n" + ] + } + ], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud8/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud8/variabler.ipynb" new file mode 100644 index 0000000..b48257e --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud8/variabler.ipynb" @@ -0,0 +1,581 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp?" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "navn='Ada'\n", + "fag='LBAS2002'\n", + "print(f'Hei, {navn}')\n", + "print(f'{fag} - interessant!')\n", + "print(f'Ha en fin dag, {navn}')\n", + "print(f'- og lykke til med {fag}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.9\n", + "Areal av sirkelen: 91.6\n", + "Areal av sylinderen: 451.3\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + "radius=5.4\n", + "høyde=7.9\n", + "omkrets=2*np.pi*radius\n", + "areal_sirkel=np.pi*radius**2\n", + "\n", + "print(\"Har en sirkel med radius\", radius, \"som er grunnflate i en sylinder med høyde\", høyde)\n", + "print(\"Omkrets av sirkelen:\", round(omkrets,1)) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", round(areal_sirkel,1))\n", + "print(\"Areal av sylinderen:\", round(omkrets * høyde + 2*areal_sirkel,1))\n", + "\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er 5 år unna idealalderen\n" + ] + } + ], + "source": [ + "navn = \"Per\"\n", + "idealalder = 42\n", + "kundensalder = 37\n", + "differanse = idealalder - kundensalder\n", + "print(f'{navn} er {differanse} år unna idealalderen')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud9/intro_til_jupyter.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud9/intro_til_jupyter.ipynb" new file mode 100644 index 0000000..0f6c72b --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud9/intro_til_jupyter.ipynb" @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Introduksjon til Jupyter\n", + "\n", + "Hei, og velkommen til Jupyter, en annen måte å skrive kode på! Jupyter er et system som lar deg lage dokumenter som inneholder både tekst og kode på en gang. Det fine her er at du kan kjøre koden i dokumentet og se resultatet umiddelbart. Dette kan du prøve ut nå. \n", + "\n", + "**oppgave a)** Klikk på kodeblokken under og trykk `ctrl + enter` på tastaturet for å kjøre koden. (Det er også mulig å klikke på kodeblokken for så å klikke `run` i menyen på toppen)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Velkommen til Jupyter\n" + ] + } + ], + "source": [ + "print(\"Velkommen til Jupyter\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser kommer resultatet av koden ut rett nedenfor kodeblokken. Dette er veldig praktisk og du kan kjøre koden så mange ganger du vil! Hvis du trykker på `ctrl + enter` i kodeblokken over en gang til vil du se at tallet til venstre for kodeblokken øker. Dette tallet brukes bare som referanse og er ikke noe du trenger å tenke på til vanlig.\n", + "\n", + "Alle kodeblokker i et dokument kan endres på, og dette oppfordres på det sterkeste! Det er mye god læring i å endre kode, tenke seg til hva som skal skje og sjekke om dette faktisk skjer. Du kan for eksempel prøve å kjøre programmet under med `ctrl + enter`, gjøre et par endringer og sjekke om den nye versjonen din gjør det du hadde tenkt." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "**Oppgave b)** Endre første linje i koden under til `print(\"Dette er mitt første Jupyter-program\")`" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dette er mitt første jupyter-program\n", + "Nå skal programmet stille et spørsmål\n", + "Hei Vendela\n", + "Da er du 32 år gammel om 5 år\n" + ] + } + ], + "source": [ + "print(\"Dette er mitt første jupyter-program\") #endre denne linjen\n", + "print(\"Nå skal programmet stille et spørsmål\")\n", + "navn = input(\"Hva heter du? \")\n", + "print(\"Hei\", navn)\n", + "\n", + "alder = int(input(\"Hvor gammel er du? \")) # Her må du kun skrive et tall\n", + "print(\"Da er du\", alder + 5, \"år gammel om 5 år\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variabler mellom kodeblokker" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Noe som er verdt å merke seg er at data kan eksistere mellom kodeblokkene i en Jupyter Notebook. La oss se på et eksempel. Trykk `ctrl + enter` i kodeblokken nedenfor slik at den kjører." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Wow, Jupyter er kult!\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør så kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wow, Jupyter er kult!\n" + ] + } + ], + "source": [ + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser får vi printet ut verdien av `message` selv om `message` ikke er definert i den nederste kodeblokken. Dette kan være veldig praktisk, men kan noen ganger være forvirrende. Prøv å endre på verdien til `message` (\"Wow! Dette var kult!\") i den første kodeblokken, for så å trykke `ctrl + enter` i den andre blokken.\n", + "\n", + "Som du ser er ikke `message` blitt oppdatert. Dette er fordi **vi er nødt til å kjøre kodeblokken med `message =` for at `message` skal bli oppdatert**. \n", + "\n", + "Prøv nå å kjøre kodeblokken med `message =` igjen for så å kjøre blokken med `print` på nytt. Da burde riktig melding printes.\n", + "\n", + "**Oppgave c)** Endre message til `\"Wow, Jupyter er kult!\"`, og print det ut i blokken under.\n", + "\n", + "Dette gjelder ikke bare for *variabler*, men også for *funksjoner*, som dere skal lære å bruke etterhvert. Hvis du skriver en funksjon og ønsker å bruke den i en annen kodeblokk må du kjøre kodeblokken hver gang funksjonen endres akkurat som med variabler." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Restarting dersom problemer skulle oppstå" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du ønsker å fjerne all output fra dokumentet og *starte på nytt* kan du trykke på `Kernel -> Restart and clear output` i menyen på toppen. Det vil komme opp en boks med en skummel rød knapp, men dette går helt fint. Å kunne restarte kan også være nyttig hvis dokumentet henger seg opp. Dette skal vi se et eksempel på nå.\n", + "\n", + "Kjør kodeblokken under to ganger uten å taste inn noe i inputfeltet som dukker opp (du må trykke på blokken igjen for å kjøre den andre gang)." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Vendela\n" + ] + } + ], + "source": [ + "navn = input(\"Hva heter du?\")\n", + "print(\"Hei,\", navn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette var veldig uheldig. Nå skjer det ingenting og vi kan heller ikke kjøre andre kodeblokker i dokumentet :(\n", + "\n", + "Når en kodeblokk venter på input kan man ikke kjøre andre kodeblokker, så hvis man da prøver å kjøre andre kodeblokker vil disse bli satt på vent.\n", + "\n", + "Nå ser vi at det står `In [*]` ved flere av blokkene våre, dette betyr at de venter på andre blokker før de selv kjører, i vårt tilfelle kjørte vi input-blokken på nytt, uten å gi inn noe til forrige kjøring av blokken. Programmet venter fortsatt på input til forrige kjøring av blokken, selv om feltet er borte, som ikke er helt optimalt! Om du ikke forstår helt hva som skjer her er ikke det noe farlig. For å komme oss ut av dette kan vi restarte med `Kernel -> Restart and clear output` i toppmenyen. **Merk: Dette endrer ikke på koden du selv har skrevet.**\n", + "\n", + "**Oppgave d)** Restart notebooken med kommandoen beskrevet over." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Endring av tekst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er også mulig å endre på teksten i et dokument ved å dobbelklikke på en tekstboks, men dette er noe du sjeldent trenger å gjøre. For å gjøre teksten «vanlig» igjen etter at du har endret trykker du her også på `ctrl + enter`.\n", + "\n", + "Jupyter bruker noe som heter markdown til formatering av tekst. Dette er ikke pensum, men hvis du ønsker å se litt på det finnes det en ganske fin oversikt (på engelsk) [her](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet?fbclid=IwAR2PRFaYr3YAPnKBzNRpgaumRufU4WHbT6Xd-0v9EsJwxtgqxOyzLluvPOA#tables). Det er også mulig å legge til LaTeX (et tekst-format til å lage fine matteuttrykk) i jupyter-tekstbokser. Dette er heller ikke pensum.\n", + "\n", + "Hvis vi skal be dere om et tekst-svar vil vi dere se noe sånt som under. Her kan dere selv fjerne det som står inne i krokodilletegnene.\n", + "\n", + "**Oppgave e)** Endre tekstboksen under til `Programmering er gøy`. *Merk: I en tekstboks trenger man ikke skrive python-kode*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Ditt svar:** Programmering er gøy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# En advarsel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Jupyter er generelt ikke så glad i at du har samme dokument åpnet i flere faner. Hvis du har dette er det mulig at endringene du gjør i den ene fanen overskriver endringene du gjør i en annen fane, noe som kan være uheldig. Sørg derfor for at du aldri har mer enn en fane åpnet med det samme dokumentet." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "# Til slutt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "source": [ + "Det er mange muligheter som ligger inne i jupyter, og vi skal ikke bruke alt i dette kurset. Det er ingenting som hindrer dere fra i å finne andre jupyter-notatbøker på nettet selv hvis dere ønsker mer utfordring eller å utforske hva som er mulig.\n", + "\n", + "**Lykke til videre med jupyter!**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud9/lab-1.md" "b/\303\270vinger/\303\270ving_1/innlevering/stud9/lab-1.md" new file mode 100644 index 0000000..548bb68 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud9/lab-1.md" @@ -0,0 +1,14 @@ +# Lab-1 + +### Læringsutbytte + +* Komme i gang med jupyter (skjønne forskjellen mellom markdown, python, html) +* Kunne skrive enkel Python program som inneholder: kommentar, kode som skriver til skjerm og leser fra tastatur. +* Kunne definere variabler +* Kunne konvertere mellom enkle datatyper + +### Læringsaktiviteter + +* [Introduksjon til Jupyter](intro_til_jupyter.ipynb) +* [Tall- og Typekonvertering](tall_og_typekonvertering.ipynb) +* [Variabler](variabler.ipynb) diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud9/tall_og_typekonvertering.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud9/tall_og_typekonvertering.ipynb" new file mode 100644 index 0000000..393e7c7 --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud9/tall_og_typekonvertering.ipynb" @@ -0,0 +1,1190 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Tall- og Typekonvertering\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Datatyper\n", + "* Konvertering mellom datatyper\n", + "* Funksjoner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## Tutorial: Datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I Python, og andre programmeringsspråk, kan data ha forskjellige _typer_. Forskjellige datatyper egner seg for forskjellige bruksområder. For eksempel hvis vi skal lagre alderen til en person, vil det lønne seg å lagre dette i en `int`. Navnet til samme person, derimot, bør være en `string`. \n", + "\n", + "Det finnes mange forksjellige datatyper, men vi skal ikke gå igjennom alle her. Det kommer i en senere øving. De du skal lære her er:\n", + "\n", + "* **Integer** - et heltall. F.eks `10`. I Python brukes `int` for en integer\n", + "* **Float** - et flyttall (tall med desimal). F.eks `10.5`\n", + "* **String** - tekst. F.eks `\"ITGK\"`. I Python brukes `str` for en string\n", + "* **Boolean** - sannhetsverdi. Enten `True` eller `False`. I Python brukes `bool` for boolean\n", + "* **List** - en liste med verdier. En liste inneholder variabler/verdier av hvilken som helst datatype. F.eks `[1, 2, \"Er ITGK kult?\", True]`\n", + "* **ndarray**/**np.array** - et array. F.eks `np.array([1,2,3,4])`. \n", + "\n", + "Les mer om de forksjellige datatypene nedenfor:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Integer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers er enten et negativt heltall, 0 eller et positivt heltall. Som kjent fra matematikken er Integers tallene denotert som $\\mathbb{Z}$. (les mer om Integers i matematikken [her](https://en.wikipedia.org/wiki/Integer). La oss nå lage noen ints i Python, det er utrolig lett. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "a = -10\n", + "b = 0\n", + "c = 10" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Integers følger et set med regler, akkurat som i matematikken. Vi kan for eksempel addere integers, hvor resultatet også vil være en integer. Det samme gjelder for multiplikasjon. Utfører vi _divisjon_ med to integers derimot, vil resultatet være en `float`. La oss gjøre litt aritmetiske operasjoner på ints. Prøv å kjøre kodeblokken under:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(a + b) # Samme som å si -10 + 0\n", + "print(b - c) # Samme som 0 - 10\n", + "print(a * c) # Samme som -10 * 10\n", + "print(b * c) # Samme som 0 * c\n", + "print(a / b) # Samme som -10 : 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Whoops, ser du koden over ga en feilmelding? Karer du å se hva feilen er? Hvis ikke er ikke det så farlig, vi forteller deg nå; på siste linje prøver vi å dele på `0`. Dette vet vi fra matematikken at er fyfy, og det samme gjelder i Python. Det som er fint med Python ovenfor matetmatikken er at Python sier ifra når du gjør noe som ikke er lov, slik som over. Det aller verste som kan skje er at programmet kræsjer, og vi må fikse opp i bugs. Se om du klarer å fikse opp i feilen over, slik at programmet kjører uten å kræsje." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Float" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Floats oppfører seg på nesten samme måte som Integers. De består av de rasjonale tallene $\\mathbb{Q}$. De skiller seg fra Integers ved at de kan ligge mellom heltall. La oss lage noen floats. Kjør kodeblokken nedenfor:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "d = 1.2\n", + "e = -4.2\n", + "f = 0.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som med `int`s kan vi utføre aritmetiske operasjoner på floats. Kjør kodeblokken under og se at du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(c + e) # Samme som 1.2 + (-4.2)\n", + "print(c - e) # Samme som 1.2 - (-4.2)\n", + "print(f * e) # Samme som 0.0 * (4.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### String" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "String er en datatype som inneholder tekst. For å lage en streng skriver vi tekst omringet av \"fnutter\". Vi kan bruke både enkeltfnutter `'Jeg er en streng'`, dobbeltfnutter `\"Jeg er en annen streng\"` eller trippelfnutter `\"\"\"Jeg er enda en streng\"\"\"`. Alle tre måtene å skrive strenger på er like riktig, men de har forskjellige bruksområder. Enkelt- og dobbeltfnutter er veldig like. En av forskjellene er at om du bruker enkeltfnutter, kan du ha dobbeltfnutter i teksten uten noe problem, og omvendt ved bruk av dobbeltfnutter. For eksempel `'Ordet \"stein\" kan være både et navn og et objekt man finner i naturen'` eller `\"Ordet 'stein' kan være både et navn og et objekt man finner i naturen\"`. Trippeltfnutter lager såkalte \"multiline\"-strenger. Altså kan vi få strenger på flere linjer. Kjør kodeblokken under og se om du forstår hva som skjer:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en streng med enkeltfnutter\n", + "Jeg er en streng med dobbeltfnutter\n", + "Jeg er en\n", + "multiline streng\n" + ] + } + ], + "source": [ + "s1 = 'Jeg er en streng med enkeltfnutter'\n", + "s2 = \"Jeg er en streng med dobbeltfnutter\"\n", + "s3 = \"\"\"Jeg er en\n", + "multiline streng\"\"\"\n", + "\n", + "print(s1)\n", + "print(s2)\n", + "print(s3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Vi kan ikke gjøre aritmetiske operasjoner på strenger, på samme måte som `int`s og `float`s. Det betyr derimot ikke at vi ikke kan bruke matematiske operatorer på strenger:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "101520\n" + ] + } + ], + "source": [ + "s4 = '10' + '15' + '20'\n", + "print(s4)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`+` operatoren \"setter sammen\" strenger. Som i eksempelet over setter vi sammen, eller konkatinerer, tre strenger; `'10'`, `'15'` og `'20'`, til én stor streng `'101520'`. Du ser forhåpentligvis at tallene `10`, `15` og `20` _ikke_ blir addert til `45` slik de ville blitt om de var `int`s eller `float`s, men strengene blir konkatinert. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10101010101010101010\n" + ] + } + ], + "source": [ + "s5 = '10' * 10\n", + "print(s5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "`*` operatoren ganger strengen antall ganger. I eksempelet over ganger vi strengen `'10'` med `10`, og får den resulterende strengen `'10101010101010101010'` ('10' 10 ganger), ikke `100` som om vi hadde ganget `int`en `10` med `int`en `10`. Operatorene `-` og `/` kan vi ikke bruke på strenger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Innimellom er det fint å ha andre datatyper inne i strenger. Dette gjøres lett med **f-strings**:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg er en f-string, og jeg kan ha for eksempel ints i meg: 12345, eller floats: 123.45\n" + ] + } + ], + "source": [ + "s6 = f'Jeg er en f-string, og jeg kan ha for eksempel ints i meg: {12345}, eller floats: {123.45}'\n", + "print(s6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som er verdt å merke seg med **f-strings** er at så fort andre datatyper blir inkorporert inne i strengen, er de ikke lenger sin egen datatype. De er nå en del av den nye strengen. F-strings er helt vanlige strenger, men de er litt lettere å formatere de. Inne i krøllparentesene {} kan vi ha stort sett det vi vil, også variabler:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her er et tall: 12345\n" + ] + } + ], + "source": [ + "tall = 12345\n", + "s7 = f'Her er et tall: {tall}'\n", + "print(s7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Boolean" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "En `bool` er en sannhetsverdi, enten `True` eller `False`, og er en _veldig_ sentral datatype i programmering. Booleans kan brukes for eksempel til å sjekke om en alder er under eller over `18`." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Jeg har gjort øvingen min: False\n" + ] + } + ], + "source": [ + "gjort_oving = False\n", + "print(f'Jeg har gjort øvingen min: {gjort_oving}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Senere i emnet vil du lære om if-setninger. Da står booleans sentralt. En liten smakebit her:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### List" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lister er en annen fundamental datatype i Python. Lister er er en samling av verdier, enten av andre datayper, eller av lister selv. For å lage en liste brukes klammeparantesene []. Inne i klammene legger vi verdiene våre, sparert med komma. Prøv å kjøre kodeblokken under, gjerne endre på verdiene også." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med tall: [1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1, 2, 3, 4]\n", + "print(f'Her har du en liste med tall: {liste_med_tall}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Du vil lære mer om lister senere, som for eksempel hvordan du henter ut elementer. Det viktigste for nå er å vite hvordan du oppretter en :) Lister kan som sagt inneholde flere forskjellige datatyper:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Her har du en liste med forskjellige verdier: [1.0, 4, True, 'hei på deg']\n" + ] + } + ], + "source": [ + "liste_med_forskjellige_verdier = [1.0, 4, True, 'hei på deg']\n", + "print(f'Her har du en liste med forskjellige verdier: {liste_med_forskjellige_verdier}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "På samme måte som strenger kan vi ikke gjøre vanlige matematiske operasjoner på lister. Vi kan derimort gange en liste med et tall, og plusse sammen lister. Oppførselen blir det samme som når vi ganger en streng med et tall, eller plusser sammen to strenger. _Elementente_ i listen blir ikke ganget med tallet, de vil bli replikert X ganger. _Elementene_ i listene vil heller ikke bli plusset sammen ved bruk av `+`, men den ene listen blir lagt til i den andre listen:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5, 6, 7, 8]\n", + "[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "liste_med_tall = [1,2,3,4]\n", + "liste_med_tall2 = [5,6,7,8]\n", + "\n", + "liste2 = liste_med_tall + liste_med_tall2\n", + "print(liste2)\n", + "\n", + "liste3 = liste_med_tall * 10\n", + "print(liste3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial: Konvertering mellom datatyper" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Vi kan ha ulike typer data, som tekststrenger (f.eks. `\"Python\"`), heltall (f.eks. `42`), flyttall (f.eks. `9.80`) og sannhetsverdier (`True`, `False`). Ofte kommer vi i situasjoner hvor vi har data av en viss type, men vi trenger samme data bare med en annen type. Da må vi konvertere dataene. Noen vanlige konverteringsfunksjoner:\n", + "\n", + "**`int()`** - konverterer til heltall.\n", + "- `int('423')` gir 423 (dvs. tekststrengen blir konvertert til et tall). Virker kun hvis tekststrengen faktisk inneholder et heltall.\n", + "- `int(5.69)` gir 5 (dvs. for flyttall blir desimaldelen fjernet)\n", + "\n", + "**`float()`** - konverterer til flyttall\n", + "- `float('5.69')` gir 5.69 (tekststreng konvertert til tall)\n", + "- `float('5')` gir 5.0, dvs. float() virker på tekststrenger enten de inneholder flyttall eller heltall (men ikke på strenger som er noe annet enn tall)\n", + "- `float(5)` gir 5.0\n", + "\n", + "**`str()`** - konverterer til tekststreng\n", + "- `str(42)` gir '42'\n", + "- `str(5.69)` gir '5.69'\n", + "Koden under feiler fordi vi har glemt å konvertere. Kjør den og se hva som skjer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + sum_alder + ' år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Den første feilen viser seg i linjen \"Gratulerer...\" Summen skulle ha blitt 50 år. Men vi har de to alderne fortsatt bare lagret som tekststrenger. Da betyr `+` å hekte sammen strengene, ikke å gjøre noen addisjon. Altså får vi `'13' + '37'` som blir `'1337'` heller enn `13 + 37` som blir `50`. Her måtte vi ha konvertert fra tekst til tall før vi gjorde addisjonen.\n", + "\n", + "Den andre feilen oppstår i den siste print-setningen. Vi har på linjen over kalkulert rett alder, ved å konvertere `alder` og `alder_mor` til `int`. Problemet nå ligger i at vi prøver å legge sammen en `string` og en `int`. Som feilmeldingen sier; \"can only concatenate str (not \"int\") to str\". En mulig løsning er å konvertere `sum_alder` tilbake til `string` nå, slik av vi kan plusse sammen to strenger, eller bruke f-strings. Mulige løsninger vises under:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gratulerer, til sammen er dere 1337 år!\n", + "Gratulerer, til sammen er dere 50 år!\n", + "Gratulerer, til sammen er dere 50 år!\n" + ] + } + ], + "source": [ + "alder = '13'\n", + "alder_mor = '37'\n", + "sum_alder = alder + alder_mor\n", + "\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')\n", + "\n", + "sum_alder = int(alder) + int(alder_mor)\n", + "\n", + "print('Gratulerer, til sammen er dere ' + str(sum_alder) + ' år!')\n", + "print(f'Gratulerer, til sammen er dere {sum_alder} år!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Altså: bruker `int()` i linje 7, dette gjør at vi får heltall i variablene `alder` og `alder_mor` så vi blir i stand til å regne med dem. Bruker deretter `str()` i linje 9 så denne opplysningen kan settes sammen med annen tekst og brukes i `print()`. Dette eksemplet viser dermed både et tilfelle hvor vi har tekst men trenger tall, og ett hvor vi har et tall men trenger tekst. Hvis det er vi trenger et desimaltall på alder (f.eks. `13.5`) vil imidlertid koden over ikke funke. Da måtte vi ha brukt funksjonen `float()` der vi nå har brukt `int()`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "I koden under er det noe feil. Finn feilene og rett opp i de" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Rett utskrift skal være:\n", + "\n", + "```python\n", + "25\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T11:24:13.550825Z", + "start_time": "2019-07-01T11:24:13.542723Z" + }, + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def legg_sammen_to_tall(a, b):\n", + " return int(a) + int(b)\n", + "\n", + "legg_sammen_to_tall(10, 15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `legg_til_landskode(telefonnummer, landskode)` som tar inn `telefonnummer` (`int`) og `landskode` (`int`) som parametere og returnerer telefonnummetet prefixet med \"+\", landskode og et mellomrom.\n", + "\n", + "***Skriv koden din i kodeblokken udner***" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+ 47 12345678\n", + "+ 46 87654321\n" + ] + } + ], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print('+', str(landskode1), str(telefonnummer1))\n", + "print ('+', str(landskode2), str (telefonnummer2)) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under gi ut:\n", + "\n", + "```python\n", + "+47 12345678\n", + "+46 87654321\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "telefonnummer1 = 12345678\n", + "landskode1 = 47\n", + "\n", + "telefonnummer2 = 87654321\n", + "landskode2 = 46\n", + "\n", + "print(legg_til_landskode (telefonnummer1, landskode1))\n", + "print(legg_til_landskode (telefonnummer2, landskode2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Kodeblokken nedenfor innheholder noen variabler. Konverter alle til `int`. **Merk**: Det lurer seg kanskje noen feil i koden!" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n" + ] + } + ], + "source": [ + "a = '1'\n", + "b = True\n", + "c = False\n", + "d = '1.5'\n", + "e = '2,45'\n", + "\n", + "# Skriv koden din her\n", + "print ('a', 'er nå', 1) \n", + "print ('b', 'er nå', 1)\n", + "print ('c', 'er nå', 0)\n", + "print ('d', 'er nå', 1)\n", + "print ('e', 'er nå', 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis du har gjort alt rett, skal kodeblokken under skrive ut:\n", + "\n", + "```python\n", + "a er nå 1\n", + "b er nå 1\n", + "c er nå 0\n", + "d er nå 1\n", + "e er nå 2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a er nå 1\n", + "b er nå True\n", + "c er nå False\n", + "d er nå 1.5\n", + "e er nå (2, 45)\n" + ] + } + ], + "source": [ + "print(f'a er nå {a}')\n", + "print(f'b er nå {b}')\n", + "print(f'c er nå {c}')\n", + "print(f'd er nå {d}')\n", + "print(f'e er nå {e}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "## d)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Lag en funksjon `mult_list_with_x(l, x)` som tar inn en liste `l` og skalar `x` som parametere og returnerer en _liste_ hvor alle elementene er multiplisert med `x`.\n", + "\n", + "***Skriv koden din i kodeblokken nedenfor***" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2.0, 3.0, 4.0, 5.0, 6.0]" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Skriv koden din her\n", + "import numpy as np\n", + "\n", + "def mult_list_with_x(l, x):\n", + " resultat = l*x\n", + " return resultat\n", + "l = np.array([1,1.5,2,2.5, 3])\n", + "\n", + "list(mult_list_with_x(l,2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken nedenfor gi output:\n", + "\n", + "```python\n", + "[2.0, 3.0, 4.0, 5.0, 6.0]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "liste = [1, 1.5, 2, 2.5, 3]\n", + "skalar = 2\n", + "\n", + "mult_list_with_x(liste, skalar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Hint" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Her må du bruke **numpy** og `np.array()`. For å gjøre om fra et array til en liste kan du bruke `list()`. Husk også å importere **numpy** med `import numpy as np`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2: avrunding av flyttall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Ofte har man flyttall, men trenger heltall, f.eks. hvis man skal bruke innebygde Python-funksjoner som krever heltall som argument, eller skal bruke tallet som indeks til en streng eller liste (som vi vil se senere i pensum). Flyttall kan konverteres til heltall med funksjoner som `int()` eller `round()`. Kodeblokka under viser litt forskjell på hvordan disse virker." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\n", + "int(2.25) er 2\n", + "int(2.5) er 2\n", + "int(2.99) er 2\n", + "round() runder av til nærmeste heltall, f.eks.\n", + "round(2.25) er 2\n", + "round(2.51) er 3\n", + "Hva hvis tallet er midt mellom to heltall?\n", + "round(2.5) er 2\n", + "round(3.5) er 4\n", + "round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\n", + "Mens int() alltid gir heltall kan round() brukes for antall desimaler:\n", + "round(2.5488, 1) blir 2.5\n", + "round(2.5488, 3) blir 2.549\n", + "Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\n", + "round(12345.67, -3) blir 12000.0\n" + ] + } + ], + "source": [ + "print(\"int() bare kutter desimalene, uansett hvor stor eller liten desimaldelen er:\")\n", + "print(\"int(2.25) er\", int(2.25))\n", + "print(\"int(2.5) er\", int(2.5))\n", + "print(\"int(2.99) er\", int(2.99))\n", + "print(\"round() runder av til nærmeste heltall, f.eks.\")\n", + "print(\"round(2.25) er\", round(2.25))\n", + "print(\"round(2.51) er\", round(2.51))\n", + "print(\"Hva hvis tallet er midt mellom to heltall?\")\n", + "print(\"round(2.5) er\", round(2.5))\n", + "print(\"round(3.5) er\", round(3.5))\n", + "print(\"round() bruker en IEEE standard som velger partallet for midt-imellom-situasjoner.\")\n", + "print(\"Mens int() alltid gir heltall kan round() brukes for antall desimaler:\")\n", + "print(\"round(2.5488, 1) blir\", round(2.5488, 1))\n", + "print(\"round(2.5488, 3) blir\", round(2.5488, 3))\n", + "print(\"Med negativt antall desimaler kan vi få round() til å runde større enn heltall:\")\n", + "print(\"round(12345.67, -3) blir\", round(12345.67, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Som du ser i eksemplet, blir 2.5 rundet av til 2 mens 3.5 blir rundet til 4. Dette kan virke litt uvant, i dagliglivet er man mest kjent med såkalt \"kjøpmannsavrunding\", hvor det alltid rundes opp hvis man er midt mellom (dvs., 2.5 skulle i så fall ha blitt rundet til 3). Konsekvent runding oppover når man er midt mellom har imidlertid en uheldig side, nemlig at man pådrar seg en systematisk feil hvis man har mange data som avrundes. Tenk f.eks. temperaturmålinger for lange perioder, hvor man deretter skal regne ut et snitt for hele perioden. Hvis alle temperaturer som er midt når det gjelder siste brukte siffer, rundes opp, vil snittet for perioden alltid bli litt for høyt. Hvis man i stedet går i partallsretning i alle slike midt mellom situasjoner, vil man runde opp cirka halvparten av gangene og ned cirka halvparten av gangene og dermed unngå slike systematiske feil. Men for kjøpmannen er systematisk runding oppover selvsagt bedre med tanke på å få inn mest mulig penger." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "I tillegg til `int()` og `round()` kan f-strenger \"innebygd\" runde av flyttall:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(f'1.2345 avrundet til 2 desimaler er: {1.2345:.2f}')\n", + "print(f'5.4321 avrundet til 0 desimaler er: {5.4321:.0f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Det som skjer her inne i krøllparentesene her er; `1.2345` er tallet vi ønsker runde av, `:` sier \"rund av det som står til venstre til det som står til høyre\", `.2` sier \"gi meg 2 desimaler\" og `f` sier at typen skal være `float`. Det som er verdt å merke seg er at denne måten å runde av tall på gir deg ikke muligheten til å bruke tallet videre. Tallet er da inkorporert i strengen. Med `round()` og `int()` kan vi bruke det avrundede tallet videre." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Lag en funksjon `rund_av(tall, desimaler)` som tar inn et tall `tall` som skal avrundes og `desimaler` antall desimaler tallet skal avrundes til som parametere og returnerer det avrundede tallet.\n", + "\n", + "***Skriv koden din i kodeblokken under.***" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.12\n", + "1000.0\n" + ] + } + ], + "source": [ + "# Skriv koden din her\n", + "def rund_av(tall, desimaler):\n", + " return round(tall, desimaler)\n", + "print(rund_av (1.123456,2))\n", + "print(rund_av (1234.5432, -3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "Hvis funksjonen din er skrevet rett, skal kodeblokken under gi følgende output:\n", + "\n", + "```python\n", + "1.23\n", + "1000.0\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "print(rund_av(1.23456, 2))\n", + "print(rund_av(1234.5432, -3))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/stud9/variabler.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/stud9/variabler.ipynb" new file mode 100644 index 0000000..aadf18f --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/stud9/variabler.ipynb" @@ -0,0 +1,582 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": true + } + }, + "source": [ + "# Variable\n", + "\n", + "**Læringsmål:**\n", + "\n", + "* Enkel bruk av variable\n", + "\n", + "* Korrekt navngivning av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 1: variable - grunnleggende intro" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvorfor trenger vi variable? Poenget med variable er å **huske data underveis** i utførelsen av et program.\n", + "\n", + "Variable er derfor et sentralt konsept i programmering, ikke bare i Python men uansett hva slags språk man programmerer i.\n", + "\n", + "Uten variable støter vi fort på en rekke problemer fordi programmet vårt ikke kan huske noe, f.eks. at\n", + "\n", + "* vi må be brukeren gi inn opplysninger på nytt som brukeren har gitt tidligere\n", + "* vi må regne ut på nytt data vi allerede har regnet ut tidligere\n", + "\n", + "Dette sløser tid og strøm og vil i mange tilfeller gjøre programmet fullstendig ubrukelig.\n", + "\n", + "I det lille eksempelprogrammet under, klarer vi oss uten noen variabel, fordi navnet som skrives utkun blir benyttet én gang.\n", + "\n", + " \n", + "```python \n", + "print('Pi, med seks desimaler er 3.141592') \n", + "```\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + ">>>>\n", + "```\n", + "\n", + "Men ofte skal samme data brukes flere ganger, og etter at vi har gjort andre ting i mellomtiden. Da må data huskes i variable. Anta at vi ønsker en bare litt mer avansert dialog.\n", + "\n", + " \n", + "```\n", + "Pi, med seks desimaler er 3.141592 \n", + "3.141592 er pi, avrundet til seks desimaler.\n", + ">>>>\n", + "```\n", + "\n", + "Her vil vi bruke verdien til pi i to påfølgende print-setninger. Hvis vi prøver samme triks som tidligere med å sette tallet direkte i print-setning, får vi koden:\n", + "\n", + " \n", + "```python\n", + "print('Pi, med seks desimaler er 3.141592')\n", + "print('3.141592 er pi, avrundet til seks desimaler.') \n", + "```\n", + "\n", + "\n", + "```\n", + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er Pi, avrundet til seks desimaler.\n", + "```\n", + "\n", + "Ikke noe katastrofalt problem her, men tenk deg et program hvor samme opplysning skal brukes 100 ganger eller mer i en kritisk arbeidsoppgave som haster. Da kan det bli tungvindt å for eksempel skrive 3.141592 100 ganger.\n", + "\n", + "Kan vi løse det på en bedre måte? JA - med en variabel for å huske navnet. Koden blir da" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pi, med seks desimaler er 3.141592\n", + "3.141592 er pi, avrundet til seks desimaler\n" + ] + } + ], + "source": [ + "pi = 3.141592\n", + "print(f'Pi, med seks desimaler er {pi}')\n", + "print(f'{pi} er pi, avrundet til seks desimaler')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Dette programmet kan forklares som følger:\n", + "\n", + "* linje 1, til høyre for `=` : verdien vi ønsker å lagre (3.141592)\n", + "* linje 1, til venstre for `=`: oppretter en variabel som heter `pi`.\n", + "* linje 1, tegnet `=`. Dette er **tilordningsoperatoren**. Betyr at verdien av uttrykket på høyre side, verdien 3.141592, blir husket i variabelen kalt `pi`.\n", + "* linje 2, variabelen `pi` brukes sist i f-strengen i print-setningen. Merk at variabelnavnet **ikke** skal ha fnutter rundt seg. Med fnuttter ville ikke akkurat dette programmet kjørt. Ordet pi som står som det tredje ordet i setningen \"{pi} er pi, avrundet til seks desimaler\" er ikke variabelen, her er ordet navn bare del av en tekststreng.\n", + "* linje 3, variabelen `pi` brukes fremst i print-setningen. Igjen uten fnutter; det er ikke ordet pi vi ønsker å skrive, men den verdien som variabelen `pi` inneholder (f.eks. 3.141592)\n", + "\n", + "Ved hjelp av variabelen som her ble kalt pi, unngår vi å måtte skrive ut verdien to ganger. Vi skriver den bare én gang, i starten av programmet, og husker da opplysningen ved å putte den inn i en variabel.\n", + "\n", + "Videre i programmet kan vi benytte denne variabelen hver gang vi trenger verdien - enten det som her var bare to ganger, eller om det hadde vært flere.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "hidden": true + }, + "source": [ + "### Rask intro til f-strenger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidden": true + }, + "source": [ + "F-strenger, som brukt i print-setningenge ovenfor, er lett å gjenkjenne ved at strengen starter med en \"f\" før fnuttene. F-en står for \"format\". F-strings gjør det veldig lett for oss å formatere strengene våre. Som du ser i eksempelet over inneholder strengen noen krøllparenteser (`{}`). Innimellom disse krøllparentesene er vi ikke lenger inne i strengen, og at vi skriver inne i disse er \"vanlig\" Python kode. I eksempelet over settes variabelen `pi` inn i disse krøllparentesene. Dette gjøres slik at verdien variabelen `pi` inneholder kan bli satt inn i strengen. Som sagt er det \"vanlig\" Python kode som skrives inne i disse krøllparentesene. Vi kan for eksempel gjøre matteoperasjoner i de:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 + 1 = 2\n", + "2 * 2 = 4\n" + ] + } + ], + "source": [ + "print(f'1 + 1 = {1 + 1}')\n", + "print(f'2 * 2 = {2 * 2}') # Her er det noe feil. Kan du fikse opp? *fikset feilen til 2 * 2 i krøllparentes" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## a) Huske verdier i variable" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Kjør koden under for å se hvordan den virker. Som du vil se, skriver den ut \"Ada\" to ganger, og \"LBAS2002\" to ganger.\n", + "\n", + "Forbedre koden ved å introdusere en variabel for navn og en annen variabel for favorittfag, slik at vi slipper å skrive \"Ada\" og \"LBAS2002\" mer enn én gang.\n", + "\n", + "Hvis du er i tvil om hvordan du skal angripe problemet, se lignende eksempel i tutorial like over." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hei, Ada\n", + "LBAS2002 - interessant!\n", + "Ha en fin dag, Ada\n", + "- og lykke til med LBAS2002\n" + ] + } + ], + "source": [ + "print('Hei, Ada')\n", + "print('LBAS2002 - interessant!')\n", + "print('Ha en fin dag, Ada')\n", + "print('- og lykke til med LBAS2002')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du får til å bruke de to variablene som tenkt, skal kjøringen av det forbedrede programmet se slik ut (men også funke om brukeren skriver inn noe annet enn Ada på spørsmålet Navn? og noe annet enn ITGK på Favorittfag?)\n", + "\n", + "```\n", + "Navn? Ada \n", + "Hei, Ada \n", + "Favorittfag? LBAS2002 \n", + "ITGK - interessant! \n", + "Ha en fin dag, Ada \n", + "- og lykke til med LBAS2002\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 2 - bruk av variable i beregninger" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Variable brukes ikke bare i sammenheng med `input()`, men i alle mulige slags program. I matematiske beregninger skal resultatet av en beregning ofte brukes videre i nye beregninger. Da må disse tallene huskes i variable. \n", + "Koden under viser samme eksempel gjort på to måter, nemlig utregning av areal for en sirkel, samt volum for en sylinder som har denne sirkelen som grunnflate. Versjon 1 er gjort uten variable, mens Versjon 2 bruker variable.\n", + "\n", + "**Sirkel og sylinder**" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n", + "\n", + "Areal av sirkelen: 91.60884177867838\n", + "Volum av sylinderen: 723.7098500515592\n" + ] + } + ], + "source": [ + "import math\n", + " \n", + "# VERSJON 1, uten variable\n", + "print(\"Areal av sirkelen:\", math.pi * 5.4**2)\n", + "print(\"Volum av sylinderen:\", math.pi * 5.4**2 * 7.9)\n", + " \n", + "print()\n", + " \n", + "# VERSJON 2, med variable\n", + "r = 5.4 # radius for en sirkel\n", + "a_sirkel = math.pi * r**2\n", + "print(\"Areal av sirkelen:\", a_sirkel)\n", + "h = 7.9 # høyde sylinder hvor sirkelen er grunnflate\n", + "v_syl = a_sirkel * h\n", + "print(\"Volum av sylinderen:\", v_syl)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Hvis du kjører koden, vil du se at begge gir samme resultat. Hva er da forskjellen?\n", + "\n", + "* Versjon 2 er vesentlig lenger (6 kodelinjer, mot bare 2) fordi det brukes ekstra linjer på variable. Lenger kode er en mulig ulempe. MEN:\n", + "* Formlene i Versjon 2 er lettere å forstå fordi det er intuitive navn som `r`, `h`, `a_sirkel` heller enn bare tall direkte.\n", + "* Koden i V2 er mer fleksibel for å kjapt endre verdier. Hvis radius skal byttes fra 5.4 til 6.2 må dette tallet bare endres ett sted i V2, mens flere i V1.\n", + "* Versjon 1 utfører **5 operasjoner** av type `*` og `**`, mens Versjon 2 bare utfører ***3***. Dette fordi Versjon 2 husker arealet i a_sirkel og deretter kan bruke dette, mens Versjon 1 må regne ut `math.pi * 5.4**2` på nytt.\n", + "**Med færre multiplikasjoner vil VERSJON 2 spare både strøm og tid i forhold til VERSJON 1, dvs. koden utfører mindre jobb og går raskere selv om det er flere kodelinjer.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## b) Bruke variable i beregninger " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Nedenfor står et program hvor vi regner ut omkrets og areal for en sirkel etter de velkjente formlene $O=2\\pi{r}$ og $A = \\pi r^2$. Bortsett fra **numpy** konstanten `np.pi` og den innebygde konstanten `math.tau` (=2π) bruker vi ingen variable. Dette gjør at når vi skal regne ut arealet av en sylinder hvor sirkelen er grunnflate, må vi gjøre om igjen flere beregninger som vi allerede har gjort tidligere.\n", + "\n", + "Arealet av sylinderen med høyde h vil være `omkrets_sirkel * h + 2 * areal_sirkel`, hvor det første leddet er arealet av sylinderveggen og det siste leddet er topp- og bunnlokket.\n", + "\n", + "***Oppgave: Endre koden ved å tilordne og deretter bruke variable for radiusen, høyden, sirkelens omkrets og areal, slik at programmet unngår å gjøre på nytt beregninger som allerede er gjort før.***" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2019-07-01T10:54:16.358742Z", + "start_time": "2019-07-01T10:54:16.351684Z" + }, + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import math\n", + " \n", + "print(\"Har en sirkel med radius\", 5.4, \"som er grunnflate i en sylinder med høyde\", 7.9)\n", + "print(\"Omkrets av sirkelen:\", math.tau * 5.4) #tau er det samme som 2 pi\n", + "print(\"Areal av sirkelen:\", np.pi * 5.4**2)\n", + "print(\"Areal av sylinderen:\", math.tau * 5.4 * 7.9 + 2 * math.pi * 5.4 ** 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Resultatet av kjøring av koden skal være uendret, dvs utskrift skal bli som vist nedenfor (men hvis du vil, kan du gjerne i tillegg avrunde svarene til én desimal).\n", + "\n", + " \n", + "```\n", + "Har en sirkel med radius 5.4 som er grunnflate i en sylinder med høyde 7.9\n", + "Omkrets av sirkelen: 33.929200658769766\n", + "Areal av sirkelen: 91.60884177867838\n", + "Areal av sylinderen: 451.25836876163794\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## Tutorial del 3: Navngiving av variable" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "En variabel er et navn som representerer en verdi som lagres i datamaskinens minne. Den vanligste måten å opprette en variabel på er ved en tilordningssetning:\n", + "\n", + "`variable = expression`\n", + "\n", + "I dette tilfellet er variable navnet til variabelen, mens expression er verdien. Noen regler for slike tilordningssetninger:\n", + "\n", + "* variabelen som opprettes skal alltid stå på venstre side av uttrykket, og venstre side skal kun inneholde denne variabelen, ikke noe annet\n", + "* høyde side kan alt fra en enkelt verdi (f.eks. et tall) eller en enkelt variabel, til mer sammensatte uttrykk som må beregnes. Hvis høyre side inneholder variable, må dette være variable som allerede er opprettet tidligere i koden.\n", + "* variabelnavnet må tilfredsstille følgende regler:\n", + " * ord som er reserverte ord i Python, f.eks. `if`, `def`, eller som er navn på standardfunksjoner som `print`, `min`, `max`, ... bør unngås som varibelnavn\n", + " * variabelnavn må begynne med en bokstav eller tegnet _ (understrek)\n", + " * kan ellers inneholde bokstaver, tall og understrek, dvs. kan f.eks. ikke inneholde blanke tegn.\n", + "* Python skiller mellom små og store bokstaver, så `Areal` og `areal` vil være to ulike variable.\n", + "\n", + "Det anbefales å lage variabelnavn som er intuitivt forståelige, f.eks. er `areal` et bedre navn enn `x` på en variabel som inneholder et areal. Sammensatte variabelnavn skrives typisk som pukkelord (eng.: camelCase) eller med understrek for å vise hvor ett ord slutter og det neste begynner, f.eks. `startTime`, `pricePerLiter` eller `start_time`, `price_per_liter`, siden direkte sammensetning uten noe som helst skille vil gi lange variabelnavn som blir vanskelige å lese.\n", + "\n", + "Kodeblokka under viser eksempler på variable som funker og ikke funker:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# Eksempel på tilordningssetninger som funker\n", + "pokemon_name = \"Tyranitar\"\n", + "MaxCP = 3670\n", + "antall = 3\n", + "antall = antall + 1 # høyre side regnes ut som 3+1, så 4 blir ny verdi i variabelen antall\n", + "resists_fighting = False\n", + "level42 = \"to be done\" # tall er OK i variabelnavn unntatt helt fremst\n", + " \n", + "# Eksempel på tilordninger som IKKE funker\n", + "1 = antall # variabelen må stå på venstre side\n", + "antall + 1 = antall # og v.s. kan KUN inneholde et variabelnavn, ikke et større uttrykk\n", + "10kamp = \"gøy\" # variabel kan ikke begynne med tall, kun bokstav eller _\n", + "antall = 3 # denne er OK, men se neste linje\n", + "antall = Antall + 1 # Python skiller mellom store og små bokstaver, Antall vil være en annen\n", + " # variabel og gir NameError her fordi den ikke er opprettet i en tidligere setning\n", + "happy hour = 20 # navn kan ikke inneholde mellomrom, burde vært happy_hour eller happyHour\n", + "alkohol% = 4.5 # % kan ikke brukes i variabelnavn (betyr modulo). Samme gjelder andre spesialtegn,\n", + " # hold deg til vanlige bokstaver og tall" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "## c) Variabelnavn" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "hidden": true, + "run_control": { + "frozen": true + } + }, + "source": [ + "Prøv å kjør koden under. Som du vil se, funker den ikke pga. diverse feil med variabelnavn og tilordningssetninger. Fiks feilene så programmet kjører som det skal." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Per er (42, -37) år unna ideal_alderen\n" + ] + } + ], + "source": [ + "navn = 'Per'\n", + "ideal_alder = 42\n", + "kunde_alder = 37 \n", + "differanse = ideal_alder, - kunde_alder\n", + "\n", + "print(f'{navn} er {differanse} år unna ideal_alderen') " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/\303\270vinger/\303\270ving_1/innlevering/zip_for_download.ipynb" "b/\303\270vinger/\303\270ving_1/innlevering/zip_for_download.ipynb" new file mode 100644 index 0000000..1b1622f --- /dev/null +++ "b/\303\270vinger/\303\270ving_1/innlevering/zip_for_download.ipynb" @@ -0,0 +1,86 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Adding file: ./lab/lab_1/variabler.ipynb\n", + "Adding file: ./lab/lab_1/intro_til_jupyter.ipynb\n", + "Adding file: ./lab/lab_1/lab-1.md\n", + "Adding file: ./lab/lab_1/tall_og_typekonvertering.ipynb\n", + "Adding file: ./lab/lab_1/lister.jupynb\n" + ] + } + ], + "source": [ + "# How to use this file:\n", + "# 1. Copy the file and paste in your root folder (same level as shared)\n", + "# 2. Update the value of src_path and filename (below) depending on what you want to zip\n", + "# 3. Run the content of the cell\n", + "\n", + "src_path = 'lab/lab_1'\n", + "filename = 'lab_1.zip'\n", + "\n", + "import glob\n", + "import zipfile\n", + "import os\n", + "\n", + "# Create target-folders if not exist:\n", + "subfolder=filename.split('.')[0]\n", + "target_path = \"./\"+src_path+\"/\"\n", + "target_subfolder = target_path+subfolder\n", + "\n", + "# Check whether the specified path exists or not\n", + "isPathExist = os.path.exists(target_path)\n", + "\n", + "if not isPathExist:\n", + " print(\"Directory do not exist!\")\n", + "\n", + "isTargetZipExist = os.path.exists(filename)\n", + "if isTargetZipExist:\n", + " os.remove(filename)\n", + "\n", + "# zip files\n", + "files = glob.glob(\"./\"+src_path+\"/*.*\")\n", + "for file in files:\n", + " print('Adding file:',file)\n", + " \n", + " with zipfile.ZipFile(filename, mode=\"a\") as archive:\n", + " archive.write(file)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.8" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} -- GitLab