├── .gitignore ├── LICENSE ├── README.md ├── bootstrap ├── README.md └── bootstrap-julia.bash ├── data ├── bruno.csv ├── coordinates.txt ├── poem.txt └── sherlock-holmes.txt ├── exercises ├── 01_Exercises-basics.ipynb ├── 02_Exercises-control-flow.ipynb ├── 03_Exercises-functions.ipynb ├── 04_Exercises-io.ipynb ├── 05_Exercises-development-practises.ipynb ├── 06_Exercises-ecosystems-I.ipynb ├── 07_Exercises-performance.ipynb ├── 08_Exercises-ecosystems-II.ipynb └── solutions │ ├── 01_Solutions-basics.ipynb │ ├── 02_Solutions-control-flow.ipynb │ ├── 03_Solutions-functions.ipynb │ ├── 04_Solutions-io.ipynb │ ├── 05_Solutions-development-practises.ipynb │ ├── 06_Solutions-ecosystems-I.ipynb │ ├── 07_Solutions-performance.ipynb │ └── 08_Solutions-ecosystems-II.ipynb ├── notebooks ├── 00_intro-to-julia.ipynb ├── 00_notebooks.ipynb ├── 01_basics.ipynb ├── 02_control-flow.ipynb ├── 03_functions.ipynb ├── 04_IO.ipynb ├── 05_development-practises.ipynb ├── 06_ecosystem-I.ipynb ├── 07_performance.ipynb ├── 08_ecosystem-II.ipynb ├── Bonus_metaprogramming.ipynb └── Bonus_simd-vectorization.ipynb └── slides ├── 00_intro-to-julia.slides.html ├── 00_notebooks.slides.html ├── 01_basics.slides.html ├── 02_control-flow.slides.html ├── 03_functions.slides.html ├── 04_io.slides.html ├── 05_development-practises.slides.html ├── 06_ecosystem-I.slides.html ├── 07_performance.slides.html ├── 08_ecosystem-II.slides.html ├── allver.svg ├── benchmarks.png ├── benchmarks.svg ├── publish.sh └── tmp.gif /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | #slides/*.html 3 | .ipynb_checkpoints/ 4 | reveal.js 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 CSC - IT Center for Science Ltd. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction to Julia 2 | 3 | This repository contains the content for the [Introduction to Julia](https://www.csc.fi/web/training/-/julia_intro_2019) course at CSC. 4 | 5 | Julia is a new emerging high-level, high-performance programming language. It aims to be simple to write and fast to run. In this course, we will introduce the basic concepts of programming with Julia. We will also discuss selected Julia packages and give an introduction to the Julia ecosystem. The course contains both lectures and hands-on exercises. All the material is provided as interactive notebooks. 6 | 7 | The course is aimed for everybody with beginner to intermediate level of skills in programming. However, the notebooks and exercises also contain extra material marked with **Advanced** tags that are aimed for the more experienced users. Don't feel overwhelmed by them, some of them can be very specific to some particular field of science. Instead, if you find some of them interesting, feel free to just mess around with them and have some fun. That is the whole point of programming with a high-level language anyway! 8 | 9 | 10 | 11 | ## Prerequisites 12 | Participants are expected to have some experience in computer programming and to be familiar with the basic concepts (e.g. variables, statements, control structures, functions) but previous knowledge of Julia is not required. 13 | 14 | 15 | ## Timetable 16 | | | | Monday | Tuesday 17 | | ----- |--------| -------------- | ----------- 18 | | 09:00 | 45min | Intro | Development practices 19 | | 09:45 | 45min | **Exercises** | **Exercises** 20 | | 10:30 | 15min | Coffee break | Coffee break 21 | | 10:45 | 30min | Control flow | Julia ecosystem 22 | | 11:15 | 60min | **Exercises** | **Exercises** 23 | | 12:15 | 60min | *Lunch* | *Lunch* 24 | | 13:15 | 30min | Functions | Performance tips 25 | | 13:45 | 45min | **Exercises** | **Exercises** 26 | | 14:30 | 15min | Coffee break | Coffee break 27 | | 14:45 | 30min | IO | Julia ecosystem II 28 | | 15:15 | 60min | **Exercises** | End of course 29 | | 16:15 | | End of day | 30 | 31 | 32 | 33 | ## Lecture material usage 34 | Lecture material can be read directly from GitHub using your browser. Just click yourself inside the `notebooks` directory. However, for best experience, you should open the notebooks in the notebook environment. Installation of `Jupyter` notebooks and IJulia for this is described below. 35 | 36 | For a quick introduction to the Jupyter notebook environment, see the [00_notebooks.ipynb](notebooks/00_notebooks.ipynb). 37 | 38 | 39 | ## Installation of Julia 40 | 41 | ### CSC notebook environment 42 | In the course we use the [CSC notebook environment](https://notebooks.csc.fi/). 43 | 44 | Once logged in, go to "Account" and "Join Group" by using the code provided to you. 45 | 46 | After joining the group, you should see "Introduction to Julia" in the Dashboard. 47 | 48 | All the hands-on exercises can be done in the cloud environment using the workstations in the training class (or using own laptop if you prefer so). 49 | 50 | 51 | ### Quick start: using Julia on juliabox 52 | The simplest way to use Julia is to go to [juliabox.com](https://www.juliabox.com/). Once you log in (e.g. with a gmail account), you can run Julia code online (on Amazon Cloud servers) via the browser-based Jupyter notebook interface without installing anything on your computer. 53 | 54 | Although you wouldn't want to run large computations on juliabox, it should be fine for simple homework problems. 55 | 56 | To add our lecture material, click the `Git` button on the top left in the menu bar. Then insert the course material url 57 | ``` 58 | https://github.com/csc-training/julia-introduction.git 59 | ``` 60 | and type `master` for the branch. Folder name can be whatever you like, for example `julia-csc`. 61 | 62 | **Caveat**: 63 | Packages can not be installed using the Julia package manager. You must install external packages by clicking the `Packages` button on the top menu. After that, just type the name of the package and hit install. 64 | 65 | 66 | ### Installing Julia and IJulia 67 | If you use Julia enough, you'll eventually want to install it on your own computer. Your code will run faster and won't require a network connection, but can still use the same browser-based notebook interface. 68 | 69 | First, [download the current release of Julia](http://julialang.org/downloads/) and run the installer. Then open the Julia application (double-click on it); a window with a julia> prompt will appear. At the prompt, type: 70 | 71 | ```julia 72 | using Pkg 73 | Pkg.add("IJulia") 74 | ``` 75 | You may also want to install these packages, which we tend to use in a lot of the lecture materials 76 | ```julia 77 | Pkg.add("Plots") 78 | Pkg.add("PlotlyJS") 79 | Pkg.add("PyPlot") 80 | ``` 81 | 82 | 83 | Then you can launch the notebook in your browser by running 84 | ```julia 85 | using IJulia 86 | notebook() 87 | ``` 88 | 89 | 90 | ---- 91 | ## References 92 | Much of this material is based on different excellent content found around the web such as: 93 | 94 | ### General topics 95 | - Julialang.org 96 | - Official Julia manual: https://docs.julialang.org/en/latest/manual/ 97 | - JuliaBox.com and the excellent tutorials therein 98 | - https://en.wikibooks.org/wiki/Introducing_Julia 99 | - [Introduction to python](https://github.com/csc-training/python-introduction) course at CSC 100 | 101 | 102 | ### Parallelism: 103 | - https://slides.com/valentinchuravy/julia-parallelism 104 | - MIT course: Performance Computing in a High Level Language: https://github.com/stevengj/18S096 105 | -------------------------------------------------------------------------------- /bootstrap/README.md: -------------------------------------------------------------------------------- 1 | # Bootstrap script 2 | 3 | This directory contains a bootstrap script that will be downloaded by 4 | Notebooks and used to check out the repo to the user. 5 | 6 | -------------------------------------------------------------------------------- /bootstrap/bootstrap-julia.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## Script that clones a repository 3 | 4 | cd /home/jovyan/ 5 | # git reflog requires a name and email if user is not in passwd 6 | # even if you're only cloning 7 | export GIT_COMMITTER_NAME=anonymous 8 | export GIT_COMMITTER_EMAIL=anon@localhost 9 | git clone https://github.com/csc-training/julia-introduction.git 10 | 11 | # clean up as host script doesn't do so yet 12 | rmdir work 13 | rm bootstrap-julia.bash 14 | -------------------------------------------------------------------------------- /data/bruno.csv: -------------------------------------------------------------------------------- 1 | 27.80985,49.61936,83.08067,116.6632,130.414,150.7206,220.1871,156.1536,148.6416,203.7845,206.0386,107.1618,68.36975,45.3359,49.96142,21.89279,17.02552,11.74317,14.75226,13.6671,5.677561,3.31234,1.156517,-0.147662 2 | 27.71966,48.55022,65.21374,95.27666,116.9964,133.9056,152.3412,151.934,160.1139,179.5327,147.6184,170.3943,121.8194,52.58537,33.08871,38.40972,44.24843,69.5786,4.019351,3.050024,3.039719,2.996142,2.967954,1.999594 3 | 30.4267,33.47752,44.80953,62.47495,77.43523,104.2153,102.7393,137.0004,186.0706,219.3173,181.7615,120.9154,143.1835,82.40501,48.47132,74.71461,60.0909,7.073525,6.089851,6.53745,6.666096,7.306965,5.73684,3.625628 4 | 16.66549,30.1086,39.96952,44.12225,59.57512,77.56929,106.8925,166.5539,175.2381,185.2815,154.5056,83.0433,62.61732,62.33167,60.55916,55.92124,15.17284,8.248324,36.68087,61.93413,20.26867,68.58819,46.49812,0.2360095 5 | 8.815617,18.3516,8.658275,27.5859,48.62691,60.18013,91.3286,145.7109,116.0653,106.2662,68.69447,53.10596,37.92797,47.95942,47.42691,69.20731,44.95468,29.17197,17.91674,16.25515,14.65559,17.26048,31.22245,46.71704 6 | 6.628881,10.41339,24.81939,26.08952,30.1605,52.30802,64.71007,76.30823,84.63686,99.4324,62.52132,46.81647,55.76606,82.4099,140.2647,81.26501,56.45756,30.42164,17.28782,8.302431,2.981626,2.698536,5.886086,5.268358 7 | 21.83975,6.63927,18.97085,32.89204,43.15014,62.86014,104.6657,130.2294,114.8494,106.9873,61.89647,55.55682,86.80986,89.27802,122.4221,123.9698,109.0952,98.41956,77.61374,32.49031,14.67344,7.370775,0.03711011,0.6423392 8 | 53.34303,26.79797,6.63927,10.88787,17.2044,56.18116,79.70141,90.8453,98.27675,80.87243,74.7931,75.54661,73.4373,74.11694,68.1749,46.24076,39.93857,31.21653,36.88335,40.02525,117.4297,12.70328,1.729771,0 9 | 25.66785,63.05717,22.1414,17.074,41.74483,60.27227,81.42432,114.444,102.3234,101.7878,111.031,119.2309,114.0777,110.5296,59.19355,42.47175,14.63598,6.944074,6.944075,27.74936,0,0,0.09449376,0.07732264 10 | 12.827,69.20554,46.76293,13.96517,33.88744,61.82613,84.74799,121.122,145.2741,153.1797,204.786,227.9242,236.3038,228.3655,79.34425,25.93483,6.944074,6.944074,6.944075,7.553681,0,0,0,0 11 | 0,68.66396,59.0435,33.35762,47.45282,57.8355,78.91689,107.8275,168.0053,130.9597,212.5541,165.8122,210.2429,181.1713,189.7617,137.3378,84.65395,8.677168,6.956576,8.468093,0,0,0,0 12 | 0,95.17499,80.03818,59.89862,39.58476,50.28058,63.81641,80.61302,66.37824,198.7651,244.3467,294.2474,264.3517,176.4082,60.21857,77.41475,53.16981,56.16393,6.949235,7.531059,3.780177,0,0,0 13 | 0,134.9879,130.3696,96.86325,75.70494,58.86466,57.20374,55.18837,78.128,108.5582,154.3774,319.1686,372.8826,275.4655,130.2632,54.93822,25.49719,8.047439,8.084393,5.115252,5.678269,0,0,0 14 | 0,48.08919,142.5558,140.3777,154.7261,87.9361,58.11092,52.83869,67.14822,83.66798,118.9242,150.0681,272.9709,341.1366,238.664,190.2,116.8943,91.48672,14.0157,42.29277,5.115252,0,0,0 15 | 0,54.1941,146.3839,99.48143,96.19411,102.9473,76.14089,57.7844,47.0402,64.36799,84.23767,162.7181,121.3275,213.1646,328.482,285.4489,283.8319,212.815,164.549,92.29631,7.244015,1.167,0,0 16 | 0,6.919659,195.1709,132.5253,135.2341,89.85069,89.45549,60.29967,50.33806,39.17583,59.06854,74.52159,84.93402,187.1219,123.9673,103.7027,128.986,165.1283,249.7054,95.39966,10.00284,2.39255,0,0 17 | 0,21.73871,123.1339,176.7414,158.2698,137.235,105.3089,86.63255,53.11591,29.03865,30.40539,39.04902,49.23405,63.27853,111.4215,101.1956,40.00962,59.84565,74.51253,17.06316,2.435141,2.287471,-0.0003636982,0 18 | 0,0,62.04672,136.3122,201.7952,168.1343,95.2046,58.90624,46.94091,49.27053,37.10416,17.97011,30.93697,33.39257,44.03077,55.64542,78.22423,14.42782,9.954997,7.768213,13.0254,21.73166,2.156372,0.5317867 19 | 0,0,79.62993,139.6978,173.167,192.8718,196.3499,144.6611,106.5424,57.16653,41.16107,32.12764,13.8566,10.91772,12.07177,22.38254,24.72105,6.803666,4.200841,16.46857,15.70744,33.96221,7.575688,-0.04880907 20 | 0,0,33.2664,57.53643,167.2241,196.4833,194.7966,182.1884,119.6961,73.02113,48.36549,33.74652,26.2379,16.3578,6.811293,6.63927,6.639271,8.468093,6.194273,3.591233,3.81486,8.600739,5.21889,0 21 | 0,0,29.77937,54.97282,144.7995,207.4904,165.3432,171.4047,174.9216,100.2733,61.46441,50.19171,26.08209,17.18218,8.468093,6.63927,6.334467,6.334467,5.666687,4.272203,0,0,0,0 22 | 0,0,31.409,132.7418,185.5796,121.8299,185.3841,160.6566,116.1478,118.1078,141.7946,65.56351,48.84066,23.13864,18.12932,10.28531,6.029663,6.044627,5.694764,3.739085,3.896037,0,0,0 23 | 0,0,19.58994,42.30355,96.26777,187.1207,179.6626,221.3898,154.2617,142.1604,148.5737,67.17937,40.69044,39.74512,26.10166,14.48469,8.65873,3.896037,3.571392,3.896037,3.896037,3.896037,1.077756,0 24 | 0.001229679,3.008948,5.909858,33.50574,104.3341,152.2165,198.1988,191.841,228.7349,168.1041,144.2759,110.7436,57.65214,42.63504,27.91891,15.41052,8.056102,3.90283,3.879774,3.936718,3.968634,0.1236256,3.985531,-0.1835741 25 | 0,5.626141,7.676256,63.16226,45.99762,79.56688,227.311,203.9287,172.5618,177.1462,140.4554,123.9905,110.346,65.12319,34.31887,24.5278,9.561069,3.334991,5.590495,5.487353,5.909499,5.868994,5.833817,3.568177 26 | -------------------------------------------------------------------------------- /data/coordinates.txt: -------------------------------------------------------------------------------- 1 | -5.000000 25.131953 2 | -3.888889 15.056032 3 | -2.777778 7.261712 4 | -1.666667 2.908772 5 | -0.555556 -0.141217 6 | 0.555556 0.176612 7 | 1.666667 2.833694 8 | 2.777778 7.643842 9 | 3.888889 14.979309 10 | 5.000000 25.299547 11 | -------------------------------------------------------------------------------- /data/poem.txt: -------------------------------------------------------------------------------- 1 | Slam poetry. Yelling. Angry. Waving my hands a lot. Specific point of view on 2 | things. Cynthia. Cyn-thi-a. Jesus died for our Cynthia’s. Jesus cried. Runaway 3 | bride. Julia Roberts. Julia rob-hurts. Cynthia. Mmmmm Cynthia, you’re dead. You 4 | are dead. Be boop beep you’re dead. 5 | 6 | - Schmidt, 22 Jump Street 7 | -------------------------------------------------------------------------------- /exercises/01_Exercises-basics.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: Basics" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Hello world!\n", 15 | "\n", 16 | "Let's begin our Julia journey with a proper way. Write a hello world program in Julia!" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Julia as calculator\n", 31 | "\n", 32 | "Try some simple math and solve these:\n", 33 | "\n", 34 | "$\n", 35 | "100 + 123 = ?\n", 36 | "$\n", 37 | "\n", 38 | "$\n", 39 | "5^2 = ?\n", 40 | "$\n", 41 | "\n", 42 | "$\n", 43 | "2\\pi = ?\n", 44 | "$\n", 45 | "\n", 46 | "$\n", 47 | "\\cos(2\\pi) = ?\n", 48 | "$\n", 49 | "\n", 50 | "$\n", 51 | "e^2 = ?\n", 52 | "$" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": { 65 | "slideshow": { 66 | "slide_type": "skip" 67 | } 68 | }, 69 | "source": [ 70 | "### Arrays\n", 71 | "\n", 72 | "Create an array `arr` with elements of `1,2,3,4,5`. Then add the number `6` to the end of this array. " 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "## Rational number magic\n", 87 | "\n", 88 | "How much is $ \\frac{3}{5} + \\frac{9}{10}$ ? Instead of typing `3/5 +...` etc. see what happens for `3//5 +...` etc." 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [] 97 | } 98 | ], 99 | "metadata": { 100 | "kernelspec": { 101 | "display_name": "Julia 1.0.3", 102 | "language": "julia", 103 | "name": "julia-1.0" 104 | }, 105 | "language_info": { 106 | "file_extension": ".jl", 107 | "mimetype": "application/julia", 108 | "name": "julia", 109 | "version": "1.0.3" 110 | } 111 | }, 112 | "nbformat": 4, 113 | "nbformat_minor": 2 114 | } 115 | -------------------------------------------------------------------------------- /exercises/02_Exercises-control-flow.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: Control flow" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### if...\n", 15 | "\n", 16 | "Write a conditional statement that prints the number itself if it is smaller than zero, and the string \"positive\" if the number is larger than or equal to zero.\n" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### ternary operator\n", 31 | "\n", 32 | "Rewrite the previous exercise using the ternary operator." 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "### for-loops\n", 47 | "\n", 48 | "Loop over integers between 1 and 100 and print their squares." 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "### while\n", 63 | "\n", 64 | "Do the same with a `while` statement" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "### arrays\n", 79 | "\n", 80 | "Use an array comprehension to create an an array that stores the squares for all integers between 1 and 100." 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "### Advanced: FizzBuzz\n", 95 | "\n", 96 | "Implement the (infamous) FizzBuzz test using Julia: \n", 97 | "\n", 98 | "Loop over numbers between 1 and 100. For every element:\n", 99 | "- given a number, N, print \"Fizz\" if N is divisible by 3, \n", 100 | "- \"Buzz\" if N is divisible by 5, \n", 101 | "- and \"FizzBuzz\" if N is divisible by 3 and 5. \n", 102 | "- Otherwise just print the number itself\n", 103 | "\n", 104 | "You can check the remainder of division using the `%` symbol, i.e., `3 % 2 = 1`" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": null, 110 | "metadata": {}, 111 | "outputs": [], 112 | "source": [] 113 | } 114 | ], 115 | "metadata": { 116 | "kernelspec": { 117 | "display_name": "Julia 0.6.2", 118 | "language": "julia", 119 | "name": "julia-0.6" 120 | }, 121 | "language_info": { 122 | "file_extension": ".jl", 123 | "mimetype": "application/julia", 124 | "name": "julia", 125 | "version": "0.6.2" 126 | } 127 | }, 128 | "nbformat": 4, 129 | "nbformat_minor": 2 130 | } 131 | -------------------------------------------------------------------------------- /exercises/03_Exercises-functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: Functions" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Introduction to functions\n", 15 | "\n", 16 | "Write a function named `addone` that adds 1 to its input." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Polynomial\n", 31 | "\n", 32 | "Write your own 2nd order polynomial function `poly2(x)` that evaluates $4 + 3x + 2x^2$." 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "Abstractify your function a little to take `x` and `coeffs` as an input. `coeffs` should be an array of length `3` that holds the coefficients of the polynomial. Internally your function should then compute $C_3 x^2 + C_2 x + C_1$ where $C_i$ is the $i$th element of the `coeff` array." 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "**Advanced**: Can you generalize your function to work for any $n$th order polynomial of the form $C_{n+1} x^{n} + C_{n} x^{n-1} \\ldots C_{n+1} x + C_n$ ?" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "### Map / Broadcast\n", 75 | "\n", 76 | "Use `map` or `broadcast` to increment every element of a matrix `A` by `1` using the function defined in the first exercise.\n", 77 | "\n", 78 | "You can easily create an empty matrix for testing with `A = zeros(5,5)`." 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": null, 84 | "metadata": {}, 85 | "outputs": [], 86 | "source": [] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "### Dot syntax\n", 93 | "\n", 94 | "Try out the broadcast dot syntax to increment every element of matrix `A` by `1` using the function defined in the first exercise." 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": {}, 107 | "source": [ 108 | "### Advanced: More dots\n", 109 | "Generalize the previous polynomial function to work for matrices, too. In practise this means that `x` can be of array too and the polynomial function is evaluated for every element of that array." 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": null, 115 | "metadata": {}, 116 | "outputs": [], 117 | "source": [] 118 | } 119 | ], 120 | "metadata": { 121 | "kernelspec": { 122 | "display_name": "Julia 0.6.2", 123 | "language": "julia", 124 | "name": "julia-0.6" 125 | }, 126 | "language_info": { 127 | "file_extension": ".jl", 128 | "mimetype": "application/julia", 129 | "name": "julia", 130 | "version": "0.6.2" 131 | } 132 | }, 133 | "nbformat": 4, 134 | "nbformat_minor": 2 135 | } 136 | -------------------------------------------------------------------------------- /exercises/04_Exercises-io.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: IO" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Hi!\n", 15 | "\n", 16 | "Create a string that says \"hi\" 100 times. Hint: maybe there is some better way than just writing it 100 times?" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "### String interpolation\n", 38 | "\n", 39 | "Declare two variables \n", 40 | "```julia\n", 41 | "a = 3\n", 42 | "b = 4\n", 43 | "```\n", 44 | "and use them to create two strings\n", 45 | "```\n", 46 | "\"3 + 4\"\n", 47 | "\"7\"\n", 48 | "```" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "### Simple file reading\n", 63 | "\n", 64 | "The file `\"../data/coordinates.txt\"` contains list of (x, y) value pairs. Read the values into an array using the `readdlm()` function. \n", 65 | "\n", 66 | "After that, write them into a file `coordinates.csv` using the CSV-format." 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "using DelimitedFiles #let's not forget this!" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "### Advanced: Not so simple file reading\n", 83 | "\n", 84 | "Read the values of the `../data/coordinate.txt` into two arrays called `x` and `y` using the `open()`, `readline()` or `eachline()`, `close()` syntax.\n", 85 | "\n", 86 | "HINT: You will somehow need to parse each string of lines into numbers. Use the help and see what `split()` and `parse(Float64,... )` can do for you." 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [] 95 | } 96 | ], 97 | "metadata": { 98 | "kernelspec": { 99 | "display_name": "Julia 0.6.2", 100 | "language": "julia", 101 | "name": "julia-0.6" 102 | }, 103 | "language_info": { 104 | "file_extension": ".jl", 105 | "mimetype": "application/julia", 106 | "name": "julia", 107 | "version": "0.6.2" 108 | } 109 | }, 110 | "nbformat": 4, 111 | "nbformat_minor": 2 112 | } 113 | -------------------------------------------------------------------------------- /exercises/05_Exercises-development-practises.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: development practises" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Pretty functions\n", 15 | "\n", 16 | "Write a function called `blackbox`. It should behave such that it takes a number as an input and adds one to it. If a keyword argument `reverse=true` is also given, it should subtract one instead.\n" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "blackbox(1)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "blackbox(2.0)" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "blackbox(100, reverse=true)" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "Write another `blackbox2` function that behaves like the previous but when given two arguments it uses the second argument as the value it adds or substracts. With one argument it behaves like the previous function.\n", 58 | "\n", 59 | "Hint: remember optional argument that can be given a default value!" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "blackbox2(10)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "blackbox2(10,5)" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [ 93 | "blackbox2(10,5,reverse=true)" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "## Multiple dispatch" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "Extend the function `foo`, adding a method that takes only one input argument, which is of type `Bool`, and prints \"foo with one boolean!\"" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "Check that the method being dispatched is the one you wrote by executing this:" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": null, 127 | "metadata": {}, 128 | "outputs": [], 129 | "source": [ 130 | "foo(true)" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "metadata": {}, 137 | "outputs": [], 138 | "source": [ 139 | "@which foo(true)" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "Now, extend `foo` such that with it prints\n", 147 | "- `I am integer` if the given value is integer\n", 148 | "- `I am float` if the given value is floating point number (i.e., float) \n", 149 | "- `I am string` if the given value is `String`, and\n", 150 | "- `I am something else` otherwise\n", 151 | "\n", 152 | "Hint: It might help you to know that there exists such types as `Integer` and `AbstractFloat` in Julia." 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": {}, 166 | "outputs": [], 167 | "source": [ 168 | "#test with these:\n", 169 | "foo(1) \n", 170 | "foo(1.0)\n", 171 | "foo(\"1\")\n", 172 | "foo([1,2,3]) # array as input" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "### Dictionaries\n", 180 | "\n", 181 | "So far we have not used dictionaries a lot. They can, however, improve the readability of your code tremendously. \n", 182 | "\n", 183 | "Create a dictionary whose keys are the fruits “pineapple”, “strawberry”, and “banana”. As values use numbers representing e.g. prices.\n", 184 | "\n", 185 | "Add “orange” to the dictionary and then remove “banana” from the dictionary. Investigate the contents of dictionary and pay attention to the order of key-value pairs.\n", 186 | "\n", 187 | "Just to remind you, the syntax for dictionaries is `dict = Dict(\"a\" => 1, \"b\" => 2, \"c\" => 3)`. They can be modified with an aptly named `delete!()` function." 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": null, 193 | "metadata": {}, 194 | "outputs": [], 195 | "source": [] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": null, 200 | "metadata": {}, 201 | "outputs": [], 202 | "source": [] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": null, 207 | "metadata": {}, 208 | "outputs": [], 209 | "source": [] 210 | }, 211 | { 212 | "cell_type": "markdown", 213 | "metadata": {}, 214 | "source": [ 215 | "### Advanced: Dictionaries for language processing\n", 216 | "\n", 217 | "This is a more complex use-case of dictionaries for processing a Sherlock Holmes book.\n", 218 | "\n", 219 | "To build the dictionary, we loop through the list of words, and use `get()` to look up the current tally, if any. If the word has already been seen, the count can be increased. If the word hasn't been seen before, the fall-back third argument of get() ensures that the absence doesn't cause an error, and 1 is stored instead." 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": null, 225 | "metadata": {}, 226 | "outputs": [], 227 | "source": [ 228 | "#read file\n", 229 | "f = open(\"../data/sherlock-holmes.txt\")\n", 230 | "\n", 231 | "#first make everything lowercase\n", 232 | "#then use regexp to split by words\n", 233 | "wordlist = split(lowercase(read(f, String)), r\"\\W\")\n", 234 | "close(f)\n", 235 | "\n", 236 | "#To store the words and the word counts, we'll create a spesific dictionary:\n", 237 | "wordcounts = Dict{String,Int64}()\n", 238 | "\n", 239 | "#get word counts\n", 240 | "for word in wordlist\n", 241 | " wordcounts[word]=get(wordcounts, word, 0) + 1\n", 242 | "end" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "Now we have all the words read into the dictionary" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": null, 255 | "metadata": {}, 256 | "outputs": [], 257 | "source": [ 258 | "wordcounts" 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "metadata": {}, 264 | "source": [ 265 | "Try and analyze what are the most frequent words in our data set." 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": null, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": null, 278 | "metadata": {}, 279 | "outputs": [], 280 | "source": [] 281 | } 282 | ], 283 | "metadata": { 284 | "kernelspec": { 285 | "display_name": "Julia 1.0.3", 286 | "language": "julia", 287 | "name": "julia-1.0" 288 | }, 289 | "language_info": { 290 | "file_extension": ".jl", 291 | "mimetype": "application/julia", 292 | "name": "julia", 293 | "version": "1.0.3" 294 | } 295 | }, 296 | "nbformat": 4, 297 | "nbformat_minor": 2 298 | } 299 | -------------------------------------------------------------------------------- /exercises/06_Exercises-ecosystems-I.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: Julia ecosystem" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Installing a package: `Primes`\n", 15 | "\n", 16 | "Load the `Primes` packages (source code at https://github.com/JuliaMath/Primes.jl). \n", 17 | "\n", 18 | "Verify that you can now use the function `primes` to grab all the primes under `100`. If unsure, maybe `?primes` will help you?" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "### Simple plots\n", 33 | "\n", 34 | "Given `x = -10:10` plot y vs. x for \n", 35 | "$\n", 36 | "y=x^2\n", 37 | "$" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": null, 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "### Mount Bruno\n", 52 | "\n", 53 | "Let's visualize Mount Bruno! \n", 54 | "\n", 55 | "Read the 2D topological data of Mount Bruno from the file `../data/bruno.csv`. Next we need some plotting engine for `Plots`, I recommend `Plotly`/`PlotlyJS` for this task. As a final touch, see what `surface()` function can do with your array." 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": null, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "## Advanced: Animations\n", 70 | "\n", 71 | "Create an animation where `sin` and `cos` functions are evaluated for longer and longer arrays.\n", 72 | " \n", 73 | "A skeleton code is provided below." 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "gr() #use gr() backend\n", 83 | "\n", 84 | "xarr = [] #initial empty array\n", 85 | "\n", 86 | "p = plot()\n", 87 | "anim = Animation()\n", 88 | "for x = range(0, stop=10π, length=100)\n", 89 | " push!(xarr, x) #add a new value to xarr\n", 90 | "\n", 91 | " #all plotting can be done here; use xarr as your x values\n", 92 | "\n", 93 | " frame(anim)\n", 94 | "end\n", 95 | "gif(anim)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [] 104 | } 105 | ], 106 | "metadata": { 107 | "celltoolbar": "Slideshow", 108 | "kernelspec": { 109 | "display_name": "Julia 1.0.3", 110 | "language": "julia", 111 | "name": "julia-1.0" 112 | }, 113 | "language_info": { 114 | "file_extension": ".jl", 115 | "mimetype": "application/julia", 116 | "name": "julia", 117 | "version": "1.0.3" 118 | } 119 | }, 120 | "nbformat": 4, 121 | "nbformat_minor": 2 122 | } 123 | -------------------------------------------------------------------------------- /exercises/08_Exercises-ecosystems-II.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: Ecosystems II" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Own module\n", 15 | "\n", 16 | "Create your own julia module. Introduce some functions inside and then apply `export` to some of them. Try also putting some functions in another file and then including with `include`." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Catch up with your own field / interests\n", 31 | "Explore the Julia ecosystem. Is there a community that matches your interests? If not, maybe one should introduce such at some point...\n", 32 | "\n", 33 | "See also the [Curated decibans of Julia language](https://github.com/svaksha/Julia.jl).\n", 34 | "\n", 35 | "These might also be of interest:\n", 36 | "- [Archimedes and pi](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Archimedes%20and%20Pi.ipynb)\n", 37 | "- [Lorenz attractor](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Lorenz%20Attractor.ipynb)\n", 38 | "- [Mandelbrot](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Mandelbrot.ipynb)\n", 39 | "- [Terminal velocity](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Terminal%20Velocity.ipynb)\n", 40 | "- [Three-body problem](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Three-Body%20Problem.ipynb)\n", 41 | "\n", 42 | "On a more meta-level, check also [World of Julia](https://github.com/jiahao/ijulia-notebooks/blob/master/2014-06-30-world-of-julia.ipynb), a study of Julia contributors. Can you spot some familiar faces?" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [] 51 | } 52 | ], 53 | "metadata": { 54 | "kernelspec": { 55 | "display_name": "Julia 0.6.2", 56 | "language": "julia", 57 | "name": "julia-0.6" 58 | }, 59 | "language_info": { 60 | "file_extension": ".jl", 61 | "mimetype": "application/julia", 62 | "name": "julia", 63 | "version": "0.6.2" 64 | } 65 | }, 66 | "nbformat": 4, 67 | "nbformat_minor": 2 68 | } 69 | -------------------------------------------------------------------------------- /exercises/solutions/01_Solutions-basics.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: Basics" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Hello world!\n", 15 | "\n", 16 | "Let's begin our Julia journey with a proper way. Write a hello world program in Julia!" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 8, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "hello world!\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "println(\"hello world!\")" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "### Julia as calculator\n", 41 | "\n", 42 | "Try some simple math and solve these:\n", 43 | "\n", 44 | "$\n", 45 | "100 + 123 = ?\n", 46 | "$\n", 47 | "\n", 48 | "$\n", 49 | "5^2 = ?\n", 50 | "$\n", 51 | "\n", 52 | "$\n", 53 | "2\\pi = ?\n", 54 | "$\n", 55 | "\n", 56 | "$\n", 57 | "\\cos(2\\pi) = ?\n", 58 | "$\n", 59 | "\n", 60 | "$\n", 61 | "e^2 = ?\n", 62 | "$" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 1, 68 | "metadata": {}, 69 | "outputs": [ 70 | { 71 | "data": { 72 | "text/plain": [ 73 | "223" 74 | ] 75 | }, 76 | "execution_count": 1, 77 | "metadata": {}, 78 | "output_type": "execute_result" 79 | } 80 | ], 81 | "source": [ 82 | "100+123" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 2, 88 | "metadata": {}, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "text/plain": [ 93 | "25" 94 | ] 95 | }, 96 | "execution_count": 2, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "5^2" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 3, 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "data": { 112 | "text/plain": [ 113 | "6.283185307179586" 114 | ] 115 | }, 116 | "execution_count": 3, 117 | "metadata": {}, 118 | "output_type": "execute_result" 119 | } 120 | ], 121 | "source": [ 122 | "2π" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 4, 128 | "metadata": {}, 129 | "outputs": [ 130 | { 131 | "data": { 132 | "text/plain": [ 133 | "1.0" 134 | ] 135 | }, 136 | "execution_count": 4, 137 | "metadata": {}, 138 | "output_type": "execute_result" 139 | } 140 | ], 141 | "source": [ 142 | "cos(2π)" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 5, 148 | "metadata": {}, 149 | "outputs": [ 150 | { 151 | "data": { 152 | "text/plain": [ 153 | "7.38905609893065" 154 | ] 155 | }, 156 | "execution_count": 5, 157 | "metadata": {}, 158 | "output_type": "execute_result" 159 | } 160 | ], 161 | "source": [ 162 | "exp(2)" 163 | ] 164 | }, 165 | { 166 | "cell_type": "markdown", 167 | "metadata": { 168 | "slideshow": { 169 | "slide_type": "skip" 170 | } 171 | }, 172 | "source": [ 173 | "### Arrays\n", 174 | "\n", 175 | "Create an array `arr` with elements of `1,2,3,4,5`. Then add the number `6` to the end of this array. " 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": 11, 181 | "metadata": {}, 182 | "outputs": [ 183 | { 184 | "data": { 185 | "text/plain": [ 186 | "6-element Array{Int64,1}:\n", 187 | " 1\n", 188 | " 2\n", 189 | " 3\n", 190 | " 4\n", 191 | " 5\n", 192 | " 6" 193 | ] 194 | }, 195 | "execution_count": 11, 196 | "metadata": {}, 197 | "output_type": "execute_result" 198 | } 199 | ], 200 | "source": [ 201 | "arr = [1,2,3,4,5]\n", 202 | "\n", 203 | "push!(arr, 6)" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "metadata": {}, 209 | "source": [ 210 | "## Rational number magic\n", 211 | "\n", 212 | "How much is $ \\frac{3}{5} + \\frac{9}{10}$ ? Instead of typing `3/5 +...` etc. see what happens for `3//5 +...` etc." 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": 10, 218 | "metadata": {}, 219 | "outputs": [ 220 | { 221 | "data": { 222 | "text/plain": [ 223 | "3//2" 224 | ] 225 | }, 226 | "execution_count": 10, 227 | "metadata": {}, 228 | "output_type": "execute_result" 229 | } 230 | ], 231 | "source": [ 232 | "3//5 + 9//10" 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": null, 238 | "metadata": {}, 239 | "outputs": [], 240 | "source": [] 241 | } 242 | ], 243 | "metadata": { 244 | "kernelspec": { 245 | "display_name": "Julia 1.0.3", 246 | "language": "julia", 247 | "name": "julia-1.0" 248 | }, 249 | "language_info": { 250 | "file_extension": ".jl", 251 | "mimetype": "application/julia", 252 | "name": "julia", 253 | "version": "1.0.3" 254 | } 255 | }, 256 | "nbformat": 4, 257 | "nbformat_minor": 2 258 | } 259 | -------------------------------------------------------------------------------- /exercises/solutions/02_Solutions-control-flow.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: Control flow" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### if...\n", 15 | "\n", 16 | "Write a conditional statement that prints the number itself if it is smaller than zero, and the string \"positive\" if the number is larger than or equal to zero.\n" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "positive\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "x = 1 \n", 34 | "if x < 0\n", 35 | " println(x)\n", 36 | "else\n", 37 | " println(\"positive\")\n", 38 | "end" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "### ternary operator\n", 46 | "\n", 47 | "Rewrite the previous exercise using the ternary operator." 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 2, 53 | "metadata": {}, 54 | "outputs": [ 55 | { 56 | "name": "stdout", 57 | "output_type": "stream", 58 | "text": [ 59 | "positive\n" 60 | ] 61 | } 62 | ], 63 | "source": [ 64 | "(x < 0) ? println(x) : println(\"positive\")" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "### for-loops\n", 72 | "\n", 73 | "Loop over integers between 1 and 100 and print their squares." 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 3, 79 | "metadata": {}, 80 | "outputs": [ 81 | { 82 | "name": "stdout", 83 | "output_type": "stream", 84 | "text": [ 85 | "1\n", 86 | "4\n", 87 | "9\n", 88 | "16\n", 89 | "25\n", 90 | "36\n", 91 | "49\n", 92 | "64\n", 93 | "81\n", 94 | "100\n", 95 | "121\n", 96 | "144\n", 97 | "169\n", 98 | "196\n", 99 | "225\n", 100 | "256\n", 101 | "289\n", 102 | "324\n", 103 | "361\n", 104 | "400\n", 105 | "441\n", 106 | "484\n", 107 | "529\n", 108 | "576\n", 109 | "625\n", 110 | "676\n", 111 | "729\n", 112 | "784\n", 113 | "841\n", 114 | "900\n", 115 | "961\n", 116 | "1024\n", 117 | "1089\n", 118 | "1156\n", 119 | "1225\n", 120 | "1296\n", 121 | "1369\n", 122 | "1444\n", 123 | "1521\n", 124 | "1600\n", 125 | "1681\n", 126 | "1764\n", 127 | "1849\n", 128 | "1936\n", 129 | "2025\n", 130 | "2116\n", 131 | "2209\n", 132 | "2304\n", 133 | "2401\n", 134 | "2500\n", 135 | "2601\n", 136 | "2704\n", 137 | "2809\n", 138 | "2916\n", 139 | "3025\n", 140 | "3136\n", 141 | "3249\n", 142 | "3364\n", 143 | "3481\n", 144 | "3600\n", 145 | "3721\n", 146 | "3844\n", 147 | "3969\n", 148 | "4096\n", 149 | "4225\n", 150 | "4356\n", 151 | "4489\n", 152 | "4624\n", 153 | "4761\n", 154 | "4900\n", 155 | "5041\n", 156 | "5184\n", 157 | "5329\n", 158 | "5476\n", 159 | "5625\n", 160 | "5776\n", 161 | "5929\n", 162 | "6084\n", 163 | "6241\n", 164 | "6400\n", 165 | "6561\n", 166 | "6724\n", 167 | "6889\n", 168 | "7056\n", 169 | "7225\n", 170 | "7396\n", 171 | "7569\n", 172 | "7744\n", 173 | "7921\n", 174 | "8100\n", 175 | "8281\n", 176 | "8464\n", 177 | "8649\n", 178 | "8836\n", 179 | "9025\n", 180 | "9216\n", 181 | "9409\n", 182 | "9604\n", 183 | "9801\n", 184 | "10000\n" 185 | ] 186 | } 187 | ], 188 | "source": [ 189 | "for i = 1:100\n", 190 | " println(i^2)\n", 191 | "end" 192 | ] 193 | }, 194 | { 195 | "cell_type": "markdown", 196 | "metadata": {}, 197 | "source": [ 198 | "### while\n", 199 | "\n", 200 | "Do the same with a `while` statement" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 4, 206 | "metadata": {}, 207 | "outputs": [ 208 | { 209 | "name": "stdout", 210 | "output_type": "stream", 211 | "text": [ 212 | "1\n", 213 | "4\n", 214 | "9\n", 215 | "16\n", 216 | "25\n", 217 | "36\n", 218 | "49\n", 219 | "64\n", 220 | "81\n", 221 | "100\n", 222 | "121\n", 223 | "144\n", 224 | "169\n", 225 | "196\n", 226 | "225\n", 227 | "256\n", 228 | "289\n", 229 | "324\n", 230 | "361\n", 231 | "400\n", 232 | "441\n", 233 | "484\n", 234 | "529\n", 235 | "576\n", 236 | "625\n", 237 | "676\n", 238 | "729\n", 239 | "784\n", 240 | "841\n", 241 | "900\n", 242 | "961\n", 243 | "1024\n", 244 | "1089\n", 245 | "1156\n", 246 | "1225\n", 247 | "1296\n", 248 | "1369\n", 249 | "1444\n", 250 | "1521\n", 251 | "1600\n", 252 | "1681\n", 253 | "1764\n", 254 | "1849\n", 255 | "1936\n", 256 | "2025\n", 257 | "2116\n", 258 | "2209\n", 259 | "2304\n", 260 | "2401\n", 261 | "2500\n", 262 | "2601\n", 263 | "2704\n", 264 | "2809\n", 265 | "2916\n", 266 | "3025\n", 267 | "3136\n", 268 | "3249\n", 269 | "3364\n", 270 | "3481\n", 271 | "3600\n", 272 | "3721\n", 273 | "3844\n", 274 | "3969\n", 275 | "4096\n", 276 | "4225\n", 277 | "4356\n", 278 | "4489\n", 279 | "4624\n", 280 | "4761\n", 281 | "4900\n", 282 | "5041\n", 283 | "5184\n", 284 | "5329\n", 285 | "5476\n", 286 | "5625\n", 287 | "5776\n", 288 | "5929\n", 289 | "6084\n", 290 | "6241\n", 291 | "6400\n", 292 | "6561\n", 293 | "6724\n", 294 | "6889\n", 295 | "7056\n", 296 | "7225\n", 297 | "7396\n", 298 | "7569\n", 299 | "7744\n", 300 | "7921\n", 301 | "8100\n", 302 | "8281\n", 303 | "8464\n", 304 | "8649\n", 305 | "8836\n", 306 | "9025\n", 307 | "9216\n", 308 | "9409\n", 309 | "9604\n", 310 | "9801\n", 311 | "10000\n" 312 | ] 313 | } 314 | ], 315 | "source": [ 316 | "i = 1\n", 317 | "while i <= 100\n", 318 | " println(i^2)\n", 319 | " i += 1\n", 320 | "end" 321 | ] 322 | }, 323 | { 324 | "cell_type": "markdown", 325 | "metadata": {}, 326 | "source": [ 327 | "### arrays\n", 328 | "\n", 329 | "Use an array comprehension to create an an array that stores the squares for all integers between 1 and 100." 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 5, 335 | "metadata": {}, 336 | "outputs": [ 337 | { 338 | "data": { 339 | "text/plain": [ 340 | "100-element Array{Int64,1}:\n", 341 | " 1\n", 342 | " 4\n", 343 | " 9\n", 344 | " 16\n", 345 | " 25\n", 346 | " 36\n", 347 | " 49\n", 348 | " 64\n", 349 | " 81\n", 350 | " 100\n", 351 | " 121\n", 352 | " 144\n", 353 | " 169\n", 354 | " ⋮\n", 355 | " 7921\n", 356 | " 8100\n", 357 | " 8281\n", 358 | " 8464\n", 359 | " 8649\n", 360 | " 8836\n", 361 | " 9025\n", 362 | " 9216\n", 363 | " 9409\n", 364 | " 9604\n", 365 | " 9801\n", 366 | " 10000" 367 | ] 368 | }, 369 | "execution_count": 5, 370 | "metadata": {}, 371 | "output_type": "execute_result" 372 | } 373 | ], 374 | "source": [ 375 | "[x^2 for x = 1:100]" 376 | ] 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": {}, 381 | "source": [ 382 | "### Advanced: FizzBuzz\n", 383 | "\n", 384 | "Implement the (infamous) FizzBuzz test using Julia: \n", 385 | "\n", 386 | "Loop over numbers between 1 and 100. For every element:\n", 387 | "- given a number, N, print \"Fizz\" if N is divisible by 3, \n", 388 | "- \"Buzz\" if N is divisible by 5, \n", 389 | "- and \"FizzBuzz\" if N is divisible by 3 and 5. \n", 390 | "- Otherwise just print the number itself\n", 391 | "\n", 392 | "You can check the remainder of division using the `%` symbol, i.e., `3 % 2 = 1`" 393 | ] 394 | }, 395 | { 396 | "cell_type": "code", 397 | "execution_count": 6, 398 | "metadata": {}, 399 | "outputs": [ 400 | { 401 | "name": "stdout", 402 | "output_type": "stream", 403 | "text": [ 404 | "1\n", 405 | "2\n", 406 | "Fizz\n", 407 | "4\n", 408 | "Buzz\n", 409 | "Fizz\n", 410 | "7\n", 411 | "8\n", 412 | "Fizz\n", 413 | "Buzz\n", 414 | "11\n", 415 | "Fizz\n", 416 | "13\n", 417 | "14\n", 418 | "FizzBuzz\n", 419 | "16\n", 420 | "17\n", 421 | "Fizz\n", 422 | "19\n", 423 | "Buzz\n", 424 | "Fizz\n", 425 | "22\n", 426 | "23\n", 427 | "Fizz\n", 428 | "Buzz\n", 429 | "26\n", 430 | "Fizz\n", 431 | "28\n", 432 | "29\n", 433 | "FizzBuzz\n", 434 | "31\n", 435 | "32\n", 436 | "Fizz\n", 437 | "34\n", 438 | "Buzz\n", 439 | "Fizz\n", 440 | "37\n", 441 | "38\n", 442 | "Fizz\n", 443 | "Buzz\n", 444 | "41\n", 445 | "Fizz\n", 446 | "43\n", 447 | "44\n", 448 | "FizzBuzz\n", 449 | "46\n", 450 | "47\n", 451 | "Fizz\n", 452 | "49\n", 453 | "Buzz\n", 454 | "Fizz\n", 455 | "52\n", 456 | "53\n", 457 | "Fizz\n", 458 | "Buzz\n", 459 | "56\n", 460 | "Fizz\n", 461 | "58\n", 462 | "59\n", 463 | "FizzBuzz\n", 464 | "61\n", 465 | "62\n", 466 | "Fizz\n", 467 | "64\n", 468 | "Buzz\n", 469 | "Fizz\n", 470 | "67\n", 471 | "68\n", 472 | "Fizz\n", 473 | "Buzz\n", 474 | "71\n", 475 | "Fizz\n", 476 | "73\n", 477 | "74\n", 478 | "FizzBuzz\n", 479 | "76\n", 480 | "77\n", 481 | "Fizz\n", 482 | "79\n", 483 | "Buzz\n", 484 | "Fizz\n", 485 | "82\n", 486 | "83\n", 487 | "Fizz\n", 488 | "Buzz\n", 489 | "86\n", 490 | "Fizz\n", 491 | "88\n", 492 | "89\n", 493 | "FizzBuzz\n", 494 | "91\n", 495 | "92\n", 496 | "Fizz\n", 497 | "94\n", 498 | "Buzz\n", 499 | "Fizz\n", 500 | "97\n", 501 | "98\n", 502 | "Fizz\n", 503 | "Buzz\n" 504 | ] 505 | } 506 | ], 507 | "source": [ 508 | "for i = 1:100\n", 509 | " if i % 3 == 0 && i % 5 == 0\n", 510 | " println(\"FizzBuzz\")\n", 511 | " elseif i % 3 == 0\n", 512 | " println(\"Fizz\")\n", 513 | " elseif i % 5 == 0\n", 514 | " println(\"Buzz\")\n", 515 | " else\n", 516 | " println(i)\n", 517 | " end\n", 518 | "end" 519 | ] 520 | }, 521 | { 522 | "cell_type": "code", 523 | "execution_count": null, 524 | "metadata": {}, 525 | "outputs": [], 526 | "source": [] 527 | } 528 | ], 529 | "metadata": { 530 | "kernelspec": { 531 | "display_name": "Julia 1.0.3", 532 | "language": "julia", 533 | "name": "julia-1.0" 534 | }, 535 | "language_info": { 536 | "file_extension": ".jl", 537 | "mimetype": "application/julia", 538 | "name": "julia", 539 | "version": "1.0.3" 540 | } 541 | }, 542 | "nbformat": 4, 543 | "nbformat_minor": 2 544 | } 545 | -------------------------------------------------------------------------------- /exercises/solutions/03_Solutions-functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: Functions" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Introduction to functions\n", 15 | "\n", 16 | "Write a function named `addone` that adds 1 to its input." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "data": { 26 | "text/plain": [ 27 | "addone (generic function with 1 method)" 28 | ] 29 | }, 30 | "execution_count": 1, 31 | "metadata": {}, 32 | "output_type": "execute_result" 33 | } 34 | ], 35 | "source": [ 36 | "function addone(x)\n", 37 | " return x + 1\n", 38 | "end" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 2, 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "data": { 48 | "text/plain": [ 49 | "2" 50 | ] 51 | }, 52 | "execution_count": 2, 53 | "metadata": {}, 54 | "output_type": "execute_result" 55 | } 56 | ], 57 | "source": [ 58 | "addone(1)" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 3, 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "ename": "MethodError", 68 | "evalue": "MethodError: no method matching +(::Array{Int64,1}, ::Int64)\nClosest candidates are:\n +(::Any, ::Any, !Matched::Any, !Matched::Any...) at operators.jl:502\n +(!Matched::Complex{Bool}, ::Real) at complex.jl:292\n +(!Matched::Missing, ::Number) at missing.jl:93\n ...", 69 | "output_type": "error", 70 | "traceback": [ 71 | "MethodError: no method matching +(::Array{Int64,1}, ::Int64)\nClosest candidates are:\n +(::Any, ::Any, !Matched::Any, !Matched::Any...) at operators.jl:502\n +(!Matched::Complex{Bool}, ::Real) at complex.jl:292\n +(!Matched::Missing, ::Number) at missing.jl:93\n ...", 72 | "", 73 | "Stacktrace:", 74 | " [1] addone(::Array{Int64,1}) at ./In[1]:2", 75 | " [2] top-level scope at In[3]:1" 76 | ] 77 | } 78 | ], 79 | "source": [ 80 | "addone([1,2,3]) #note that it is not vectorized automatically!" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "### Polynomial\n", 88 | "\n", 89 | "Write your own 2nd order polynomial function `poly2(x)` that evaluates $4 + 3x + 2x^2$." 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 4, 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "poly2 (generic function with 1 method)" 101 | ] 102 | }, 103 | "execution_count": 4, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "source": [ 109 | "poly2(x) = 4 + 3x + 2x^2" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 5, 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "data": { 119 | "text/plain": [ 120 | "9" 121 | ] 122 | }, 123 | "execution_count": 5, 124 | "metadata": {}, 125 | "output_type": "execute_result" 126 | } 127 | ], 128 | "source": [ 129 | "poly2(1)" 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "metadata": {}, 135 | "source": [ 136 | "Abstractify your function a little to take `x` and `coeffs` as an input. `coeffs` should be an array of length `3` that holds the coefficients of the polynomial. Internally your function should then compute $C_3 x^2 + C_2 x + C_1$ where $C_i$ is the $i$th element of the `coeff` array." 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 6, 142 | "metadata": {}, 143 | "outputs": [ 144 | { 145 | "data": { 146 | "text/plain": [ 147 | "poly2 (generic function with 2 methods)" 148 | ] 149 | }, 150 | "execution_count": 6, 151 | "metadata": {}, 152 | "output_type": "execute_result" 153 | } 154 | ], 155 | "source": [ 156 | "function poly2(x, coeffs)\n", 157 | " @assert length(coeffs) == 3\n", 158 | "\n", 159 | " y = 0\n", 160 | " for i in 1:3\n", 161 | " y += coeffs[i] * x^(i-1)\n", 162 | " end\n", 163 | " return y\n", 164 | "end" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 7, 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "data": { 174 | "text/plain": [ 175 | "9" 176 | ] 177 | }, 178 | "execution_count": 7, 179 | "metadata": {}, 180 | "output_type": "execute_result" 181 | } 182 | ], 183 | "source": [ 184 | "poly2(1, [4,3,2])" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": {}, 190 | "source": [ 191 | "**Advanced**: Can you generalize your function to work for any $n$th order polynomial of the form $C_{n+1} x^{n} + C_{n} x^{n-1} \\ldots C_{n+1} x + C_n$ ?" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": 8, 197 | "metadata": {}, 198 | "outputs": [ 199 | { 200 | "data": { 201 | "text/plain": [ 202 | "poly (generic function with 1 method)" 203 | ] 204 | }, 205 | "execution_count": 8, 206 | "metadata": {}, 207 | "output_type": "execute_result" 208 | } 209 | ], 210 | "source": [ 211 | "function poly(x, coeffs)\n", 212 | " y = 0\n", 213 | " for i in 1:length(coeffs)\n", 214 | " y += coeffs[i] * x^(i-1)\n", 215 | " end\n", 216 | " return y\n", 217 | "end" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "### Map / Broadcast\n", 225 | "\n", 226 | "Use `map` or `broadcast` to increment every element of a matrix `A` by `1` using the function defined in the first exercise.\n", 227 | "\n", 228 | "You can easily create an empty matrix for testing with `A = zeros(5,5)`." 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 9, 234 | "metadata": {}, 235 | "outputs": [ 236 | { 237 | "data": { 238 | "text/plain": [ 239 | "5×5 Array{Float64,2}:\n", 240 | " 1.0 1.0 1.0 1.0 1.0\n", 241 | " 1.0 1.0 1.0 1.0 1.0\n", 242 | " 1.0 1.0 1.0 1.0 1.0\n", 243 | " 1.0 1.0 1.0 1.0 1.0\n", 244 | " 1.0 1.0 1.0 1.0 1.0" 245 | ] 246 | }, 247 | "execution_count": 9, 248 | "metadata": {}, 249 | "output_type": "execute_result" 250 | } 251 | ], 252 | "source": [ 253 | "A = zeros(5,5)\n", 254 | "\n", 255 | "map(addone, A)" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": {}, 261 | "source": [ 262 | "### Dot syntax\n", 263 | "\n", 264 | "Try out the broadcast dot syntax to increment every element of matrix `A` by `1` using the function defined in the first exercise." 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": 10, 270 | "metadata": {}, 271 | "outputs": [ 272 | { 273 | "data": { 274 | "text/plain": [ 275 | "5×5 Array{Float64,2}:\n", 276 | " 1.0 1.0 1.0 1.0 1.0\n", 277 | " 1.0 1.0 1.0 1.0 1.0\n", 278 | " 1.0 1.0 1.0 1.0 1.0\n", 279 | " 1.0 1.0 1.0 1.0 1.0\n", 280 | " 1.0 1.0 1.0 1.0 1.0" 281 | ] 282 | }, 283 | "execution_count": 10, 284 | "metadata": {}, 285 | "output_type": "execute_result" 286 | } 287 | ], 288 | "source": [ 289 | "addone.(A)" 290 | ] 291 | }, 292 | { 293 | "cell_type": "markdown", 294 | "metadata": {}, 295 | "source": [ 296 | "### Advanced: More dots\n", 297 | "Generalize the previous polynomial function to work for matrices, too. In practise this means that `x` can be of array too and the polynomial function is evaluated for every element of that array." 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "execution_count": 15, 303 | "metadata": {}, 304 | "outputs": [ 305 | { 306 | "data": { 307 | "text/plain": [ 308 | "poly (generic function with 1 method)" 309 | ] 310 | }, 311 | "execution_count": 15, 312 | "metadata": {}, 313 | "output_type": "execute_result" 314 | } 315 | ], 316 | "source": [ 317 | "function poly(x, coeffs)\n", 318 | " y = zeros(size(x))\n", 319 | " for i in 1:length(coeffs)\n", 320 | " y .+= coeffs[i] .* x.^(i-1)\n", 321 | " end\n", 322 | " return y\n", 323 | "end" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": 16, 329 | "metadata": {}, 330 | "outputs": [ 331 | { 332 | "data": { 333 | "text/plain": [ 334 | "4×4 Array{Float64,2}:\n", 335 | " 9.0 9.0 9.0 9.0\n", 336 | " 9.0 9.0 9.0 9.0\n", 337 | " 9.0 9.0 9.0 9.0\n", 338 | " 9.0 9.0 9.0 9.0" 339 | ] 340 | }, 341 | "execution_count": 16, 342 | "metadata": {}, 343 | "output_type": "execute_result" 344 | } 345 | ], 346 | "source": [ 347 | "x = ones(4,4)\n", 348 | "coeffs = [4,3,2]\n", 349 | "poly(x, coeffs)" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": null, 355 | "metadata": {}, 356 | "outputs": [], 357 | "source": [] 358 | } 359 | ], 360 | "metadata": { 361 | "kernelspec": { 362 | "display_name": "Julia 1.0.3", 363 | "language": "julia", 364 | "name": "julia-1.0" 365 | }, 366 | "language_info": { 367 | "file_extension": ".jl", 368 | "mimetype": "application/julia", 369 | "name": "julia", 370 | "version": "1.0.3" 371 | } 372 | }, 373 | "nbformat": 4, 374 | "nbformat_minor": 2 375 | } 376 | -------------------------------------------------------------------------------- /exercises/solutions/04_Solutions-io.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: IO" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Hi!\n", 15 | "\n", 16 | "Create a string that says \"hi\" 100 times. Hint: maybe there is some better way than just writing it 100 times?" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "data": { 26 | "text/plain": [ 27 | "\"hihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihi\"" 28 | ] 29 | }, 30 | "execution_count": 1, 31 | "metadata": {}, 32 | "output_type": "execute_result" 33 | } 34 | ], 35 | "source": [ 36 | "s = \"\"\n", 37 | "for i in 1:100\n", 38 | " s *= \"hi\"\n", 39 | "end\n", 40 | "\n", 41 | "s" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 2, 47 | "metadata": {}, 48 | "outputs": [ 49 | { 50 | "data": { 51 | "text/plain": [ 52 | "\"hihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihi\"" 53 | ] 54 | }, 55 | "execution_count": 2, 56 | "metadata": {}, 57 | "output_type": "execute_result" 58 | } 59 | ], 60 | "source": [ 61 | "#More elaborate way, since the power syntax is just calling multiplication under the hood (duck-typing)\n", 62 | "s = \"hi\"^100" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "### String interpolation\n", 70 | "\n", 71 | "Declare two variables \n", 72 | "```julia\n", 73 | "a = 3\n", 74 | "b = 4\n", 75 | "```\n", 76 | "and use them to create two strings\n", 77 | "```\n", 78 | "\"3 + 4\"\n", 79 | "\"7\"\n", 80 | "```" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 3, 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "name": "stdout", 90 | "output_type": "stream", 91 | "text": [ 92 | "3 + 4\n", 93 | "7\n" 94 | ] 95 | } 96 | ], 97 | "source": [ 98 | "a = 3\n", 99 | "b = 4\n", 100 | "\n", 101 | "s1 = \"$a + $b\"\n", 102 | "s2 = \"$(a+b)\"\n", 103 | "\n", 104 | "println(s1)\n", 105 | "println(s2)" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "### Simple file reading\n", 113 | "\n", 114 | "The file `\"../data/coordinates.txt\"` contains list of (x, y) value pairs. Read the values into an array using the `readdlm()` function. \n", 115 | "\n", 116 | "After that, write them into a file `coordinates.csv` using the CSV-format." 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 7, 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "text/plain": [ 127 | "10×2 Array{Float64,2}:\n", 128 | " -5.0 25.132 \n", 129 | " -3.88889 15.056 \n", 130 | " -2.77778 7.26171 \n", 131 | " -1.66667 2.90877 \n", 132 | " -0.555556 -0.141217\n", 133 | " 0.555556 0.176612\n", 134 | " 1.66667 2.83369 \n", 135 | " 2.77778 7.64384 \n", 136 | " 3.88889 14.9793 \n", 137 | " 5.0 25.2995 " 138 | ] 139 | }, 140 | "execution_count": 7, 141 | "metadata": {}, 142 | "output_type": "execute_result" 143 | } 144 | ], 145 | "source": [ 146 | "using DelimitedFiles\n", 147 | "arr = readdlm(\"../../data/coordinates.txt\")" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 8, 153 | "metadata": {}, 154 | "outputs": [], 155 | "source": [ 156 | "writedlm(\"../../data/coordinates.csv\", arr, ',')" 157 | ] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "metadata": {}, 162 | "source": [ 163 | "### Advanced: Not so simple file reading\n", 164 | "\n", 165 | "Read the values of the `../data/coordinate.txt` into two arrays called `x` and `y` using the `open()`, `readline()` or `eachline()`, `close()` syntax.\n", 166 | "\n", 167 | "HINT: You will somehow need to parse each string of lines into numbers. Use the help and see what `split()` and `parse(Float64,... )` can do for you." 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 17, 173 | "metadata": {}, 174 | "outputs": [ 175 | { 176 | "name": "stdout", 177 | "output_type": "stream", 178 | "text": [ 179 | " -5.000000 25.131953\n", 180 | " -3.888889 15.056032\n", 181 | " -2.777778 7.261712\n", 182 | " -1.666667 2.908772\n", 183 | " -0.555556 -0.141217\n", 184 | " 0.555556 0.176612\n", 185 | " 1.666667 2.833694\n", 186 | " 2.777778 7.643842\n", 187 | " 3.888889 14.979309\n", 188 | " 5.000000 25.299547\n" 189 | ] 190 | } 191 | ], 192 | "source": [ 193 | "x = Real[]\n", 194 | "y = Real[]\n", 195 | "open(\"../../data/coordinates.txt\", \"r\") do f\n", 196 | " for line in eachline(f)\n", 197 | " println(line)\n", 198 | "\n", 199 | " a,b = parse.(Float64, split(line))\n", 200 | " \n", 201 | " push!(x, a)\n", 202 | " push!(y, b)\n", 203 | " end\n", 204 | "end" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": null, 210 | "metadata": {}, 211 | "outputs": [], 212 | "source": [] 213 | } 214 | ], 215 | "metadata": { 216 | "kernelspec": { 217 | "display_name": "Julia 1.0.3", 218 | "language": "julia", 219 | "name": "julia-1.0" 220 | }, 221 | "language_info": { 222 | "file_extension": ".jl", 223 | "mimetype": "application/julia", 224 | "name": "julia", 225 | "version": "1.0.3" 226 | } 227 | }, 228 | "nbformat": 4, 229 | "nbformat_minor": 2 230 | } 231 | -------------------------------------------------------------------------------- /exercises/solutions/05_Solutions-development-practises.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: development practises" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Pretty functions\n", 15 | "\n", 16 | "Write a function called `blackbox`. It should behave such that it takes a number as an input and adds one to it. If a keyword argument `reverse=true` is also given, it should subtract one instead.\n" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 20, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "data": { 26 | "text/plain": [ 27 | "blackbox (generic function with 1 method)" 28 | ] 29 | }, 30 | "execution_count": 20, 31 | "metadata": {}, 32 | "output_type": "execute_result" 33 | } 34 | ], 35 | "source": [ 36 | "function blackbox(x::Number ;reverse=false)\n", 37 | " if reverse\n", 38 | " return x-1\n", 39 | " else\n", 40 | " return x+1\n", 41 | " end\n", 42 | "end" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 22, 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "data": { 52 | "text/plain": [ 53 | "2" 54 | ] 55 | }, 56 | "execution_count": 22, 57 | "metadata": {}, 58 | "output_type": "execute_result" 59 | } 60 | ], 61 | "source": [ 62 | "blackbox(1)" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 23, 68 | "metadata": {}, 69 | "outputs": [ 70 | { 71 | "data": { 72 | "text/plain": [ 73 | "3.0" 74 | ] 75 | }, 76 | "execution_count": 23, 77 | "metadata": {}, 78 | "output_type": "execute_result" 79 | } 80 | ], 81 | "source": [ 82 | "blackbox(2.0)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 24, 88 | "metadata": {}, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "text/plain": [ 93 | "99" 94 | ] 95 | }, 96 | "execution_count": 24, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "blackbox(100, reverse=true)" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "Write another `blackbox2` function that behaves like the previous but when given two arguments it uses the second argument as the value it adds or substracts. With one argument it behaves like the previous function.\n", 110 | "\n", 111 | "Hint: remember optional argument that can be given a default value!" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 26, 117 | "metadata": {}, 118 | "outputs": [ 119 | { 120 | "data": { 121 | "text/plain": [ 122 | "blackbox2 (generic function with 2 methods)" 123 | ] 124 | }, 125 | "execution_count": 26, 126 | "metadata": {}, 127 | "output_type": "execute_result" 128 | } 129 | ], 130 | "source": [ 131 | "function blackbox2(x::Number, val=1;reverse=false)\n", 132 | " if reverse\n", 133 | " return x-val\n", 134 | " else\n", 135 | " return x+val\n", 136 | " end\n", 137 | "end" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": 27, 143 | "metadata": {}, 144 | "outputs": [ 145 | { 146 | "data": { 147 | "text/plain": [ 148 | "15" 149 | ] 150 | }, 151 | "execution_count": 27, 152 | "metadata": {}, 153 | "output_type": "execute_result" 154 | } 155 | ], 156 | "source": [ 157 | "blackbox2(10,5)" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 28, 163 | "metadata": {}, 164 | "outputs": [ 165 | { 166 | "data": { 167 | "text/plain": [ 168 | "5" 169 | ] 170 | }, 171 | "execution_count": 28, 172 | "metadata": {}, 173 | "output_type": "execute_result" 174 | } 175 | ], 176 | "source": [ 177 | "blackbox2(10,5,reverse=true)" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "metadata": {}, 183 | "source": [ 184 | "## Multiple dispatch" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": {}, 190 | "source": [ 191 | "Extend the function `foo`, adding a method that takes only one input argument, which is of type `Bool`, and prints \"foo with one boolean!\"" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": 12, 197 | "metadata": {}, 198 | "outputs": [ 199 | { 200 | "data": { 201 | "text/plain": [ 202 | "foo (generic function with 1 method)" 203 | ] 204 | }, 205 | "execution_count": 12, 206 | "metadata": {}, 207 | "output_type": "execute_result" 208 | } 209 | ], 210 | "source": [ 211 | "foo(x::Bool) = println(\"foo with one boolean!\")" 212 | ] 213 | }, 214 | { 215 | "cell_type": "markdown", 216 | "metadata": {}, 217 | "source": [ 218 | "Check that the method being dispatched is the one you wrote by executing this:" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": 13, 224 | "metadata": {}, 225 | "outputs": [ 226 | { 227 | "name": "stdout", 228 | "output_type": "stream", 229 | "text": [ 230 | "foo with one boolean!\n" 231 | ] 232 | } 233 | ], 234 | "source": [ 235 | "foo(true)" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": 14, 241 | "metadata": {}, 242 | "outputs": [ 243 | { 244 | "data": { 245 | "text/html": [ 246 | "foo(x::Bool) in Main at In[12]:1" 247 | ], 248 | "text/plain": [ 249 | "foo(x::Bool) in Main at In[12]:1" 250 | ] 251 | }, 252 | "execution_count": 14, 253 | "metadata": {}, 254 | "output_type": "execute_result" 255 | } 256 | ], 257 | "source": [ 258 | "@which foo(true)" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": null, 264 | "metadata": {}, 265 | "outputs": [], 266 | "source": [] 267 | }, 268 | { 269 | "cell_type": "markdown", 270 | "metadata": {}, 271 | "source": [ 272 | "Now, extend `foo` such that with it prints\n", 273 | "- `I am integer` if the given value is integer\n", 274 | "- `I am float` if the given value is floating point number (i.e., float) \n", 275 | "- `I am string` if the given value is `String`, and\n", 276 | "- `I am something else` else\n", 277 | "\n", 278 | "Hint: It might help you to know that there exists such types as `Integer` and `AbstractFloat` in Julia." 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 18, 284 | "metadata": {}, 285 | "outputs": [ 286 | { 287 | "data": { 288 | "text/html": [ 289 | "5 methods for generic function foo:" 290 | ], 291 | "text/plain": [ 292 | "# 5 methods for generic function \"foo\":\n", 293 | "[1] foo(v::String) in Main at In[18]:4\n", 294 | "[2] foo(x::Bool) in Main at In[12]:1\n", 295 | "[3] foo(v::Integer) in Main at In[18]:2\n", 296 | "[4] foo(v::AbstractFloat) in Main at In[18]:3\n", 297 | "[5] foo(v) in Main at In[18]:1" 298 | ] 299 | }, 300 | "execution_count": 18, 301 | "metadata": {}, 302 | "output_type": "execute_result" 303 | } 304 | ], 305 | "source": [ 306 | "foo(v) = println(\"I am something else\")\n", 307 | "foo(v::Integer) = println(\"I am integer\")\n", 308 | "foo(v::AbstractFloat) = println(\"I am float\")\n", 309 | "foo(v::String) = println(\"I am string\")\n", 310 | "\n", 311 | "methods(foo)" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": 19, 317 | "metadata": {}, 318 | "outputs": [ 319 | { 320 | "name": "stdout", 321 | "output_type": "stream", 322 | "text": [ 323 | "I am integer\n", 324 | "I am float\n", 325 | "I am string\n", 326 | "I am something else\n" 327 | ] 328 | } 329 | ], 330 | "source": [ 331 | "foo(1) \n", 332 | "foo(1.0)\n", 333 | "foo(\"1\")\n", 334 | "foo([1,2,3]) # array as input" 335 | ] 336 | }, 337 | { 338 | "cell_type": "markdown", 339 | "metadata": {}, 340 | "source": [ 341 | "### Dictionaries\n", 342 | "\n", 343 | "So far we have not used dictionaries a lot. They can, however, improve the readability of your code tremendously. \n", 344 | "\n", 345 | "Create a dictionary whose keys are the fruits “pineapple”, “strawberry”, and “banana”. As values use numbers representing e.g. prices.\n", 346 | "\n", 347 | "Add “orange” to the dictionary and then remove “banana” from the dictionary. Investigate the contents of dictionary and pay attention to the order of key-value pairs.\n", 348 | "\n", 349 | "Just to remind you, the syntax for dictionaries is `dict = Dict(\"a\" => 1, \"b\" => 2, \"c\" => 3)`. They can be modified with an aptly named `delete!()` function." 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": 9, 355 | "metadata": {}, 356 | "outputs": [ 357 | { 358 | "data": { 359 | "text/plain": [ 360 | "Dict{String,Float64} with 3 entries:\n", 361 | " \"strawberry\" => 9.99\n", 362 | " \"banana\" => 0.49\n", 363 | " \"pineapple\" => 2.99" 364 | ] 365 | }, 366 | "execution_count": 9, 367 | "metadata": {}, 368 | "output_type": "execute_result" 369 | } 370 | ], 371 | "source": [ 372 | "fruits = Dict(\n", 373 | " \"pineapple\" => 2.99,\n", 374 | " \"strawberry\" => 9.99,\n", 375 | " \"banana\" => 0.49\n", 376 | " )" 377 | ] 378 | }, 379 | { 380 | "cell_type": "code", 381 | "execution_count": 10, 382 | "metadata": {}, 383 | "outputs": [ 384 | { 385 | "data": { 386 | "text/plain": [ 387 | "Dict{String,Float64} with 4 entries:\n", 388 | " \"orange\" => 1.99\n", 389 | " \"strawberry\" => 9.99\n", 390 | " \"banana\" => 0.49\n", 391 | " \"pineapple\" => 2.99" 392 | ] 393 | }, 394 | "execution_count": 10, 395 | "metadata": {}, 396 | "output_type": "execute_result" 397 | } 398 | ], 399 | "source": [ 400 | "fruits[\"orange\"] = 1.99\n", 401 | "fruits" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": 11, 407 | "metadata": {}, 408 | "outputs": [ 409 | { 410 | "data": { 411 | "text/plain": [ 412 | "Dict{String,Float64} with 3 entries:\n", 413 | " \"orange\" => 1.99\n", 414 | " \"strawberry\" => 9.99\n", 415 | " \"pineapple\" => 2.99" 416 | ] 417 | }, 418 | "execution_count": 11, 419 | "metadata": {}, 420 | "output_type": "execute_result" 421 | } 422 | ], 423 | "source": [ 424 | "delete!(fruits, \"banana\")" 425 | ] 426 | }, 427 | { 428 | "cell_type": "markdown", 429 | "metadata": {}, 430 | "source": [ 431 | "### Advanced: Dictionaries for language processing\n", 432 | "\n", 433 | "This is a more complex use-case of dictionaries for processing a Sherlock Holmes book.\n", 434 | "\n", 435 | "To build the dictionary, we loop through the list of words, and use `get()` to look up the current tally, if any. If the word has already been seen, the count can be increased. If the word hasn't been seen before, the fall-back third argument of get() ensures that the absence doesn't cause an error, and 1 is stored instead." 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": 6, 441 | "metadata": {}, 442 | "outputs": [], 443 | "source": [ 444 | "#read file\n", 445 | "f = open(\"../../data/sherlock-holmes.txt\")\n", 446 | "\n", 447 | "#first make everything lowercase\n", 448 | "#then use regexp to split by words\n", 449 | "#finally, keep=false means that characters in between words are not stored\n", 450 | "wordlist = split(lowercase(read(f, String)), r\"\\W\")\n", 451 | "close(f)\n", 452 | "\n", 453 | "#To store the words and the word counts, we'll create a spesific dictionary:\n", 454 | "wordcounts = Dict{String,Int64}()\n", 455 | "\n", 456 | "#get word counts\n", 457 | "for word in wordlist\n", 458 | " wordcounts[word]=get(wordcounts, word, 0) + 1\n", 459 | "end" 460 | ] 461 | }, 462 | { 463 | "cell_type": "markdown", 464 | "metadata": {}, 465 | "source": [ 466 | "Now we have all the words read into the dictionary" 467 | ] 468 | }, 469 | { 470 | "cell_type": "code", 471 | "execution_count": 7, 472 | "metadata": {}, 473 | "outputs": [ 474 | { 475 | "data": { 476 | "text/plain": [ 477 | "Dict{String,Int64} with 8167 entries:\n", 478 | " \"baleful\" => 1\n", 479 | " \"ferret\" => 1\n", 480 | " \"adviser\" => 2\n", 481 | " \"enjoy\" => 1\n", 482 | " \"shouldn\" => 1\n", 483 | " \"advertisements\" => 1\n", 484 | " \"fight\" => 3\n", 485 | " \"princess\" => 1\n", 486 | " \"everywhere\" => 1\n", 487 | " \"surveyed\" => 1\n", 488 | " \"helping\" => 1\n", 489 | " \"frowning\" => 1\n", 490 | " \"whose\" => 23\n", 491 | " \"sleepless\" => 1\n", 492 | " \"hurried\" => 22\n", 493 | " \"incoherent\" => 1\n", 494 | " \"henry\" => 10\n", 495 | " \"skylight\" => 4\n", 496 | " \"borders\" => 2\n", 497 | " \"drawers\" => 3\n", 498 | " \"star\" => 9\n", 499 | " \"prick\" => 1\n", 500 | " \"strand\" => 1\n", 501 | " \"rejoin\" => 1\n", 502 | " \"plan\" => 3\n", 503 | " ⋮ => ⋮" 504 | ] 505 | }, 506 | "execution_count": 7, 507 | "metadata": {}, 508 | "output_type": "execute_result" 509 | } 510 | ], 511 | "source": [ 512 | "wordcounts" 513 | ] 514 | }, 515 | { 516 | "cell_type": "markdown", 517 | "metadata": {}, 518 | "source": [ 519 | "Try and analyze what are the most frequent words in our data set." 520 | ] 521 | }, 522 | { 523 | "cell_type": "code", 524 | "execution_count": 8, 525 | "metadata": {}, 526 | "outputs": [ 527 | { 528 | "data": { 529 | "text/plain": [ 530 | "20-element Array{Pair{String,Int64},1}:\n", 531 | " \"\" => 38049\n", 532 | " \"the\" => 5810 \n", 533 | " \"and\" => 3088 \n", 534 | " \"i\" => 3038 \n", 535 | " \"to\" => 2823 \n", 536 | " \"of\" => 2778 \n", 537 | " \"a\" => 2700 \n", 538 | " \"in\" => 1823 \n", 539 | " \"that\" => 1767 \n", 540 | " \"it\" => 1749 \n", 541 | " \"you\" => 1572 \n", 542 | " \"he\" => 1486 \n", 543 | " \"was\" => 1411 \n", 544 | " \"his\" => 1159 \n", 545 | " \"is\" => 1150 \n", 546 | " \"my\" => 1007 \n", 547 | " \"have\" => 929 \n", 548 | " \"with\" => 877 \n", 549 | " \"as\" => 863 \n", 550 | " \"had\" => 830 " 551 | ] 552 | }, 553 | "execution_count": 8, 554 | "metadata": {}, 555 | "output_type": "execute_result" 556 | } 557 | ], 558 | "source": [ 559 | "# 20 most common words\n", 560 | "sort(collect(wordcounts), by = tuple -> last(tuple), rev=true)[1:20]" 561 | ] 562 | }, 563 | { 564 | "cell_type": "code", 565 | "execution_count": null, 566 | "metadata": {}, 567 | "outputs": [], 568 | "source": [] 569 | } 570 | ], 571 | "metadata": { 572 | "kernelspec": { 573 | "display_name": "Julia 1.0.3", 574 | "language": "julia", 575 | "name": "julia-1.0" 576 | }, 577 | "language_info": { 578 | "file_extension": ".jl", 579 | "mimetype": "application/julia", 580 | "name": "julia", 581 | "version": "1.0.3" 582 | } 583 | }, 584 | "nbformat": 4, 585 | "nbformat_minor": 2 586 | } 587 | -------------------------------------------------------------------------------- /exercises/solutions/08_Solutions-ecosystems-II.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exercises: Ecosystems II" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Own module\n", 15 | "\n", 16 | "Create your own julia module. Introduce some functions inside and then apply `export` to some of them. Try also putting some functions in another file and then including with `include`." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Catch up with your own field / interests\n", 31 | "Explore the Julia ecosystem. Is there a community that matches your interests? If not, maybe one should introduce such at some point...\n", 32 | "\n", 33 | "See also the [Curated decibans of Julia language](https://github.com/svaksha/Julia.jl).\n", 34 | "\n", 35 | "These might also be of interest:\n", 36 | "- [Archimedes and pi](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Archimedes%20and%20Pi.ipynb)\n", 37 | "- [Lorenz attractor](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Lorenz%20Attractor.ipynb)\n", 38 | "- [Mandelbrot](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Mandelbrot.ipynb)\n", 39 | "- [Terminal velocity](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Terminal%20Velocity.ipynb)\n", 40 | "- [Three-body problem](http://nbviewer.jupyter.org/github/pjpmarques/Julia-Modeling-the-World/blob/master/Three-Body%20Problem.ipynb)\n", 41 | "\n", 42 | "On a more meta-level, check also [World of Julia](https://github.com/jiahao/ijulia-notebooks/blob/master/2014-06-30-world-of-julia.ipynb), a study of Julia contributors. Can you spot some familiar faces?" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [] 51 | } 52 | ], 53 | "metadata": { 54 | "kernelspec": { 55 | "display_name": "Julia 0.6.2", 56 | "language": "julia", 57 | "name": "julia-0.6" 58 | }, 59 | "language_info": { 60 | "file_extension": ".jl", 61 | "mimetype": "application/julia", 62 | "name": "julia", 63 | "version": "0.6.2" 64 | } 65 | }, 66 | "nbformat": 4, 67 | "nbformat_minor": 2 68 | } 69 | -------------------------------------------------------------------------------- /notebooks/00_intro-to-julia.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Introduction to Julia\n", 12 | "*\"Are you sitting comfortably? Then I'll begin.\"* - [Julia Lang](https://en.wikipedia.org/wiki/Julia_Lang)" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": { 18 | "slideshow": { 19 | "slide_type": "fragment" 20 | } 21 | }, 22 | "source": [ 23 | "## Learning outcome \n", 24 | "\n", 25 | "- Learn basics of Julia\n", 26 | "- Get introduced to the (lively) Julia code ecosystem\n", 27 | "- Know where to look for more" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "slideshow": { 34 | "slide_type": "fragment" 35 | } 36 | }, 37 | "source": [ 38 | "## Target audience\n", 39 | "- Level of the content is aimed for beginners/intermediate students\n", 40 | " - but interesting bonus remarks are added here and there for the more advanced students too!\n", 41 | " - These notebooks should provide multiple [links](https://github.com/jupyter/jupyter/wiki/A-gallery-of-interesting-Jupyter-Notebooks#julia) to more advanced material and for [further reading](https://en.wikibooks.org/wiki/Introducing_Julia)" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": { 47 | "slideshow": { 48 | "slide_type": "slide" 49 | } 50 | }, 51 | "source": [ 52 | "## General remarks\n", 53 | "\n", 54 | "Julia is a high-level, high-performance dynamic programming language for numerical computing.\n", 55 | "\n", 56 | "### A summary of features:\n", 57 | "- Free and open source!\n", 58 | "- [Multiple dispatch](http://en.wikipedia.org/wiki/Multiple_dispatch)\n", 59 | "- Dynamic types\n", 60 | "- Good performance approaching that of statically-compiled languages like C\n", 61 | "- Built-in package manager\n", 62 | "- Lisp-like macros and other metaprogramming facilities\n", 63 | "- Call [Python functions](https://github.com/stevengj/PyCall.jl)\n", 64 | "- Call [C and Fortran functions](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/) directly\n", 65 | "- User-defined types are as fast and compact as built-ins because Julia is homoiconic" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": { 71 | "slideshow": { 72 | "slide_type": "slide" 73 | } 74 | }, 75 | "source": [ 76 | "## Open source\n", 77 | "Julia is open source, developed now by a community. \n", 78 | "\n", 79 | "Licensed under MIT license. \n", 80 | "- open and permissive license\n", 81 | "\n", 82 | "This means it *is* and *will be* open source." 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": { 88 | "slideshow": { 89 | "slide_type": "slide" 90 | } 91 | }, 92 | "source": [ 93 | "## High-performance JIT Compiler\n", 94 | "\n", 95 | "Julia's LLVM-based JIT compiler (Low level virtual machine just-in-time) compiler combined with the language's design allows it to approach and often match the performance of C in typical user scenarios." 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": { 101 | "slideshow": { 102 | "slide_type": "slide" 103 | } 104 | }, 105 | "source": [ 106 | "### A simple [benchmark](https://julialang.org/benchmarks/) relative to C:\n", 107 | "\n", 108 | "![benchmarks](../slides/benchmarks.svg)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": { 114 | "slideshow": { 115 | "slide_type": "slide" 116 | } 117 | }, 118 | "source": [ 119 | "## Versions\n", 120 | "\n", 121 | "Julia is evolving & actively being developed. Currently we are living in the `v1.1` era. \n", 122 | "\n", 123 | "### Time frame\n", 124 | "- started 2009 at MIT by Alan Edelman, Jeff Bezanson, Stefan Karpinski, Viral Shah\n", 125 | "- publicly announced 2012\n", 126 | "- `v0.6` 2017 Jun 19: pretty much the \"modern\" version of Julia\n", 127 | " - Some old stuff you encounter in the internet is targeted for this. So be aware! \n", 128 | "- `v0.7` 2018 Aug 8: short test release before v1\n", 129 | "- `v1.0` 2018 Aug 9: Official release\n", 130 | "- `v1.1` 2019 Jan 22: minor improvements & bug fixes" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": { 136 | "slideshow": { 137 | "slide_type": "slide" 138 | } 139 | }, 140 | "source": [ 141 | "## Syntax" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": null, 147 | "metadata": { 148 | "scrolled": false, 149 | "slideshow": { 150 | "slide_type": "fragment" 151 | } 152 | }, 153 | "outputs": [], 154 | "source": [ 155 | "function mandel(z)\n", 156 | " c = z\n", 157 | " maxiter = 80\n", 158 | " for n = 1:maxiter\n", 159 | " if abs(z) > 2\n", 160 | " return n-1\n", 161 | " end\n", 162 | " z = z^2 + c\n", 163 | " end\n", 164 | " return maxiter\n", 165 | "end\n", 166 | "[ mandel(complex(r,i)) for i=-1.:.2:1., r=-2.0:.2:0.5 ]" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": { 173 | "slideshow": { 174 | "slide_type": "slide" 175 | } 176 | }, 177 | "outputs": [], 178 | "source": [ 179 | "using Statistics\n", 180 | "using LinearAlgebra\n", 181 | "function randmatstat(t)\n", 182 | " n = 5\n", 183 | " v = zeros(t)\n", 184 | " w = zeros(t)\n", 185 | " for i=1:t\n", 186 | " a = randn(n,n)\n", 187 | " b = randn(n,n)\n", 188 | " c = randn(n,n)\n", 189 | " d = randn(n,n)\n", 190 | " P = [a b c d]\n", 191 | " Q = [a b; c d]\n", 192 | " v[i] = tr((P'*P)^4)\n", 193 | " w[i] = tr((Q'*Q)^4)\n", 194 | " end\n", 195 | " return (std(v)/mean(v), std(w)/mean(w))\n", 196 | "end\n", 197 | "randmatstat(2)" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": { 203 | "slideshow": { 204 | "slide_type": "fragment" 205 | } 206 | }, 207 | "source": [ 208 | "Compare to [C implementation](https://github.com/JuliaLang/Microbenchmarks/blob/master/perf.c#L135) (although the comparison is not 100% fair)" 209 | ] 210 | }, 211 | { 212 | "cell_type": "markdown", 213 | "metadata": { 214 | "slideshow": { 215 | "slide_type": "slide" 216 | } 217 | }, 218 | "source": [ 219 | "## First program" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": null, 225 | "metadata": { 226 | "slideshow": { 227 | "slide_type": "fragment" 228 | } 229 | }, 230 | "outputs": [], 231 | "source": [ 232 | "println(\"hello world!\")" 233 | ] 234 | }, 235 | { 236 | "cell_type": "markdown", 237 | "metadata": { 238 | "slideshow": { 239 | "slide_type": "fragment" 240 | } 241 | }, 242 | "source": [ 243 | "This can be run directly inside the `jupyter` notebook environment. But, you can also copy the command into file and run it from the command line\n", 244 | "\n", 245 | "```bash\n", 246 | "$ julia hello.jl\n", 247 | "```\n", 248 | "or within the Julia interpreter\n", 249 | "```\n", 250 | "julia> include(\"hello.jl\")\n", 251 | "```\n" 252 | ] 253 | }, 254 | { 255 | "cell_type": "markdown", 256 | "metadata": { 257 | "slideshow": { 258 | "slide_type": "slide" 259 | } 260 | }, 261 | "source": [ 262 | "## Getting help\n", 263 | "The built-in `help` environment can be activated by pressing `?` inside the interactive julia interpreter (REPL)." 264 | ] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": 26, 269 | "metadata": { 270 | "slideshow": { 271 | "slide_type": "fragment" 272 | } 273 | }, 274 | "outputs": [ 275 | { 276 | "name": "stdout", 277 | "output_type": "stream", 278 | "text": [ 279 | "search: \u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22m\u001b[0m\u001b[1ml\u001b[22m\u001b[0m\u001b[1mn\u001b[22m \u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22msty\u001b[0m\u001b[1ml\u001b[22med \u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22m s\u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22m is\u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22m\n", 280 | "\n" 281 | ] 282 | }, 283 | { 284 | "data": { 285 | "text/latex": [ 286 | "\\begin{verbatim}\n", 287 | "println([io::IO], xs...)\n", 288 | "\\end{verbatim}\n", 289 | "Print (using \\href{@ref}{\\texttt{print}}) \\texttt{xs} followed by a newline. If \\texttt{io} is not supplied, prints to \\href{@ref}{\\texttt{stdout}}.\n", 290 | "\n", 291 | "\\section{Examples}\n", 292 | "\\begin{verbatim}\n", 293 | "julia> println(\"Hello, world\")\n", 294 | "Hello, world\n", 295 | "\n", 296 | "julia> io = IOBuffer();\n", 297 | "\n", 298 | "julia> println(io, \"Hello, world\")\n", 299 | "\n", 300 | "julia> String(take!(io))\n", 301 | "\"Hello, world\\n\"\n", 302 | "\\end{verbatim}\n" 303 | ], 304 | "text/markdown": [ 305 | "```\n", 306 | "println([io::IO], xs...)\n", 307 | "```\n", 308 | "\n", 309 | "Print (using [`print`](@ref)) `xs` followed by a newline. If `io` is not supplied, prints to [`stdout`](@ref).\n", 310 | "\n", 311 | "# Examples\n", 312 | "\n", 313 | "```jldoctest\n", 314 | "julia> println(\"Hello, world\")\n", 315 | "Hello, world\n", 316 | "\n", 317 | "julia> io = IOBuffer();\n", 318 | "\n", 319 | "julia> println(io, \"Hello, world\")\n", 320 | "\n", 321 | "julia> String(take!(io))\n", 322 | "\"Hello, world\\n\"\n", 323 | "```\n" 324 | ], 325 | "text/plain": [ 326 | "\u001b[36m println([io::IO], xs...)\u001b[39m\n", 327 | "\n", 328 | " Print (using \u001b[36mprint\u001b[39m) \u001b[36mxs\u001b[39m followed by a newline. If \u001b[36mio\u001b[39m is not supplied, prints\n", 329 | " to \u001b[36mstdout\u001b[39m.\n", 330 | "\n", 331 | "\u001b[1m Examples\u001b[22m\n", 332 | "\u001b[1m ≡≡≡≡≡≡≡≡≡≡\u001b[22m\n", 333 | "\n", 334 | "\u001b[36m julia> println(\"Hello, world\")\u001b[39m\n", 335 | "\u001b[36m Hello, world\u001b[39m\n", 336 | "\u001b[36m \u001b[39m\n", 337 | "\u001b[36m julia> io = IOBuffer();\u001b[39m\n", 338 | "\u001b[36m \u001b[39m\n", 339 | "\u001b[36m julia> println(io, \"Hello, world\")\u001b[39m\n", 340 | "\u001b[36m \u001b[39m\n", 341 | "\u001b[36m julia> String(take!(io))\u001b[39m\n", 342 | "\u001b[36m \"Hello, world\\n\"\u001b[39m" 343 | ] 344 | }, 345 | "execution_count": 26, 346 | "metadata": {}, 347 | "output_type": "execute_result" 348 | } 349 | ], 350 | "source": [ 351 | "?println" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": null, 357 | "metadata": {}, 358 | "outputs": [], 359 | "source": [] 360 | } 361 | ], 362 | "metadata": { 363 | "celltoolbar": "Slideshow", 364 | "kernelspec": { 365 | "display_name": "Julia 1.0.3", 366 | "language": "julia", 367 | "name": "julia-1.0" 368 | }, 369 | "language_info": { 370 | "file_extension": ".jl", 371 | "mimetype": "application/julia", 372 | "name": "julia", 373 | "version": "1.0.3" 374 | } 375 | }, 376 | "nbformat": 4, 377 | "nbformat_minor": 2 378 | } 379 | -------------------------------------------------------------------------------- /notebooks/00_notebooks.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Getting started with Jupyter notebooks" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "subslide" 19 | } 20 | }, 21 | "source": [ 22 | "## Interactively\n", 23 | "- [CSC notebook environment](https://notebooks.csc.fi/) (*recommended*)\n", 24 | "- [JuliaBox](https://www.juliabox.com) (Amazon web server reserver for Julia teaching)\n", 25 | "- [notebooks.csc.fi](https://notebooks.csc.fi/) with HAKA-account.\n", 26 | "\n", 27 | "## Locally\n", 28 | "- `IJulia` [repository](https://github.com/JuliaLang/IJulia.jl)\n", 29 | "- via `Pkg` as `using Pkg` and `Pkg.add(\"IJulia\")`\n", 30 | "- `using IJulia` and opening a new notebook in your browser `notebook()`" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": { 36 | "slideshow": { 37 | "slide_type": "slide" 38 | } 39 | }, 40 | "source": [ 41 | "## Running a cell\n", 42 | "\n", 43 | "To execute code within a cell, select that cell and either (1) hit `Shift` and `Enter` or (2) hit the run button (the right pointing arrow) above." 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 1, 49 | "metadata": { 50 | "slideshow": { 51 | "slide_type": "fragment" 52 | } 53 | }, 54 | "outputs": [ 55 | { 56 | "data": { 57 | "text/plain": [ 58 | "4" 59 | ] 60 | }, 61 | "execution_count": 1, 62 | "metadata": {}, 63 | "output_type": "execute_result" 64 | } 65 | ], 66 | "source": [ 67 | "1 + 1\n", 68 | "2 + 2 " 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": { 74 | "slideshow": { 75 | "slide_type": "fragment" 76 | } 77 | }, 78 | "source": [ 79 | "Note that only the last line of a cell prints by default. It is possible to suppress this output with a semicolon." 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 2, 85 | "metadata": { 86 | "slideshow": { 87 | "slide_type": "fragment" 88 | } 89 | }, 90 | "outputs": [], 91 | "source": [ 92 | "1 + 1\n", 93 | "2 + 2;" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": { 99 | "slideshow": { 100 | "slide_type": "slide" 101 | } 102 | }, 103 | "source": [ 104 | "## How to get docs for Julia functions\n", 105 | "\n", 106 | "To get docs for a function, precede it with a question mark. This works in the REPL too." 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 3, 112 | "metadata": { 113 | "slideshow": { 114 | "slide_type": "fragment" 115 | } 116 | }, 117 | "outputs": [ 118 | { 119 | "name": "stdout", 120 | "output_type": "stream", 121 | "text": [ 122 | "search: \u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22m\u001b[0m\u001b[1ml\u001b[22m\u001b[0m\u001b[1mn\u001b[22m \u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22msty\u001b[0m\u001b[1ml\u001b[22med \u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22m s\u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22m is\u001b[0m\u001b[1mp\u001b[22m\u001b[0m\u001b[1mr\u001b[22m\u001b[0m\u001b[1mi\u001b[22m\u001b[0m\u001b[1mn\u001b[22m\u001b[0m\u001b[1mt\u001b[22m\n", 123 | "\n" 124 | ] 125 | }, 126 | { 127 | "data": { 128 | "text/latex": [ 129 | "\\begin{verbatim}\n", 130 | "println([io::IO], xs...)\n", 131 | "\\end{verbatim}\n", 132 | "Print (using \\href{@ref}{\\texttt{print}}) \\texttt{xs} followed by a newline. If \\texttt{io} is not supplied, prints to \\href{@ref}{\\texttt{stdout}}.\n", 133 | "\n", 134 | "\\section{Examples}\n", 135 | "\\begin{verbatim}\n", 136 | "julia> println(\"Hello, world\")\n", 137 | "Hello, world\n", 138 | "\n", 139 | "julia> io = IOBuffer();\n", 140 | "\n", 141 | "julia> println(io, \"Hello, world\")\n", 142 | "\n", 143 | "julia> String(take!(io))\n", 144 | "\"Hello, world\\n\"\n", 145 | "\\end{verbatim}\n" 146 | ], 147 | "text/markdown": [ 148 | "```\n", 149 | "println([io::IO], xs...)\n", 150 | "```\n", 151 | "\n", 152 | "Print (using [`print`](@ref)) `xs` followed by a newline. If `io` is not supplied, prints to [`stdout`](@ref).\n", 153 | "\n", 154 | "# Examples\n", 155 | "\n", 156 | "```jldoctest\n", 157 | "julia> println(\"Hello, world\")\n", 158 | "Hello, world\n", 159 | "\n", 160 | "julia> io = IOBuffer();\n", 161 | "\n", 162 | "julia> println(io, \"Hello, world\")\n", 163 | "\n", 164 | "julia> String(take!(io))\n", 165 | "\"Hello, world\\n\"\n", 166 | "```\n" 167 | ], 168 | "text/plain": [ 169 | "\u001b[36m println([io::IO], xs...)\u001b[39m\n", 170 | "\n", 171 | " Print (using \u001b[36mprint\u001b[39m) \u001b[36mxs\u001b[39m followed by a newline. If \u001b[36mio\u001b[39m is not supplied, prints\n", 172 | " to \u001b[36mstdout\u001b[39m.\n", 173 | "\n", 174 | "\u001b[1m Examples\u001b[22m\n", 175 | "\u001b[1m ≡≡≡≡≡≡≡≡≡≡\u001b[22m\n", 176 | "\n", 177 | "\u001b[36m julia> println(\"Hello, world\")\u001b[39m\n", 178 | "\u001b[36m Hello, world\u001b[39m\n", 179 | "\u001b[36m \u001b[39m\n", 180 | "\u001b[36m julia> io = IOBuffer();\u001b[39m\n", 181 | "\u001b[36m \u001b[39m\n", 182 | "\u001b[36m julia> println(io, \"Hello, world\")\u001b[39m\n", 183 | "\u001b[36m \u001b[39m\n", 184 | "\u001b[36m julia> String(take!(io))\u001b[39m\n", 185 | "\u001b[36m \"Hello, world\\n\"\u001b[39m" 186 | ] 187 | }, 188 | "execution_count": 3, 189 | "metadata": {}, 190 | "output_type": "execute_result" 191 | } 192 | ], 193 | "source": [ 194 | "?println" 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "metadata": { 200 | "slideshow": { 201 | "slide_type": "slide" 202 | } 203 | }, 204 | "source": [ 205 | "## How to use shell commands\n", 206 | "\n", 207 | "Type `;` and then you can use (UNIX) shell commands." 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": 4, 213 | "metadata": { 214 | "slideshow": { 215 | "slide_type": "fragment" 216 | } 217 | }, 218 | "outputs": [ 219 | { 220 | "name": "stdout", 221 | "output_type": "stream", 222 | "text": [ 223 | "00_intro-to-julia.ipynb\n", 224 | "00_notebooks.ipynb\n", 225 | "01_basics.ipynb\n", 226 | "02_control-flow.ipynb\n", 227 | "03_functions.ipynb\n", 228 | "04_io.ipynb\n", 229 | "05_development-practises.ipynb\n", 230 | "06_ecosystem-I.ipynb\n", 231 | "07_ecosystem-II.ipynb\n", 232 | "08_hpc.ipynb\n", 233 | "Bonus_metaprogramming.ipynb\n", 234 | "Bonus_simd-vectorization.ipynb\n", 235 | "tmp.gif\n" 236 | ] 237 | } 238 | ], 239 | "source": [ 240 | ";ls" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 5, 246 | "metadata": { 247 | "slideshow": { 248 | "slide_type": "fragment" 249 | } 250 | }, 251 | "outputs": [ 252 | { 253 | "name": "stdout", 254 | "output_type": "stream", 255 | "text": [ 256 | "/Users/natj/Documents/csc/julia-introduction/notebooks\n" 257 | ] 258 | } 259 | ], 260 | "source": [ 261 | ";pwd" 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": null, 267 | "metadata": {}, 268 | "outputs": [], 269 | "source": [] 270 | } 271 | ], 272 | "metadata": { 273 | "celltoolbar": "Slideshow", 274 | "kernelspec": { 275 | "display_name": "Julia 1.0.3", 276 | "language": "julia", 277 | "name": "julia-1.0" 278 | }, 279 | "language_info": { 280 | "file_extension": ".jl", 281 | "mimetype": "application/julia", 282 | "name": "julia", 283 | "version": "1.0.3" 284 | } 285 | }, 286 | "nbformat": 4, 287 | "nbformat_minor": 2 288 | } 289 | -------------------------------------------------------------------------------- /notebooks/01_basics.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Basics of Julia\n", 12 | "\n" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": { 18 | "slideshow": { 19 | "slide_type": "fragment" 20 | } 21 | }, 22 | "source": [ 23 | "## Topics\n", 24 | "- printing\n", 25 | "- commenting\n", 26 | "- syntax\n", 27 | "- types\n", 28 | "- arrays\n", 29 | " - arrays, tuples, dictionaries" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": { 35 | "slideshow": { 36 | "slide_type": "slide" 37 | } 38 | }, 39 | "source": [ 40 | "## How to print\n", 41 | "\n", 42 | "In Julia we usually use `println()` to print. This is `print` followed with a newline (`ln`)." 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": { 49 | "slideshow": { 50 | "slide_type": "fragment" 51 | } 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "println(\"Let's get started!\")" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": { 61 | "slideshow": { 62 | "slide_type": "slide" 63 | } 64 | }, 65 | "source": [ 66 | "## How to comment" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "metadata": { 73 | "slideshow": { 74 | "slide_type": "fragment" 75 | } 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "# You can leave a comment on a single line like this" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": null, 85 | "metadata": { 86 | "slideshow": { 87 | "slide_type": "fragment" 88 | } 89 | }, 90 | "outputs": [], 91 | "source": [ 92 | "#=\n", 93 | "For a multi-line comments,\n", 94 | "use the '#= =#' sequence.\n", 95 | "\n", 96 | "=#" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": { 102 | "slideshow": { 103 | "slide_type": "slide" 104 | } 105 | }, 106 | "source": [ 107 | "## How to assign variables\n", 108 | "\n", 109 | "All we need is a variable name, value, and an equal sign. Julia will figure out types for us. Try it out below:" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": null, 115 | "metadata": { 116 | "slideshow": { 117 | "slide_type": "fragment" 118 | } 119 | }, 120 | "outputs": [], 121 | "source": [ 122 | "my_anwer = 42\n", 123 | "typeof(my_anwer)" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": null, 129 | "metadata": { 130 | "slideshow": { 131 | "slide_type": "fragment" 132 | } 133 | }, 134 | "outputs": [], 135 | "source": [ 136 | "my_pi = 3.14159\n", 137 | "typeof(my_pi)" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": { 144 | "slideshow": { 145 | "slide_type": "fragment" 146 | } 147 | }, 148 | "outputs": [], 149 | "source": [ 150 | "😺 = \"smiley cat!\"\n", 151 | "typeof(😺)" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": { 157 | "slideshow": { 158 | "slide_type": "slide" 159 | } 160 | }, 161 | "source": [ 162 | "## Variables and data types\n", 163 | "Julia allows to write generic code. Symbols like 😺 are an example of this. \n", 164 | "\n", 165 | "In Julia variable names \n", 166 | "- may contain letters, numbers, underscores or exclamation marks.\n", 167 | "- start with a letter or underscores (but not with a number!)\n", 168 | "- are case sensitive\n", 169 | "- in addition, UTF-8 symbols are supported!" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": { 175 | "slideshow": { 176 | "slide_type": "slide" 177 | } 178 | }, 179 | "source": [ 180 | "## Special characters\n", 181 | "Julia supports many special characters familiar from `LaTeX`. Just try common names such as `\\alpha` and press `` to complete. \n", 182 | "\n", 183 | "If the name is not familiar to you, just copy the character and use the `?` to probe what it is." 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "metadata": { 190 | "slideshow": { 191 | "slide_type": "fragment" 192 | } 193 | }, 194 | "outputs": [], 195 | "source": [ 196 | "α = 0.01\n", 197 | "β = 0.2" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": 21, 203 | "metadata": { 204 | "slideshow": { 205 | "slide_type": "fragment" 206 | } 207 | }, 208 | "outputs": [ 209 | { 210 | "data": { 211 | "text/plain": [ 212 | "π = 3.1415926535897..." 213 | ] 214 | }, 215 | "execution_count": 21, 216 | "metadata": {}, 217 | "output_type": "execute_result" 218 | } 219 | ], 220 | "source": [ 221 | "π #some are already defined, like pi" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 22, 227 | "metadata": { 228 | "slideshow": { 229 | "slide_type": "slide" 230 | } 231 | }, 232 | "outputs": [ 233 | { 234 | "name": "stdout", 235 | "output_type": "stream", 236 | "text": [ 237 | "\"\u001b[36mγ\u001b[39m\" can be typed by \u001b[36m\\gamma\u001b[39m\n", 238 | "\n", 239 | "search:\n", 240 | "\n", 241 | "Couldn't find \u001b[36mγ\u001b[39m\n", 242 | "Perhaps you meant a, b, c, x, α, β, 😺, !, %, &, *, +, -, /, :, <, >, \\, ^ or |\n" 243 | ] 244 | }, 245 | { 246 | "data": { 247 | "text/latex": [ 248 | "No documentation found.\n", 249 | "\n", 250 | "Binding \\texttt{γ} does not exist.\n", 251 | "\n" 252 | ], 253 | "text/markdown": [ 254 | "No documentation found.\n", 255 | "\n", 256 | "Binding `γ` does not exist.\n" 257 | ], 258 | "text/plain": [ 259 | " No documentation found.\n", 260 | "\n", 261 | " Binding \u001b[36mγ\u001b[39m does not exist." 262 | ] 263 | }, 264 | "execution_count": 22, 265 | "metadata": {}, 266 | "output_type": "execute_result" 267 | } 268 | ], 269 | "source": [ 270 | "?γ" 271 | ] 272 | }, 273 | { 274 | "cell_type": "markdown", 275 | "metadata": { 276 | "slideshow": { 277 | "slide_type": "slide" 278 | } 279 | }, 280 | "source": [ 281 | "## Dynamic and loose\n", 282 | "Julia is a dynamically and loosely typed language.\n", 283 | "In practise, this means that:\n", 284 | "- variables (and their types) don't need to be declared\n", 285 | " - but they can be\n", 286 | "- variables are automatically casted to \"correct\" types" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": null, 292 | "metadata": { 293 | "slideshow": { 294 | "slide_type": "fragment" 295 | } 296 | }, 297 | "outputs": [], 298 | "source": [ 299 | "a = 1\n", 300 | "b = 3\n", 301 | "c = a/b #what will happen?" 302 | ] 303 | }, 304 | { 305 | "cell_type": "markdown", 306 | "metadata": { 307 | "slideshow": { 308 | "slide_type": "slide" 309 | } 310 | }, 311 | "source": [ 312 | "# Data types\n", 313 | "### Primitive and abstract types\n", 314 | "- Numeric types, that represent numbers\n", 315 | " - `Number`\n", 316 | " - `Real` (example: `a::Real`)\n", 317 | " - `Integer` (example: `b::Int`)\n", 318 | " - `Int16`, `Int32`, `Int64`,..., `UInt64`\n", 319 | " - `AbstractFloat` \n", 320 | " - `Float16`, `Float32`,`Float64`,...\n", 321 | "- Strings (`String`, `Char`,...)\n", 322 | "- `Bool` is a data type that can be either `true` or `false`.\n", 323 | "\n", 324 | "### Composite types\n", 325 | "- `complex` (`Complex{Int64}`,...) with `1 + 0.1im`\n", 326 | "- Arrays (`Array{Int64,1}`,...)\n", 327 | "- Mappings\n", 328 | " - `Dict`: a dictionary, also called a hashmap (`Dict{String,Int64}`,...)\n", 329 | "\n" 330 | ] 331 | }, 332 | { 333 | "cell_type": "markdown", 334 | "metadata": { 335 | "slideshow": { 336 | "slide_type": "fragment" 337 | } 338 | }, 339 | "source": [ 340 | "To learn more about Types in Julia, see the [manual entry on types](https://docs.julialang.org/en/v1/manual/types/).\n", 341 | "We, for example, completely omit the discussion of parametric types here." 342 | ] 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "metadata": { 347 | "slideshow": { 348 | "slide_type": "slide" 349 | } 350 | }, 351 | "source": [ 352 | "## Syntax for basic math" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": null, 358 | "metadata": { 359 | "slideshow": { 360 | "slide_type": "fragment" 361 | } 362 | }, 363 | "outputs": [], 364 | "source": [ 365 | "sum = 3 + 7" 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": null, 371 | "metadata": { 372 | "slideshow": { 373 | "slide_type": "fragment" 374 | } 375 | }, 376 | "outputs": [], 377 | "source": [ 378 | "difference = 10 - 3" 379 | ] 380 | }, 381 | { 382 | "cell_type": "code", 383 | "execution_count": null, 384 | "metadata": { 385 | "slideshow": { 386 | "slide_type": "fragment" 387 | } 388 | }, 389 | "outputs": [], 390 | "source": [ 391 | "product = 20 * 5" 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": null, 397 | "metadata": { 398 | "slideshow": { 399 | "slide_type": "fragment" 400 | } 401 | }, 402 | "outputs": [], 403 | "source": [ 404 | "quotient = 100 / 10" 405 | ] 406 | }, 407 | { 408 | "cell_type": "code", 409 | "execution_count": null, 410 | "metadata": { 411 | "slideshow": { 412 | "slide_type": "fragment" 413 | } 414 | }, 415 | "outputs": [], 416 | "source": [ 417 | "power = 10 ^ 2" 418 | ] 419 | }, 420 | { 421 | "cell_type": "code", 422 | "execution_count": null, 423 | "metadata": { 424 | "slideshow": { 425 | "slide_type": "fragment" 426 | } 427 | }, 428 | "outputs": [], 429 | "source": [ 430 | "modulus = 101 % 2" 431 | ] 432 | }, 433 | { 434 | "cell_type": "markdown", 435 | "metadata": { 436 | "slideshow": { 437 | "slide_type": "slide" 438 | } 439 | }, 440 | "source": [ 441 | "## Numeric literal coefficients\n", 442 | "To make common formulas and expressions more clear, Julia allows variables to be immediately preceded by a number, implying multiplication. \n", 443 | "\n", 444 | "This makes writing polynomial expressions much cleaner:" 445 | ] 446 | }, 447 | { 448 | "cell_type": "code", 449 | "execution_count": null, 450 | "metadata": { 451 | "slideshow": { 452 | "slide_type": "fragment" 453 | } 454 | }, 455 | "outputs": [], 456 | "source": [ 457 | "x = 3\n", 458 | "2x^2 - 3.5x + 1" 459 | ] 460 | }, 461 | { 462 | "cell_type": "code", 463 | "execution_count": null, 464 | "metadata": { 465 | "slideshow": { 466 | "slide_type": "fragment" 467 | } 468 | }, 469 | "outputs": [], 470 | "source": [ 471 | "2(x-1)^2 - 3(x-1) + 1" 472 | ] 473 | }, 474 | { 475 | "cell_type": "markdown", 476 | "metadata": { 477 | "slideshow": { 478 | "slide_type": "slide" 479 | } 480 | }, 481 | "source": [ 482 | "## Arrays\n", 483 | "\n", 484 | "Arrays are created using the `[]` brackets (or the `Array` constructor.)\n", 485 | "\n", 486 | "Arrays support multiple types of indexing with normal indices and with range operator `:`." 487 | ] 488 | }, 489 | { 490 | "cell_type": "code", 491 | "execution_count": null, 492 | "metadata": { 493 | "slideshow": { 494 | "slide_type": "fragment" 495 | } 496 | }, 497 | "outputs": [], 498 | "source": [ 499 | "arr = [1,2,3 4]" 500 | ] 501 | }, 502 | { 503 | "cell_type": "code", 504 | "execution_count": null, 505 | "metadata": { 506 | "slideshow": { 507 | "slide_type": "fragment" 508 | } 509 | }, 510 | "outputs": [], 511 | "source": [ 512 | "arr[1] # indexing starts from 1" 513 | ] 514 | }, 515 | { 516 | "cell_type": "code", 517 | "execution_count": null, 518 | "metadata": { 519 | "slideshow": { 520 | "slide_type": "fragment" 521 | } 522 | }, 523 | "outputs": [], 524 | "source": [ 525 | "arr[1:3] # so-called slice syntax can be used to select parts of an array" 526 | ] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "execution_count": null, 531 | "metadata": { 532 | "slideshow": { 533 | "slide_type": "fragment" 534 | } 535 | }, 536 | "outputs": [], 537 | "source": [ 538 | "arr[end] # end keyword points to the end of the array" 539 | ] 540 | }, 541 | { 542 | "cell_type": "markdown", 543 | "metadata": { 544 | "slideshow": { 545 | "slide_type": "slide" 546 | } 547 | }, 548 | "source": [ 549 | "## Arrays\n", 550 | "Type can be specifically forced by writing them in front of the array brackets:" 551 | ] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "execution_count": null, 556 | "metadata": { 557 | "slideshow": { 558 | "slide_type": "fragment" 559 | } 560 | }, 561 | "outputs": [], 562 | "source": [ 563 | "arr = Float64[1,2,3,4]" 564 | ] 565 | }, 566 | { 567 | "cell_type": "markdown", 568 | "metadata": { 569 | "slideshow": { 570 | "slide_type": "slide" 571 | } 572 | }, 573 | "source": [ 574 | "## Array manipulation\n", 575 | "Arrays can be extended with several methods." 576 | ] 577 | }, 578 | { 579 | "cell_type": "code", 580 | "execution_count": null, 581 | "metadata": { 582 | "slideshow": { 583 | "slide_type": "fragment" 584 | } 585 | }, 586 | "outputs": [], 587 | "source": [ 588 | "arr = [1, 2]" 589 | ] 590 | }, 591 | { 592 | "cell_type": "code", 593 | "execution_count": null, 594 | "metadata": { 595 | "slideshow": { 596 | "slide_type": "fragment" 597 | } 598 | }, 599 | "outputs": [], 600 | "source": [ 601 | "push!(arr, 3) # Exclamation mark ! means that the function mutates its argument" 602 | ] 603 | }, 604 | { 605 | "cell_type": "code", 606 | "execution_count": null, 607 | "metadata": { 608 | "slideshow": { 609 | "slide_type": "fragment" 610 | } 611 | }, 612 | "outputs": [], 613 | "source": [ 614 | "insert!(arr, 1, 42) # insert places the given element to given location in the array" 615 | ] 616 | }, 617 | { 618 | "cell_type": "code", 619 | "execution_count": null, 620 | "metadata": { 621 | "slideshow": { 622 | "slide_type": "fragment" 623 | } 624 | }, 625 | "outputs": [], 626 | "source": [ 627 | "append!(arr, [100, 101, 102]) # append another array to the end" 628 | ] 629 | }, 630 | { 631 | "cell_type": "markdown", 632 | "metadata": { 633 | "slideshow": { 634 | "slide_type": "slide" 635 | } 636 | }, 637 | "source": [ 638 | "## 2-D Arrays\n", 639 | "2-dimensional arrays use space-separated values and semicolon-separated rows." 640 | ] 641 | }, 642 | { 643 | "cell_type": "code", 644 | "execution_count": 23, 645 | "metadata": { 646 | "slideshow": { 647 | "slide_type": "fragment" 648 | } 649 | }, 650 | "outputs": [ 651 | { 652 | "data": { 653 | "text/plain": [ 654 | "2×2 Array{Int64,2}:\n", 655 | " 1 2\n", 656 | " 3 4" 657 | ] 658 | }, 659 | "execution_count": 23, 660 | "metadata": {}, 661 | "output_type": "execute_result" 662 | } 663 | ], 664 | "source": [ 665 | "matrix = [1 2; 3 4]" 666 | ] 667 | }, 668 | { 669 | "cell_type": "markdown", 670 | "metadata": { 671 | "slideshow": { 672 | "slide_type": "slide" 673 | } 674 | }, 675 | "source": [ 676 | "## N-dimensional arrays\n", 677 | "For more dimensions than 2, one should initialize the arrays somehow else. \n", 678 | "\n", 679 | "Standard ways are:" 680 | ] 681 | }, 682 | { 683 | "cell_type": "code", 684 | "execution_count": null, 685 | "metadata": { 686 | "slideshow": { 687 | "slide_type": "fragment" 688 | } 689 | }, 690 | "outputs": [], 691 | "source": [ 692 | "A = zeros(3,3,3)" 693 | ] 694 | }, 695 | { 696 | "cell_type": "code", 697 | "execution_count": null, 698 | "metadata": { 699 | "slideshow": { 700 | "slide_type": "fragment" 701 | } 702 | }, 703 | "outputs": [], 704 | "source": [ 705 | "B = ones(4,5,6,7)" 706 | ] 707 | }, 708 | { 709 | "cell_type": "code", 710 | "execution_count": null, 711 | "metadata": { 712 | "slideshow": { 713 | "slide_type": "fragment" 714 | } 715 | }, 716 | "outputs": [], 717 | "source": [ 718 | "C = rand(2,3,4,5,6)" 719 | ] 720 | }, 721 | { 722 | "cell_type": "markdown", 723 | "metadata": { 724 | "slideshow": { 725 | "slide_type": "slide" 726 | } 727 | }, 728 | "source": [ 729 | "## Dictionaries\n", 730 | "If we have sets of data related to one another, we may choose to store that data in a dictionary. We can create a dictionary using the `Dict()` function, which we can initialize as an empty dictionary or one storing key, value pairs.\n", 731 | "\n", 732 | "Syntax:\n", 733 | "```julia\n", 734 | "Dict(key1 => value1, key2 => value2, ...)\n", 735 | "```" 736 | ] 737 | }, 738 | { 739 | "cell_type": "code", 740 | "execution_count": null, 741 | "metadata": { 742 | "slideshow": { 743 | "slide_type": "fragment" 744 | } 745 | }, 746 | "outputs": [], 747 | "source": [ 748 | "myphonebook = Dict(\"Jenny\" => \"867-5309\", \"Ghostbusters\" => \"555-2368\")" 749 | ] 750 | }, 751 | { 752 | "cell_type": "code", 753 | "execution_count": null, 754 | "metadata": { 755 | "slideshow": { 756 | "slide_type": "fragment" 757 | } 758 | }, 759 | "outputs": [], 760 | "source": [ 761 | "myphonebook[\"Jenny\"] # we can access the element by using the key" 762 | ] 763 | }, 764 | { 765 | "cell_type": "code", 766 | "execution_count": null, 767 | "metadata": { 768 | "slideshow": { 769 | "slide_type": "fragment" 770 | } 771 | }, 772 | "outputs": [], 773 | "source": [ 774 | "myphonebook[\"Kramer\"] = \"555-FILK\" # new elements can be easily added" 775 | ] 776 | }, 777 | { 778 | "cell_type": "markdown", 779 | "metadata": { 780 | "slideshow": { 781 | "slide_type": "slide" 782 | } 783 | }, 784 | "source": [ 785 | "## Tuples \n", 786 | "We can create a tuple by enclosing an ordered collection of elements in `( )`. Syntax is `(item1, item2,...)`.\n", 787 | "\n", 788 | "Julia does automatic packing and unpacking of tuples as `(a, b) = 1, 2`.\n", 789 | "\n", 790 | "Note that tuples are immutable!" 791 | ] 792 | }, 793 | { 794 | "cell_type": "code", 795 | "execution_count": null, 796 | "metadata": { 797 | "slideshow": { 798 | "slide_type": "fragment" 799 | } 800 | }, 801 | "outputs": [], 802 | "source": [ 803 | "myfavoriteanimals = (\"penguins\", \"cats\", \"sugargliders\")" 804 | ] 805 | }, 806 | { 807 | "cell_type": "code", 808 | "execution_count": null, 809 | "metadata": { 810 | "slideshow": { 811 | "slide_type": "fragment" 812 | } 813 | }, 814 | "outputs": [], 815 | "source": [ 816 | "myfavoriteanimals[1] # tuples can be indexed the same way as arrays" 817 | ] 818 | }, 819 | { 820 | "cell_type": "code", 821 | "execution_count": null, 822 | "metadata": { 823 | "slideshow": { 824 | "slide_type": "fragment" 825 | } 826 | }, 827 | "outputs": [], 828 | "source": [ 829 | "myfavoriteanimals[1] = \"otters\" #but not modified since they are immutable" 830 | ] 831 | }, 832 | { 833 | "cell_type": "markdown", 834 | "metadata": { 835 | "slideshow": { 836 | "slide_type": "skip" 837 | } 838 | }, 839 | "source": [ 840 | "## Advanced: Big numbers!\n", 841 | "Arbitrary precision arithmetics is also supported, see the [manual](https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/#Arbitrary-Precision-Arithmetic-1) for more." 842 | ] 843 | }, 844 | { 845 | "cell_type": "code", 846 | "execution_count": null, 847 | "metadata": { 848 | "slideshow": { 849 | "slide_type": "skip" 850 | } 851 | }, 852 | "outputs": [], 853 | "source": [ 854 | "BigFloat(2.0^66) / 3" 855 | ] 856 | }, 857 | { 858 | "cell_type": "markdown", 859 | "metadata": { 860 | "slideshow": { 861 | "slide_type": "skip" 862 | } 863 | }, 864 | "source": [ 865 | "## Advanced: Dynamic types\n", 866 | "When evaluating `1/3`, it equals `0.3333...` (which is what the user often meant).\n", 867 | "However, not always! Then the ``::`` operator can be attached to the expressions. It is read as *\"is instance of\"*." 868 | ] 869 | }, 870 | { 871 | "cell_type": "code", 872 | "execution_count": null, 873 | "metadata": { 874 | "slideshow": { 875 | "slide_type": "skip" 876 | } 877 | }, 878 | "outputs": [], 879 | "source": [ 880 | "a = 1\n", 881 | "b = 3\n", 882 | "c = (a + b)::Int\n", 883 | "typeof(c)" 884 | ] 885 | }, 886 | { 887 | "cell_type": "code", 888 | "execution_count": null, 889 | "metadata": { 890 | "slideshow": { 891 | "slide_type": "skip" 892 | } 893 | }, 894 | "outputs": [], 895 | "source": [] 896 | } 897 | ], 898 | "metadata": { 899 | "celltoolbar": "Slideshow", 900 | "kernelspec": { 901 | "display_name": "Julia 1.0.3", 902 | "language": "julia", 903 | "name": "julia-1.0" 904 | }, 905 | "language_info": { 906 | "file_extension": ".jl", 907 | "mimetype": "application/julia", 908 | "name": "julia", 909 | "version": "1.0.3" 910 | } 911 | }, 912 | "nbformat": 4, 913 | "nbformat_minor": 2 914 | } 915 | -------------------------------------------------------------------------------- /notebooks/02_control-flow.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Control flow" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "fragment" 19 | } 20 | }, 21 | "source": [ 22 | "## Topics\n", 23 | "- conditional statements\n", 24 | "- repeated evaluation\n", 25 | " - `while` and `for`\n", 26 | "- breaking and continuing \n", 27 | "\n", 28 | "See also the [documentation](https://docs.julialang.org/en/v1/manual/control-flow/\n", 29 | ")" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": { 35 | "slideshow": { 36 | "slide_type": "slide" 37 | } 38 | }, 39 | "source": [ 40 | "## Numeric Comparisons\n", 41 | "\n", 42 | "Standard comparison operations are defined for all the primitive numeric types:\n", 43 | "\n", 44 | "\n", 45 | "- `==`: equality \n", 46 | "- `!=`, `≠`: inequality \n", 47 | "- `<`: less than \n", 48 | "- `<=`, `≤`: less than or equal to \n", 49 | "- `>`: greater than \n", 50 | "- `>=`, `≥`: greater than or equal to" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": { 56 | "slideshow": { 57 | "slide_type": "fragment" 58 | } 59 | }, 60 | "source": [ 61 | "Conditions can be chained, i.e., `0 < x < 1`" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": { 67 | "slideshow": { 68 | "slide_type": "slide" 69 | } 70 | }, 71 | "source": [ 72 | "## Conditional statements\n", 73 | "\n", 74 | "The most common conditional statement is the `if` statement. Syntax is\n", 75 | "```julia\n", 76 | "if *condition*\n", 77 | " *option 1*\n", 78 | "elseif *condition 2*\n", 79 | " *option 2*\n", 80 | "else\n", 81 | " *option 3*\n", 82 | "end\n", 83 | "```" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": { 90 | "slideshow": { 91 | "slide_type": "fragment" 92 | } 93 | }, 94 | "outputs": [], 95 | "source": [ 96 | "variable = \n", 97 | "if variable > 5\n", 98 | " println(\"Wow! The variable is larger than 5\")\n", 99 | "elseif variable > 0\n", 100 | " println(\"Well, it is positive, at least\")\n", 101 | "else\n", 102 | " println(\"Phew, too small number!\")\n", 103 | "end" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": { 109 | "slideshow": { 110 | "slide_type": "fragment" 111 | } 112 | }, 113 | "source": [ 114 | "Julia is relying on the `end` keyword to close the statements!" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": { 120 | "slideshow": { 121 | "slide_type": "slide" 122 | } 123 | }, 124 | "source": [ 125 | "## And, or, ...\n", 126 | "- And is expressed as `&&`, i.e., `*condition1* && *condition2*`\n", 127 | "- Or is expressed as `||`, i.e., `*condition1* || *condition2*`\n" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 3, 133 | "metadata": { 134 | "slideshow": { 135 | "slide_type": "fragment" 136 | } 137 | }, 138 | "outputs": [ 139 | { 140 | "data": { 141 | "text/plain": [ 142 | "false" 143 | ] 144 | }, 145 | "execution_count": 3, 146 | "metadata": {}, 147 | "output_type": "execute_result" 148 | } 149 | ], 150 | "source": [ 151 | "false && true" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 2, 157 | "metadata": { 158 | "slideshow": { 159 | "slide_type": "fragment" 160 | } 161 | }, 162 | "outputs": [ 163 | { 164 | "data": { 165 | "text/plain": [ 166 | "true" 167 | ] 168 | }, 169 | "execution_count": 2, 170 | "metadata": {}, 171 | "output_type": "execute_result" 172 | } 173 | ], 174 | "source": [ 175 | "false || true" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "metadata": { 181 | "slideshow": { 182 | "slide_type": "slide" 183 | } 184 | }, 185 | "source": [ 186 | "## Ternary operator\n", 187 | "Even though the name for this operation is scary, it is actually very easy to understand and handy to use. Syntax is:\n", 188 | "```julia\n", 189 | "*condition* ? *do 1* : *do 2*\n", 190 | "```\n", 191 | "which is equal to writing\n", 192 | "```julia\n", 193 | "if *condition*\n", 194 | " *do 1*\n", 195 | "else\n", 196 | " *do 2*\n", 197 | "end\n", 198 | "```" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": null, 204 | "metadata": { 205 | "slideshow": { 206 | "slide_type": "fragment" 207 | } 208 | }, 209 | "outputs": [], 210 | "source": [ 211 | "# What does the followning code do? Try it out by giving values to `x` and `y`\n", 212 | "x = \n", 213 | "y = \n", 214 | "(x > y ) ? x : y" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": { 220 | "slideshow": { 221 | "slide_type": "slide" 222 | } 223 | }, 224 | "source": [ 225 | "## While statement\n", 226 | "Syntax is \n", 227 | "```julia\n", 228 | "while *condition*\n", 229 | " *loop body*\n", 230 | "end\n", 231 | "```" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": null, 237 | "metadata": { 238 | "slideshow": { 239 | "slide_type": "fragment" 240 | } 241 | }, 242 | "outputs": [], 243 | "source": [ 244 | "n = 0\n", 245 | "while n < 10\n", 246 | " n += 1\n", 247 | " println(n)\n", 248 | "end" 249 | ] 250 | }, 251 | { 252 | "cell_type": "markdown", 253 | "metadata": { 254 | "slideshow": { 255 | "slide_type": "slide" 256 | } 257 | }, 258 | "source": [ 259 | "## For loops\n", 260 | "The syntax is\n", 261 | "```julia\n", 262 | "for *var* in *loop iterable*\n", 263 | " *loop body*\n", 264 | "end\n", 265 | "```" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": null, 271 | "metadata": { 272 | "slideshow": { 273 | "slide_type": "fragment" 274 | } 275 | }, 276 | "outputs": [], 277 | "source": [ 278 | "for n in 1:10\n", 279 | " println(n)\n", 280 | "end" 281 | ] 282 | }, 283 | { 284 | "cell_type": "markdown", 285 | "metadata": { 286 | "slideshow": { 287 | "slide_type": "slide" 288 | } 289 | }, 290 | "source": [ 291 | "## For loops for iteration\n", 292 | "For loops can also be used to iterate over containers" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 1, 298 | "metadata": { 299 | "slideshow": { 300 | "slide_type": "fragment" 301 | } 302 | }, 303 | "outputs": [ 304 | { 305 | "name": "stdout", 306 | "output_type": "stream", 307 | "text": [ 308 | "1\n", 309 | "4\n", 310 | "0\n" 311 | ] 312 | } 313 | ], 314 | "source": [ 315 | "for i in [1,4,0]\n", 316 | " println(i)\n", 317 | "end" 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": 3, 323 | "metadata": { 324 | "slideshow": { 325 | "slide_type": "fragment" 326 | } 327 | }, 328 | "outputs": [ 329 | { 330 | "name": "stdout", 331 | "output_type": "stream", 332 | "text": [ 333 | "foo\n", 334 | "bar\n", 335 | "baz\n" 336 | ] 337 | } 338 | ], 339 | "source": [ 340 | "for s ∈ [\"foo\",\"bar\",\"baz\"]\n", 341 | " println(s)\n", 342 | "end" 343 | ] 344 | }, 345 | { 346 | "cell_type": "markdown", 347 | "metadata": { 348 | "slideshow": { 349 | "slide_type": "slide" 350 | } 351 | }, 352 | "source": [ 353 | "## Enumerate: A life saver\n", 354 | "Iterate over an array with index AND value. \n", 355 | "\n", 356 | "Syntax is\n", 357 | "```julia\n", 358 | "for (index, value) in enumerate(arr)\n", 359 | " println((index,value))\n", 360 | "end\n", 361 | "```" 362 | ] 363 | }, 364 | { 365 | "cell_type": "markdown", 366 | "metadata": { 367 | "slideshow": { 368 | "slide_type": "slide" 369 | } 370 | }, 371 | "source": [ 372 | "## Breaking and continuing\n", 373 | "Sometimes you need to terminate a `while` or `for` evaluation before the end. This can be accomplished with the `break` keyword\n" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": null, 379 | "metadata": { 380 | "slideshow": { 381 | "slide_type": "fragment" 382 | } 383 | }, 384 | "outputs": [], 385 | "source": [ 386 | "i = 1;\n", 387 | "while true\n", 388 | " println(i)\n", 389 | " if i >= 5\n", 390 | " break\n", 391 | " end\n", 392 | " i += 1\n", 393 | "end" 394 | ] 395 | }, 396 | { 397 | "cell_type": "code", 398 | "execution_count": null, 399 | "metadata": { 400 | "slideshow": { 401 | "slide_type": "fragment" 402 | } 403 | }, 404 | "outputs": [], 405 | "source": [ 406 | "for i = 1:1000\n", 407 | " println(i)\n", 408 | " if i >= 5\n", 409 | " break\n", 410 | " end\n", 411 | "end" 412 | ] 413 | }, 414 | { 415 | "cell_type": "markdown", 416 | "metadata": { 417 | "slideshow": { 418 | "slide_type": "slide" 419 | } 420 | }, 421 | "source": [ 422 | "## Breaking and continuing\n", 423 | "In other circumstances, it is handy to be able to stop an iteration and move on to the next one immediately. The `continue` keyword accomplishes this.\n" 424 | ] 425 | }, 426 | { 427 | "cell_type": "code", 428 | "execution_count": 3, 429 | "metadata": { 430 | "slideshow": { 431 | "slide_type": "fragment" 432 | } 433 | }, 434 | "outputs": [ 435 | { 436 | "name": "stdout", 437 | "output_type": "stream", 438 | "text": [ 439 | "3\n", 440 | "6\n", 441 | "9\n" 442 | ] 443 | } 444 | ], 445 | "source": [ 446 | "for i = 1:10\n", 447 | " if i % 3 != 0\n", 448 | " continue\n", 449 | " end\n", 450 | " println(i)\n", 451 | "end" 452 | ] 453 | }, 454 | { 455 | "cell_type": "markdown", 456 | "metadata": { 457 | "slideshow": { 458 | "slide_type": "slide" 459 | } 460 | }, 461 | "source": [ 462 | "## Nested loops\n", 463 | "Multiple nested loops can be combined into a single outer loop. " 464 | ] 465 | }, 466 | { 467 | "cell_type": "code", 468 | "execution_count": null, 469 | "metadata": { 470 | "slideshow": { 471 | "slide_type": "fragment" 472 | } 473 | }, 474 | "outputs": [], 475 | "source": [ 476 | "for i = 1:2\n", 477 | " for j = 3:3\n", 478 | " println((i,j))\n", 479 | " end\n", 480 | "end" 481 | ] 482 | }, 483 | { 484 | "cell_type": "markdown", 485 | "metadata": { 486 | "slideshow": { 487 | "slide_type": "fragment" 488 | } 489 | }, 490 | "source": [ 491 | "Translates into:" 492 | ] 493 | }, 494 | { 495 | "cell_type": "code", 496 | "execution_count": null, 497 | "metadata": { 498 | "slideshow": { 499 | "slide_type": "fragment" 500 | } 501 | }, 502 | "outputs": [], 503 | "source": [ 504 | "for i = 1:2, j = 3:4\n", 505 | " println((i, j))\n", 506 | "end" 507 | ] 508 | }, 509 | { 510 | "cell_type": "markdown", 511 | "metadata": { 512 | "slideshow": { 513 | "slide_type": "fragment" 514 | } 515 | }, 516 | "source": [ 517 | "A `break` statement inside such a loop exits the entire nest of loops, not just the inner one.\n" 518 | ] 519 | }, 520 | { 521 | "cell_type": "markdown", 522 | "metadata": { 523 | "slideshow": { 524 | "slide_type": "slide" 525 | } 526 | }, 527 | "source": [ 528 | "## List comprehension\n", 529 | "Comprehensions provide a general and powerful way to construct arrays. \n", 530 | "\n", 531 | "Comprehension syntax is similar to set construction notation in mathematics\n", 532 | "```julia\n", 533 | "A = [ F(x,y,...) for x=rx, y=ry, ... ]\n", 534 | "```" 535 | ] 536 | }, 537 | { 538 | "cell_type": "code", 539 | "execution_count": 6, 540 | "metadata": { 541 | "slideshow": { 542 | "slide_type": "fragment" 543 | } 544 | }, 545 | "outputs": [ 546 | { 547 | "data": { 548 | "text/plain": [ 549 | "3-element Array{Tuple{Int64,Int64},1}:\n", 550 | " (1, 1)\n", 551 | " (2, 1)\n", 552 | " (2, 2)" 553 | ] 554 | }, 555 | "execution_count": 6, 556 | "metadata": {}, 557 | "output_type": "execute_result" 558 | } 559 | ], 560 | "source": [ 561 | "[(i,j) for i=1:2 for j=1:i]" 562 | ] 563 | }, 564 | { 565 | "cell_type": "markdown", 566 | "metadata": { 567 | "slideshow": { 568 | "slide_type": "slide" 569 | } 570 | }, 571 | "source": [ 572 | "## Advanced: Tasks (aka Coroutines)\n", 573 | "Tasks are a control flow feature that allows computations to be suspended and resumed in a flexible manner. More information can be found from the [documentation](https://docs.julialang.org/en/v1/manual/control-flow/#man-tasks-1)" 574 | ] 575 | }, 576 | { 577 | "cell_type": "code", 578 | "execution_count": 4, 579 | "metadata": { 580 | "slideshow": { 581 | "slide_type": "fragment" 582 | } 583 | }, 584 | "outputs": [], 585 | "source": [ 586 | "function producer(c::Channel)\n", 587 | " put!(c, \"start\")\n", 588 | " for n=1:4\n", 589 | " put!(c, 2n)\n", 590 | " end\n", 591 | " put!(c, \"stop\")\n", 592 | "end;\n", 593 | "\n", 594 | "chnl = Channel(producer);" 595 | ] 596 | }, 597 | { 598 | "cell_type": "code", 599 | "execution_count": null, 600 | "metadata": { 601 | "slideshow": { 602 | "slide_type": "fragment" 603 | } 604 | }, 605 | "outputs": [], 606 | "source": [ 607 | "take!(chnl) # try executing me repeatedly" 608 | ] 609 | }, 610 | { 611 | "cell_type": "code", 612 | "execution_count": null, 613 | "metadata": {}, 614 | "outputs": [], 615 | "source": [] 616 | } 617 | ], 618 | "metadata": { 619 | "celltoolbar": "Slideshow", 620 | "kernelspec": { 621 | "display_name": "Julia 1.0.3", 622 | "language": "julia", 623 | "name": "julia-1.0" 624 | }, 625 | "language_info": { 626 | "file_extension": ".jl", 627 | "mimetype": "application/julia", 628 | "name": "julia", 629 | "version": "1.0.3" 630 | } 631 | }, 632 | "nbformat": 4, 633 | "nbformat_minor": 2 634 | } 635 | -------------------------------------------------------------------------------- /notebooks/03_functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Functions" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "fragment" 19 | } 20 | }, 21 | "source": [ 22 | "## Topics\n", 23 | "- How to declare a function\n", 24 | "- Duck-typing in Julia\n", 25 | "- Mutating vs. non-mutating functions\n", 26 | "- Some higher-order functions" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "slideshow": { 33 | "slide_type": "slide" 34 | } 35 | }, 36 | "source": [ 37 | "## Functions in a functional language\n", 38 | "Functions are the building blocks of Julia code, acting as the subroutines, procedures, blocks, and similar structural concepts found in other programming languages.\n", 39 | "\n", 40 | "- A function's job is to take a tuple of values as an argument list and return a value. \n", 41 | "- If the arguments contain mutable values like arrays, the array can be modified inside the function. \n", 42 | " - By convention, an exclamation mark (!) at the end of a function's name indicates that the function may modify its arguments." 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": { 48 | "slideshow": { 49 | "slide_type": "slide" 50 | } 51 | }, 52 | "source": [ 53 | "## How to declare a function\n", 54 | "\n", 55 | "Julia gives us a few different ways to write a function. The first (and most standard) requires `function` and `end` keywords." 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": null, 61 | "metadata": { 62 | "slideshow": { 63 | "slide_type": "fragment" 64 | } 65 | }, 66 | "outputs": [], 67 | "source": [ 68 | "function sayhi(name)\n", 69 | " println(\"Hi $name, nice to meet you!\")\n", 70 | "end\n", 71 | "\n", 72 | "sayhi(\"R2D2\")" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": { 79 | "slideshow": { 80 | "slide_type": "fragment" 81 | } 82 | }, 83 | "outputs": [], 84 | "source": [ 85 | "function f(x)\n", 86 | " return x^2\n", 87 | "end\n", 88 | "\n", 89 | "f(42)" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": { 95 | "slideshow": { 96 | "slide_type": "slide" 97 | } 98 | }, 99 | "source": [ 100 | "## Single line function definitions\n", 101 | "Alternatively, we could have spared a few lines of code and written:" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": { 108 | "slideshow": { 109 | "slide_type": "fragment" 110 | } 111 | }, 112 | "outputs": [], 113 | "source": [ 114 | "sayhi2(name) = println(\"Hi $name, nice to meet you!\")" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": { 121 | "slideshow": { 122 | "slide_type": "fragment" 123 | } 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "f2(x) = x^2" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": { 133 | "slideshow": { 134 | "slide_type": "slide" 135 | } 136 | }, 137 | "source": [ 138 | "## Anonymous functions\n", 139 | "Or we could have declared them as \"anonymous\" functions as" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": { 146 | "slideshow": { 147 | "slide_type": "fragment" 148 | } 149 | }, 150 | "outputs": [], 151 | "source": [ 152 | "sayhi3 = name -> println(\"Hi $name, nice to meet you!\")" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": { 159 | "slideshow": { 160 | "slide_type": "fragment" 161 | } 162 | }, 163 | "outputs": [], 164 | "source": [ 165 | "f3 = x -> x^2" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": { 171 | "slideshow": { 172 | "slide_type": "slide" 173 | } 174 | }, 175 | "source": [ 176 | "## Duck-typing in Julia\n", 177 | "*\"If it quacks like a duck, it's a duck.\"*\n", 178 | "\n", 179 | "Julia functions will just work on whatever input makes sense. For example, `sayhi` works also with the name written as an integer:" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 2, 185 | "metadata": { 186 | "slideshow": { 187 | "slide_type": "fragment" 188 | } 189 | }, 190 | "outputs": [ 191 | { 192 | "name": "stdout", 193 | "output_type": "stream", 194 | "text": [ 195 | "Hi 55595472, nice to meet you!\n" 196 | ] 197 | } 198 | ], 199 | "source": [ 200 | "sayhi(55595472)" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "metadata": { 206 | "slideshow": { 207 | "slide_type": "fragment" 208 | } 209 | }, 210 | "source": [ 211 | "And `f` will work on a matrix" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": null, 217 | "metadata": { 218 | "slideshow": { 219 | "slide_type": "fragment" 220 | } 221 | }, 222 | "outputs": [], 223 | "source": [ 224 | "A = rand(3,3)\n", 225 | "A" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": null, 231 | "metadata": { 232 | "slideshow": { 233 | "slide_type": "fragment" 234 | } 235 | }, 236 | "outputs": [], 237 | "source": [ 238 | "f(A)" 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": { 244 | "slideshow": { 245 | "slide_type": "slide" 246 | } 247 | }, 248 | "source": [ 249 | "## Mutating vs. non-mutating functions\n", 250 | "By convention, functions followed by `!` alter their contents and functions lacking `!` do not.\n", 251 | "\n", 252 | "For example, let's look at the difference between `sort` and `sort!`." 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": null, 258 | "metadata": { 259 | "slideshow": { 260 | "slide_type": "fragment" 261 | } 262 | }, 263 | "outputs": [], 264 | "source": [ 265 | "v = [3,5,2]" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 4, 271 | "metadata": { 272 | "slideshow": { 273 | "slide_type": "fragment" 274 | } 275 | }, 276 | "outputs": [ 277 | { 278 | "data": { 279 | "text/plain": [ 280 | "3-element Array{Int64,1}:\n", 281 | " 2\n", 282 | " 3\n", 283 | " 5" 284 | ] 285 | }, 286 | "execution_count": 4, 287 | "metadata": {}, 288 | "output_type": "execute_result" 289 | } 290 | ], 291 | "source": [ 292 | "sort(v)" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 5, 298 | "metadata": { 299 | "slideshow": { 300 | "slide_type": "fragment" 301 | } 302 | }, 303 | "outputs": [ 304 | { 305 | "data": { 306 | "text/plain": [ 307 | "3-element Array{Int64,1}:\n", 308 | " 3\n", 309 | " 5\n", 310 | " 2" 311 | ] 312 | }, 313 | "execution_count": 5, 314 | "metadata": {}, 315 | "output_type": "execute_result" 316 | } 317 | ], 318 | "source": [ 319 | "v" 320 | ] 321 | }, 322 | { 323 | "cell_type": "markdown", 324 | "metadata": { 325 | "slideshow": { 326 | "slide_type": "slide" 327 | } 328 | }, 329 | "source": [ 330 | "`sort(v)` returns a sorted array that contains the same elements as `v`, but `v` is left unchanged.\n", 331 | "\n", 332 | "On the other hand, when we run `sort!(v)` the content of `v` is really modified." 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": null, 338 | "metadata": { 339 | "slideshow": { 340 | "slide_type": "fragment" 341 | } 342 | }, 343 | "outputs": [], 344 | "source": [ 345 | "sort!(v)" 346 | ] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "execution_count": 9, 351 | "metadata": { 352 | "slideshow": { 353 | "slide_type": "fragment" 354 | } 355 | }, 356 | "outputs": [ 357 | { 358 | "data": { 359 | "text/plain": [ 360 | "3-element Array{Int64,1}:\n", 361 | " 2\n", 362 | " 3\n", 363 | " 5" 364 | ] 365 | }, 366 | "execution_count": 9, 367 | "metadata": {}, 368 | "output_type": "execute_result" 369 | } 370 | ], 371 | "source": [ 372 | "v" 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": { 378 | "slideshow": { 379 | "slide_type": "slide" 380 | } 381 | }, 382 | "source": [ 383 | "## Some higher-order functions: `map`\n", 384 | "\n", 385 | "`map` is a \"higher-order\" function in Julia that takes a *function* as one of its input arguments. `map` then applies that function to every element of the data structure you pass. \n", 386 | "\n", 387 | "For example\n", 388 | "```julia\n", 389 | "map(f, [1,2,3])\n", 390 | "```\n", 391 | "will correspond to\n", 392 | "```julia\n", 393 | "[f(1), f(2), f(3)]\n", 394 | "```" 395 | ] 396 | }, 397 | { 398 | "cell_type": "markdown", 399 | "metadata": { 400 | "slideshow": { 401 | "slide_type": "slide" 402 | } 403 | }, 404 | "source": [ 405 | "## Some higher-order functions: `broadcast`\n", 406 | "`broadcast` is another higher-order function like `map`. `broadcast` is actually a generalization, so it can do what `map` but also more!\n", 407 | "\n", 408 | "Syntax is the same\n", 409 | "```julia\n", 410 | "broadcast(f, [1,2,3])\n", 411 | "```\n", 412 | "\n", 413 | "And so we have again applied f (squared) to all elements of `[1,2,3]`. " 414 | ] 415 | }, 416 | { 417 | "cell_type": "markdown", 418 | "metadata": { 419 | "slideshow": { 420 | "slide_type": "slide" 421 | } 422 | }, 423 | "source": [ 424 | "## Broadcasting (or vectorizing)\n", 425 | "Some syntactic sugar for calling `broadcast` is to place `.` between the name of the function you want to broadcast and its input arguments. \n", 426 | " \n", 427 | "For example\n", 428 | "```julia\n", 429 | "broadcast(f, [1,2,3])\n", 430 | "```\n", 431 | "is the same as\n", 432 | "```julia\n", 433 | "f.([1,2,3])\n", 434 | "```\n", 435 | "\n", 436 | "Note that this is not the same as `f([1,2,3])` because we can not square a vector!" 437 | ] 438 | }, 439 | { 440 | "cell_type": "markdown", 441 | "metadata": { 442 | "slideshow": { 443 | "slide_type": "slide" 444 | } 445 | }, 446 | "source": [ 447 | "Let's try broadcasting for a matrix `A`" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 10, 453 | "metadata": { 454 | "slideshow": { 455 | "slide_type": "fragment" 456 | } 457 | }, 458 | "outputs": [ 459 | { 460 | "data": { 461 | "text/plain": [ 462 | "3×3 Array{Int64,2}:\n", 463 | " 1 2 3\n", 464 | " 4 5 6\n", 465 | " 7 8 9" 466 | ] 467 | }, 468 | "execution_count": 10, 469 | "metadata": {}, 470 | "output_type": "execute_result" 471 | } 472 | ], 473 | "source": [ 474 | "A = [i + 3j for j in 0:2, i in 1:3]" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "execution_count": 11, 480 | "metadata": { 481 | "slideshow": { 482 | "slide_type": "fragment" 483 | } 484 | }, 485 | "outputs": [ 486 | { 487 | "data": { 488 | "text/plain": [ 489 | "3×3 Array{Int64,2}:\n", 490 | " 30 36 42\n", 491 | " 66 81 96\n", 492 | " 102 126 150" 493 | ] 494 | }, 495 | "execution_count": 11, 496 | "metadata": {}, 497 | "output_type": "execute_result" 498 | } 499 | ], 500 | "source": [ 501 | "f(A)" 502 | ] 503 | }, 504 | { 505 | "cell_type": "code", 506 | "execution_count": 12, 507 | "metadata": { 508 | "slideshow": { 509 | "slide_type": "fragment" 510 | } 511 | }, 512 | "outputs": [ 513 | { 514 | "data": { 515 | "text/plain": [ 516 | "3×3 Array{Int64,2}:\n", 517 | " 1 4 9\n", 518 | " 16 25 36\n", 519 | " 49 64 81" 520 | ] 521 | }, 522 | "execution_count": 12, 523 | "metadata": {}, 524 | "output_type": "execute_result" 525 | } 526 | ], 527 | "source": [ 528 | "B = f.(A)" 529 | ] 530 | }, 531 | { 532 | "cell_type": "markdown", 533 | "metadata": { 534 | "slideshow": { 535 | "slide_type": "slide" 536 | } 537 | }, 538 | "source": [ 539 | "## Dot syntax for vectorization\n", 540 | "The dot syntax allows to write complex compound **elementwise** expressions in a way that looks natural/closer to mathematical notation. \n", 541 | "\n", 542 | "For example:" 543 | ] 544 | }, 545 | { 546 | "cell_type": "code", 547 | "execution_count": null, 548 | "metadata": { 549 | "slideshow": { 550 | "slide_type": "fragment" 551 | } 552 | }, 553 | "outputs": [], 554 | "source": [ 555 | "A + 2 .* f.(A) ./ A" 556 | ] 557 | }, 558 | { 559 | "cell_type": "markdown", 560 | "metadata": { 561 | "slideshow": { 562 | "slide_type": "fragment" 563 | } 564 | }, 565 | "source": [ 566 | "Instead of the more nasty looking version with `broadcast` as" 567 | ] 568 | }, 569 | { 570 | "cell_type": "code", 571 | "execution_count": null, 572 | "metadata": { 573 | "slideshow": { 574 | "slide_type": "fragment" 575 | } 576 | }, 577 | "outputs": [], 578 | "source": [ 579 | "broadcast(x-> x + 2 * f(x) / x, A) " 580 | ] 581 | }, 582 | { 583 | "cell_type": "markdown", 584 | "metadata": { 585 | "slideshow": { 586 | "slide_type": "skip" 587 | } 588 | }, 589 | "source": [ 590 | "### Advanced: SIMD vectorization\n", 591 | "Vectorization is discussed more in the bonus notebook about SIMD vectorization.\n", 592 | "\n", 593 | "In short, the topic is quite technical but you should rest assured that the dot syntax actually works quite well to make your code easy to read **and** fast to run." 594 | ] 595 | }, 596 | { 597 | "cell_type": "markdown", 598 | "metadata": { 599 | "slideshow": { 600 | "slide_type": "slide" 601 | } 602 | }, 603 | "source": [ 604 | "## Macros\n", 605 | "Finally, let's touch the metaprogramming capabilities of Julia. \n", 606 | "\n", 607 | "Since metaprogramming is a whole another topic (see bonus notebook) we will only cover the very basics of something you might encounter when dealing with Julia code: macros." 608 | ] 609 | }, 610 | { 611 | "cell_type": "markdown", 612 | "metadata": { 613 | "slideshow": { 614 | "slide_type": "slide" 615 | } 616 | }, 617 | "source": [ 618 | "Macros provide a method to include generated code in the final body of a program. A macro maps a tuple of arguments to a returned **expression**, and the resulting expression is compiled directly.\n", 619 | "\n", 620 | "This means that macros can change how functions work, hence the *meta* in metaprogramming." 621 | ] 622 | }, 623 | { 624 | "cell_type": "code", 625 | "execution_count": 7, 626 | "metadata": { 627 | "slideshow": { 628 | "slide_type": "fragment" 629 | } 630 | }, 631 | "outputs": [ 632 | { 633 | "data": { 634 | "text/plain": [ 635 | "@sayhello (macro with 1 method)" 636 | ] 637 | }, 638 | "execution_count": 7, 639 | "metadata": {}, 640 | "output_type": "execute_result" 641 | } 642 | ], 643 | "source": [ 644 | "macro sayhello()\n", 645 | " return :( println(\"Hello, world!\") )\n", 646 | "end" 647 | ] 648 | }, 649 | { 650 | "cell_type": "markdown", 651 | "metadata": { 652 | "slideshow": { 653 | "slide_type": "slide" 654 | } 655 | }, 656 | "source": [ 657 | "## Macro invocation\n", 658 | "Macros are invoked with the following general syntax:\n", 659 | "```julia\n", 660 | "@name expr1 expr2 ...\n", 661 | "@name(expr1, expr2, ...)\n", 662 | "```" 663 | ] 664 | }, 665 | { 666 | "cell_type": "code", 667 | "execution_count": 8, 668 | "metadata": { 669 | "slideshow": { 670 | "slide_type": "fragment" 671 | } 672 | }, 673 | "outputs": [ 674 | { 675 | "name": "stdout", 676 | "output_type": "stream", 677 | "text": [ 678 | "Hello, world!\n" 679 | ] 680 | } 681 | ], 682 | "source": [ 683 | "@sayhello" 684 | ] 685 | }, 686 | { 687 | "cell_type": "markdown", 688 | "metadata": { 689 | "slideshow": { 690 | "slide_type": "slide" 691 | } 692 | }, 693 | "source": [ 694 | "## Hold up: why macros?\n", 695 | "So, why do macros exist?\n", 696 | "\n", 697 | "Macros are necessary because they execute when code is parsed, therefore, macros allow the programmer to generate and include fragments of customized code before the full program is run. To illustrate the usefulness, consider the following example:" 698 | ] 699 | }, 700 | { 701 | "cell_type": "code", 702 | "execution_count": 6, 703 | "metadata": { 704 | "slideshow": { 705 | "slide_type": "fragment" 706 | } 707 | }, 708 | "outputs": [ 709 | { 710 | "name": "stdout", 711 | "output_type": "stream", 712 | "text": [ 713 | " 0.077456 seconds (129.70 k allocations: 14.319 MiB, 7.03% gc time)\n" 714 | ] 715 | }, 716 | { 717 | "data": { 718 | "text/plain": [ 719 | "1000×1000 Array{Float64,2}:\n", 720 | " 0.133788 0.289875 0.301358 … 0.722712 0.132119 0.0711878 \n", 721 | " 0.232199 0.708361 0.757317 0.382954 0.90457 0.541329 \n", 722 | " 0.841865 0.25019 0.863874 0.791287 0.838446 0.688754 \n", 723 | " 0.905365 0.699254 0.791713 0.168175 0.700649 0.00768163\n", 724 | " 0.908601 0.231062 0.805617 0.274653 0.237761 0.0545861 \n", 725 | " 0.97303 0.350525 0.859059 … 0.122305 0.480321 0.683983 \n", 726 | " 0.485601 0.897776 0.79468 0.610637 0.542205 0.0194064 \n", 727 | " 0.586251 0.308654 0.42805 0.674692 0.713126 0.920915 \n", 728 | " 0.858069 0.38761 0.466336 0.115616 0.452334 0.304697 \n", 729 | " 0.587535 0.220633 0.023312 0.282934 0.843557 0.4574 \n", 730 | " 0.150961 0.169397 0.608804 … 0.343032 0.097016 0.852851 \n", 731 | " 0.320002 0.302165 0.775676 0.0170152 0.495148 0.293688 \n", 732 | " 0.141472 0.400419 0.492219 0.62024 0.493211 0.893538 \n", 733 | " ⋮ ⋱ \n", 734 | " 0.842716 0.0553613 0.433981 0.867206 0.479867 0.0407928 \n", 735 | " 0.516374 0.143694 0.276819 0.810143 0.0304361 0.466436 \n", 736 | " 0.696987 0.930386 0.143151 … 0.984575 0.000769774 0.684915 \n", 737 | " 0.409961 0.212214 0.20033 0.407988 0.315202 0.372112 \n", 738 | " 0.861621 0.504287 0.969606 0.675994 0.525149 0.450284 \n", 739 | " 0.516016 0.032955 0.855961 0.243357 0.651287 0.265455 \n", 740 | " 0.438274 0.783291 0.890055 0.668783 0.433839 0.485094 \n", 741 | " 0.81713 0.665118 0.806534 … 0.964697 0.340583 0.196312 \n", 742 | " 0.681564 0.0719173 0.833805 0.899317 0.0135019 0.571898 \n", 743 | " 0.978836 0.948982 0.806822 0.0928541 0.053412 0.664294 \n", 744 | " 0.434929 0.127112 0.861749 0.262989 0.592082 0.859197 \n", 745 | " 0.69802 0.963343 0.925205 0.0603075 0.489748 0.67149 " 746 | ] 747 | }, 748 | "execution_count": 6, 749 | "metadata": {}, 750 | "output_type": "execute_result" 751 | } 752 | ], 753 | "source": [ 754 | "@time A = rand(10^3, 10^3)" 755 | ] 756 | }, 757 | { 758 | "cell_type": "code", 759 | "execution_count": null, 760 | "metadata": {}, 761 | "outputs": [], 762 | "source": [] 763 | } 764 | ], 765 | "metadata": { 766 | "celltoolbar": "Slideshow", 767 | "kernelspec": { 768 | "display_name": "Julia 1.0.3", 769 | "language": "julia", 770 | "name": "julia-1.0" 771 | }, 772 | "language_info": { 773 | "file_extension": ".jl", 774 | "mimetype": "application/julia", 775 | "name": "julia", 776 | "version": "1.0.3" 777 | } 778 | }, 779 | "nbformat": 4, 780 | "nbformat_minor": 2 781 | } 782 | -------------------------------------------------------------------------------- /notebooks/04_IO.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# I/O" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "fragment" 19 | } 20 | }, 21 | "source": [ 22 | "## Topics\n", 23 | "- Strings and characters\n", 24 | "- text manipulation\n", 25 | "- working with text files" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": { 31 | "slideshow": { 32 | "slide_type": "slide" 33 | } 34 | }, 35 | "source": [ 36 | "## Strings and characters\n", 37 | "A string is a sequence of one or more characters, usually enclosed in double quotes:\n", 38 | "```julia\n", 39 | "\"this is a string\"\n", 40 | "```\n", 41 | "\n", 42 | "In some cases it might also be useful to use an equivalent triple double quotes\n", 43 | "```julia\n", 44 | "\"\"\"this is also a string, but it supports double quotes \"just\" like this.\"\"\"\"\n", 45 | "```\n", 46 | "\n", 47 | "Characters are enclosed in single quotes, i.e., `'a'`. Be aware that this is not the same as string of length 1!" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": { 53 | "slideshow": { 54 | "slide_type": "slide" 55 | } 56 | }, 57 | "source": [ 58 | "## Indexing strings\n", 59 | "If you want to extract characters from strings, you index into it" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 14, 65 | "metadata": { 66 | "slideshow": { 67 | "slide_type": "fragment" 68 | } 69 | }, 70 | "outputs": [ 71 | { 72 | "data": { 73 | "text/plain": [ 74 | "'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)" 75 | ] 76 | }, 77 | "execution_count": 14, 78 | "metadata": {}, 79 | "output_type": "execute_result" 80 | } 81 | ], 82 | "source": [ 83 | "s = \"abcdefghijklmnopqrstuvwxyz\"\n", 84 | "s[1]" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": { 90 | "slideshow": { 91 | "slide_type": "fragment" 92 | } 93 | }, 94 | "source": [ 95 | "You can also extract a substring using range indexing" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 15, 101 | "metadata": { 102 | "slideshow": { 103 | "slide_type": "fragment" 104 | } 105 | }, 106 | "outputs": [ 107 | { 108 | "data": { 109 | "text/plain": [ 110 | "\"abc\"" 111 | ] 112 | }, 113 | "execution_count": 15, 114 | "metadata": {}, 115 | "output_type": "execute_result" 116 | } 117 | ], 118 | "source": [ 119 | "s[1:3]" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": { 125 | "slideshow": { 126 | "slide_type": "fragment" 127 | } 128 | }, 129 | "source": [ 130 | "Note how `s[1]` and `s[1:1]` do not give the same result: first gives a character, the other a (sub)string!" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": { 136 | "slideshow": { 137 | "slide_type": "slide" 138 | } 139 | }, 140 | "source": [ 141 | "## String interpolation \n", 142 | "Often you want to use the results of Julia expressions inside strings. This can be done with the string interpolation machinery. Syntax is to use `$(x)` for the expression `x`. \n", 143 | "\n", 144 | "Note that for a simple variable it is enough to just use `$var` without the parentheses.\n", 145 | "\n", 146 | "Inverse conversion, i.e., from other types into a string type, is easily done using the `string()` function." 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 2, 152 | "metadata": { 153 | "slideshow": { 154 | "slide_type": "fragment" 155 | } 156 | }, 157 | "outputs": [ 158 | { 159 | "data": { 160 | "text/plain": [ 161 | "\"The value of x is 42\"" 162 | ] 163 | }, 164 | "execution_count": 2, 165 | "metadata": {}, 166 | "output_type": "execute_result" 167 | } 168 | ], 169 | "source": [ 170 | "x = 42\n", 171 | "\"The value of x is $x\"" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": 3, 177 | "metadata": { 178 | "slideshow": { 179 | "slide_type": "fragment" 180 | } 181 | }, 182 | "outputs": [ 183 | { 184 | "data": { 185 | "text/plain": [ 186 | "\"The value of 2 + 2 is 4\"" 187 | ] 188 | }, 189 | "execution_count": 3, 190 | "metadata": {}, 191 | "output_type": "execute_result" 192 | } 193 | ], 194 | "source": [ 195 | "\"The value of 2 + 2 is $(2+2)\"" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": 6, 201 | "metadata": { 202 | "slideshow": { 203 | "slide_type": "fragment" 204 | } 205 | }, 206 | "outputs": [ 207 | { 208 | "data": { 209 | "text/plain": [ 210 | "\"42\"" 211 | ] 212 | }, 213 | "execution_count": 6, 214 | "metadata": {}, 215 | "output_type": "execute_result" 216 | } 217 | ], 218 | "source": [ 219 | "string(x)" 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "metadata": { 225 | "slideshow": { 226 | "slide_type": "slide" 227 | } 228 | }, 229 | "source": [ 230 | "## Splitting and joining strings\n", 231 | "You can stick together (a process often called *concatenation*) using multiply (`*`) operator" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 5, 237 | "metadata": { 238 | "slideshow": { 239 | "slide_type": "fragment" 240 | } 241 | }, 242 | "outputs": [ 243 | { 244 | "data": { 245 | "text/plain": [ 246 | "\"first part second part!\"" 247 | ] 248 | }, 249 | "execution_count": 5, 250 | "metadata": {}, 251 | "output_type": "execute_result" 252 | } 253 | ], 254 | "source": [ 255 | "\"first part \" * \"second part!\"" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": { 261 | "slideshow": { 262 | "slide_type": "fragment" 263 | } 264 | }, 265 | "source": [ 266 | "Note: you might be more familiar with using `+` sign that is used for concatenation in many other languages. \n", 267 | "\n", 268 | "Julia philosophy to select multiplication was, however, done because it makes *mathematically* more sense to express the \"sticking together\" as multiplication." 269 | ] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": { 274 | "slideshow": { 275 | "slide_type": "skip" 276 | } 277 | }, 278 | "source": [ 279 | "### Special addition for math nerds:\n", 280 | "While `*` may seem like a surprising choice to users of languages that provide `+` for string concatenation, this use of `*` has precedent in mathematics, particularly in abstract algebra.\n", 281 | "\n", 282 | "In mathematics, `+` usually denotes a commutative operation, where the order of the operands does not matter. An example of this is matrix addition, where `A + B == B + A` for any matrices `A` and `B` that have the same shape. In contrast, `*` typically denotes a noncommutative operation, where the order of the operands does matter. An example of this is matrix multiplication, where in general `A * B != B * A`. As with matrix multiplication, string concatenation is noncommutative: `greet * whom != whom * greet`. As such, `*` is a more natural choice for an infix string concatenation operator, consistent with common mathematical use." 283 | ] 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "metadata": { 288 | "slideshow": { 289 | "slide_type": "slide" 290 | } 291 | }, 292 | "source": [ 293 | "## Specialized strings\n", 294 | "Sometimes strings come with a specialization, marked by a one or more characters immediately followed by the opening double quotes:\n", 295 | "- `r\" \"` indicates a regular expression\n", 296 | "- `v\" \"` indicates a version string\n", 297 | "- `raw\" \"` indicates a raw string literal (so no errors with `$`)\n", 298 | "\n", 299 | "Furthermore, some packages extend this feature even further. For example, the [LaTeXStrings](https://github.com/stevengj/LaTeXStrings.jl) supported by many plotting libraries uses \n", 300 | "```julia\n", 301 | "label = L\"This is a LaTeX string $\\sum_i x^2$\"\n", 302 | "```\n", 303 | "that supports full arsenal of mathematical symbols using the LaTeX syntax." 304 | ] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": { 309 | "slideshow": { 310 | "slide_type": "slide" 311 | } 312 | }, 313 | "source": [ 314 | "## Advanced: `printf()`\n", 315 | "If you are deeply attached to C-style `printf()` functionality, you'll be able to use a Julia macro for it (which are called by prefacing them with the `@` sign) by first issuing `using Printf`." 316 | ] 317 | }, 318 | { 319 | "cell_type": "code", 320 | "execution_count": 2, 321 | "metadata": { 322 | "slideshow": { 323 | "slide_type": "fragment" 324 | } 325 | }, 326 | "outputs": [ 327 | { 328 | "name": "stdout", 329 | "output_type": "stream", 330 | "text": [ 331 | "pi = 3.14159265358979311600" 332 | ] 333 | } 334 | ], 335 | "source": [ 336 | "using Printf\n", 337 | "@printf(\"pi = %0.20f\", float(pi))" 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": { 343 | "slideshow": { 344 | "slide_type": "fragment" 345 | } 346 | }, 347 | "source": [ 348 | "Or you can create another string using the `sprintf()` macro:" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": 3, 354 | "metadata": { 355 | "slideshow": { 356 | "slide_type": "fragment" 357 | } 358 | }, 359 | "outputs": [ 360 | { 361 | "data": { 362 | "text/plain": [ 363 | "\"pi = 3.14159265358979311600\"" 364 | ] 365 | }, 366 | "execution_count": 3, 367 | "metadata": {}, 368 | "output_type": "execute_result" 369 | } 370 | ], 371 | "source": [ 372 | "s = @sprintf(\"pi = %0.20f\", float(pi))" 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": { 378 | "slideshow": { 379 | "slide_type": "skip" 380 | } 381 | }, 382 | "source": [ 383 | "## List of string manipulation functions\n", 384 | "There are lots of functions for testing and changing strings:\n", 385 | "\n", 386 | "- `length(str)` length of string\n", 387 | "- `sizeof(str)` length/size\n", 388 | "- `startswith(strA, strB)` does strA start with strB?\n", 389 | "- `endswith(strA, strB)` does strA end with strB?\n", 390 | "- `isascii(str)` is str ASCII?\n", 391 | "- `all(isdigit, str)` is str 0-9?\n", 392 | "- `all(ispunct, str)` does str consist of punctuation?\n", 393 | "- `all(isspace, str)` is str whitespace characters?\n", 394 | "- `all(isxdigit, str)` is str hexadecimal digits?\n", 395 | "- `uppercase(str)` return a copy of str converted to uppercase\n", 396 | "- `lowercase(str)` return a copy of str converted to lowercase\n", 397 | "- `titlecase(str)` return copy of str with the first character of each word converted to uppercase\n", 398 | "- `chop(str)` return a copy with the last character removed\n", 399 | "- `chomp(str)` return a copy with the last character removed only if it's a newline\n" 400 | ] 401 | }, 402 | { 403 | "cell_type": "markdown", 404 | "metadata": { 405 | "slideshow": { 406 | "slide_type": "slide" 407 | } 408 | }, 409 | "source": [ 410 | "## Reading from files\n", 411 | "The standard approach for getting information from a text file is using the `open()`, `read()`, and `close()` functions." 412 | ] 413 | }, 414 | { 415 | "cell_type": "markdown", 416 | "metadata": { 417 | "slideshow": { 418 | "slide_type": "slide" 419 | } 420 | }, 421 | "source": [ 422 | "### Open\n", 423 | "Let's see how they work in action. First we need to open the file. In Julia, a file can be opened in the following modes\n", 424 | "- `\"r\"`: reading\n", 425 | "- `\"w\"`: writing (destroys everything in file)\n", 426 | "- `\"a\"`: appending (appends to the end of the file)\n", 427 | "\n", 428 | "Let's open a file in a folder `data/` called `poem.txt`. The syntax is \n", 429 | "```julia\n", 430 | "open(filename, mode)\n", 431 | "```" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 4, 437 | "metadata": { 438 | "slideshow": { 439 | "slide_type": "fragment" 440 | } 441 | }, 442 | "outputs": [ 443 | { 444 | "data": { 445 | "text/plain": [ 446 | "IOStream()" 447 | ] 448 | }, 449 | "execution_count": 4, 450 | "metadata": {}, 451 | "output_type": "execute_result" 452 | } 453 | ], 454 | "source": [ 455 | "f = open(\"../data/poem.txt\", \"r\")" 456 | ] 457 | }, 458 | { 459 | "cell_type": "markdown", 460 | "metadata": { 461 | "slideshow": { 462 | "slide_type": "slide" 463 | } 464 | }, 465 | "source": [ 466 | "### Read\n", 467 | "Then, we can read the content with a specific function made for this, `readline()`. Let's also remember to close the stream once we are done." 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": 5, 473 | "metadata": { 474 | "slideshow": { 475 | "slide_type": "fragment" 476 | } 477 | }, 478 | "outputs": [], 479 | "source": [ 480 | "lines = readlines(f)\n", 481 | "close(f)" 482 | ] 483 | }, 484 | { 485 | "cell_type": "markdown", 486 | "metadata": { 487 | "slideshow": { 488 | "slide_type": "fragment" 489 | } 490 | }, 491 | "source": [ 492 | "Now the content is inside a vector of strings called `lines`.\n", 493 | "\n", 494 | "Alternatively, we could have used `eachline()` function that turns a source into an iterator. This allows to process a file a line at a time:" 495 | ] 496 | }, 497 | { 498 | "cell_type": "code", 499 | "execution_count": null, 500 | "metadata": { 501 | "slideshow": { 502 | "slide_type": "fragment" 503 | } 504 | }, 505 | "outputs": [], 506 | "source": [ 507 | "open(\"../data/poem.txt\") do f\n", 508 | " for line in eachline(f)\n", 509 | " println(line)\n", 510 | " end\n", 511 | "end" 512 | ] 513 | }, 514 | { 515 | "cell_type": "markdown", 516 | "metadata": { 517 | "slideshow": { 518 | "slide_type": "skip" 519 | } 520 | }, 521 | "source": [ 522 | "Note: I am sorry all literature enthusiastics, this was the only short poem having a word \"julia\" in it that I could find." 523 | ] 524 | }, 525 | { 526 | "cell_type": "markdown", 527 | "metadata": { 528 | "slideshow": { 529 | "slide_type": "slide" 530 | } 531 | }, 532 | "source": [ 533 | "### Writing\n", 534 | "Writing a file, is a similar process. Instead of printing into the screen, we can provide an open file handle to our printing function:" 535 | ] 536 | }, 537 | { 538 | "cell_type": "code", 539 | "execution_count": 7, 540 | "metadata": { 541 | "slideshow": { 542 | "slide_type": "fragment" 543 | } 544 | }, 545 | "outputs": [], 546 | "source": [ 547 | "open(\"../data/example.txt\", \"w\") do f\n", 548 | " println(f, \"My very own line of text.\")\n", 549 | "end" 550 | ] 551 | }, 552 | { 553 | "cell_type": "markdown", 554 | "metadata": { 555 | "slideshow": { 556 | "slide_type": "slide" 557 | } 558 | }, 559 | "source": [ 560 | "## Writing and reading array to and from a file\n", 561 | "In real life, this is typically not how stuff is done. There is a much easier way via `using DelimitedFiles`!\n", 562 | "\n", 563 | "In many cases, we are reading data that is in some fixed array format. Most common is the CSV (Comma Separated Value) format. Julia provides us with a convenient set of functions to handle these kind of data formats with read and write delimited data, or `readdlm()` and `writedlm()`.\n", 564 | "\n", 565 | "Syntax is \n", 566 | "```julia\n", 567 | "readdlm(filename, delimiter)\n", 568 | "```\n", 569 | "and\n", 570 | "```julia\n", 571 | "writedlm(filename, array, delimiter)\n", 572 | "```\n", 573 | "If the `delimiter` (i.e., `','` for CSV) is omitted, a TAB is used by default." 574 | ] 575 | }, 576 | { 577 | "cell_type": "code", 578 | "execution_count": 8, 579 | "metadata": { 580 | "slideshow": { 581 | "slide_type": "slide" 582 | } 583 | }, 584 | "outputs": [ 585 | { 586 | "data": { 587 | "text/plain": [ 588 | "3×5 Array{Float64,2}:\n", 589 | " 0.568929 0.575358 0.789489 0.699436 0.64208 \n", 590 | " 0.990878 0.253297 0.653797 0.277166 0.680533\n", 591 | " 0.288649 0.250189 0.9892 0.213586 0.740666" 592 | ] 593 | }, 594 | "execution_count": 8, 595 | "metadata": {}, 596 | "output_type": "execute_result" 597 | } 598 | ], 599 | "source": [ 600 | "arr = rand(3,5)" 601 | ] 602 | }, 603 | { 604 | "cell_type": "code", 605 | "execution_count": 10, 606 | "metadata": { 607 | "slideshow": { 608 | "slide_type": "fragment" 609 | } 610 | }, 611 | "outputs": [], 612 | "source": [ 613 | "using DelimitedFiles\n", 614 | "writedlm(\"../data/my_arr.txt\", arr, ',')" 615 | ] 616 | }, 617 | { 618 | "cell_type": "code", 619 | "execution_count": 11, 620 | "metadata": { 621 | "slideshow": { 622 | "slide_type": "fragment" 623 | } 624 | }, 625 | "outputs": [ 626 | { 627 | "data": { 628 | "text/plain": [ 629 | "3×5 Array{Float64,2}:\n", 630 | " 0.568929 0.575358 0.789489 0.699436 0.64208 \n", 631 | " 0.990878 0.253297 0.653797 0.277166 0.680533\n", 632 | " 0.288649 0.250189 0.9892 0.213586 0.740666" 633 | ] 634 | }, 635 | "execution_count": 11, 636 | "metadata": {}, 637 | "output_type": "execute_result" 638 | } 639 | ], 640 | "source": [ 641 | "arr2 = readdlm(\"../data/my_arr.txt\", ',')" 642 | ] 643 | }, 644 | { 645 | "cell_type": "markdown", 646 | "metadata": { 647 | "slideshow": { 648 | "slide_type": "skip" 649 | } 650 | }, 651 | "source": [ 652 | "## Advanced: Regular expressions\n", 653 | "Julia has Perl-compatible regular expressions (regexes), as provided by the [PCRE](http://www.pcre.org/) library. Regular expressions are used to find regular patterns in strings. " 654 | ] 655 | }, 656 | { 657 | "cell_type": "code", 658 | "execution_count": 12, 659 | "metadata": { 660 | "slideshow": { 661 | "slide_type": "skip" 662 | } 663 | }, 664 | "outputs": [ 665 | { 666 | "data": { 667 | "text/plain": [ 668 | "r\"^\\s*(?:#|$)\"" 669 | ] 670 | }, 671 | "execution_count": 12, 672 | "metadata": {}, 673 | "output_type": "execute_result" 674 | } 675 | ], 676 | "source": [ 677 | "r = r\"^\\s*(?:#|$)\"" 678 | ] 679 | }, 680 | { 681 | "cell_type": "code", 682 | "execution_count": 13, 683 | "metadata": { 684 | "slideshow": { 685 | "slide_type": "skip" 686 | } 687 | }, 688 | "outputs": [ 689 | { 690 | "data": { 691 | "text/plain": [ 692 | "Regex" 693 | ] 694 | }, 695 | "execution_count": 13, 696 | "metadata": {}, 697 | "output_type": "execute_result" 698 | } 699 | ], 700 | "source": [ 701 | "typeof(r)" 702 | ] 703 | }, 704 | { 705 | "cell_type": "markdown", 706 | "metadata": { 707 | "slideshow": { 708 | "slide_type": "skip" 709 | } 710 | }, 711 | "source": [ 712 | "To check if a regex matches a string, use `match()`. Note that it returns nothing if nothing is found." 713 | ] 714 | }, 715 | { 716 | "cell_type": "code", 717 | "execution_count": 16, 718 | "metadata": { 719 | "slideshow": { 720 | "slide_type": "skip" 721 | } 722 | }, 723 | "outputs": [], 724 | "source": [ 725 | "match(r\"^\\s*(?:#|$)\", \"not a comment\")" 726 | ] 727 | }, 728 | { 729 | "cell_type": "code", 730 | "execution_count": 17, 731 | "metadata": { 732 | "slideshow": { 733 | "slide_type": "skip" 734 | } 735 | }, 736 | "outputs": [ 737 | { 738 | "data": { 739 | "text/plain": [ 740 | "RegexMatch(\"#\")" 741 | ] 742 | }, 743 | "execution_count": 17, 744 | "metadata": {}, 745 | "output_type": "execute_result" 746 | } 747 | ], 748 | "source": [ 749 | "match(r\"^\\s*(?:#|$)\", \"# a comment\")" 750 | ] 751 | }, 752 | { 753 | "cell_type": "markdown", 754 | "metadata": { 755 | "slideshow": { 756 | "slide_type": "skip" 757 | } 758 | }, 759 | "source": [ 760 | "For more, see the docs about [Regular Expressions](https://docs.julialang.org/en/v1/manual/strings/#Regular-Expressions-1)" 761 | ] 762 | }, 763 | { 764 | "cell_type": "code", 765 | "execution_count": null, 766 | "metadata": {}, 767 | "outputs": [], 768 | "source": [] 769 | } 770 | ], 771 | "metadata": { 772 | "celltoolbar": "Slideshow", 773 | "kernelspec": { 774 | "display_name": "Julia 1.0.3", 775 | "language": "julia", 776 | "name": "julia-1.0" 777 | }, 778 | "language_info": { 779 | "file_extension": ".jl", 780 | "mimetype": "application/julia", 781 | "name": "julia", 782 | "version": "1.0.3" 783 | } 784 | }, 785 | "nbformat": 4, 786 | "nbformat_minor": 2 787 | } 788 | -------------------------------------------------------------------------------- /notebooks/08_ecosystem-II.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Julia ecosystems II" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "fragment" 19 | } 20 | }, 21 | "source": [ 22 | "## Topics\n", 23 | "- Ecosystems\n", 24 | "- Own modules & packages\n" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": { 30 | "slideshow": { 31 | "slide_type": "slide" 32 | } 33 | }, 34 | "source": [ 35 | "## Ecosystem\n", 36 | "\n", 37 | "Julia has a large ecosystem of packages, maintained by a wide variety of people. \n", 38 | "\n", 39 | "In the best of academic ideals, Julia users from across the world come together to create mutually compatible and supporting packages for their domains. To manage these collections of packages they often use GitHub organisations" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": { 45 | "slideshow": { 46 | "slide_type": "slide" 47 | } 48 | }, 49 | "source": [ 50 | "## Julia package ecosystem [pulse](https://pkg.julialang.org/docs/)\n", 51 | "![pulse](../slides/allver.svg)" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": { 57 | "slideshow": { 58 | "slide_type": "slide" 59 | } 60 | }, 61 | "source": [ 62 | "## General\n", 63 | "- [JuliaDocs](https://github.com/juliadocs) – Documentation-related packages for Julia \n", 64 | "- [Julia-i18n](https://github.com/Julia-i18n) – Internationalization (i18n) and localization (L10n) for Julians \n", 65 | "- [JuliaTime](https://github.com/JuliaTime) – Date and time libraries\n", 66 | "- [JuliaPraxis](https://github.com/JuliaPraxis) – Best practices \n", 67 | "- [JuliaEditorSupport](https://github.com/JuliaEditorSupport) – Extensions/Plugins for text editors and IDEs\n", 68 | "- [Juno](https://github.com/JunoLab) – The Juno IDE for Atom \n" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": { 74 | "slideshow": { 75 | "slide_type": "slide" 76 | } 77 | }, 78 | "source": [ 79 | "## Computing\n", 80 | "- [JuliaArrays](https://github.com/JuliaArrays) – Custom array types (and utilities for building array types)\n", 81 | "- [JuliaBerry](https://github.com/JuliaBerry) – [Julia resources for the Raspberry Pi](https://juliaberry.github.io/)\n", 82 | "- [JuliaCI](https://github.com/JuliaCI) – Continuous Integration Support for Julia packages\n", 83 | "- [JuliaGPU](https://github.com/JuliaGPU) – GPU computing\n", 84 | "- [JuliaInterop](https://github.com/JuliaInterop) – Easy interoperability between Julia and not-Julia\n", 85 | "- [JuliaIO](https://github.com/JuliaIO) – IO-related functionality, such as serialization\n", 86 | "- [JuliaParallel](https://github.com/JuliaParallel) – Parallel programming in Julia\n", 87 | "- [JuliaWeb](https://github.com/JuliaWeb) – Web stack" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": { 93 | "slideshow": { 94 | "slide_type": "slide" 95 | } 96 | }, 97 | "source": [ 98 | "## Mathematics\n", 99 | "- [JuliaDiff](https://github.com/JuliaDiff/) – Differentiation tools\n", 100 | "- [JuliaDiffEq](https://github.com/JuliaDiffEq) – Differential equation solving and analysis \n", 101 | "- [JuliaGeometry](https://github.com/JuliaGeometry) – Computational Geometry\n", 102 | "- [JuliaGraphs](https://github.com/JuliaGraphs) – Graph Theory and Implementation\n", 103 | "- [JuliaIntervals](https://github.com/JuliaIntervals) - Rigorous numerics with interval arithmetic & applications\n", 104 | "- [JuliaMath](https://github.com/JuliaMath) – Mathematics made easy in Julia\n", 105 | "- [JuliaOpt](https://github.com/JuliaOpt) – Optimization \n", 106 | "- [JuliaPolyhedra](https://github.com/JuliaPolyhedra) – Polyhedral computation\n", 107 | "- [JuliaSparse](https://github.com/JuliaSparse) – Sparse matrix solvers\n", 108 | "\n" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": { 114 | "slideshow": { 115 | "slide_type": "slide" 116 | } 117 | }, 118 | "source": [ 119 | "## Scientific domains\n", 120 | "- [BioJulia](https://github.com/BioJulia) – Biology \n", 121 | "- [EcoJulia](https://github.com/EcoJulia) – Ecology\n", 122 | "- [JuliaAstro](https://github.com/JuliaAstro) – Astronomy \n", 123 | "- [JuliaDSP](https://github.com/JuliaDSP) – Digital signal processing\n", 124 | "- [JuliaQuant](https://github.com/JuliaQuant) – Finance\n", 125 | "- [JuliaQuantum](https://github.com/JuliaQuantum) – Julia libraries for quantum science and technology \n", 126 | "- [JuliaPhysics](https://github.com/JuliaPhysics) – Physics\n", 127 | "- [JuliaDynamics](https://github.com/JuliaDynamics) - Dynamical systems, nonlinear dynamics and chaos.\n" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": { 133 | "slideshow": { 134 | "slide_type": "slide" 135 | } 136 | }, 137 | "source": [ 138 | "## Data sciences\n", 139 | "- [JuliaML](https://github.com/JuliaML) – Machine Learning\n", 140 | "- [JuliaStats](https://github.com/JuliaStats) – Statistics\n", 141 | "- [JuliaImages](https://github.com/JuliaImages) – Image Processing\n", 142 | "- [JuliaText](https://github.com/JuliaText) – Natural Language Processing (NLP), Computational Linguistics and (textual) Information Retrieval\n", 143 | "- [JuliaDatabases](https://github.com/JuliaDatabases) – Various database drivers for Julia\n", 144 | "- [JuliaData](https://github.com/JuliaData) – Data manipulation, storage, and I/O in Julia\n" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": { 150 | "slideshow": { 151 | "slide_type": "slide" 152 | } 153 | }, 154 | "source": [ 155 | "## Own modules\n", 156 | "Julia code is organized into files, modules, and packages. Files containing Julia code use the `.jl` file extension.\n", 157 | "\n", 158 | "Related functions and other definitions can be grouped together and stored in modules. The structure of a module is like this:\n", 159 | "```julia\n", 160 | "module MyModule\n", 161 | "\n", 162 | "end\n", 163 | "```\n", 164 | "and in between these lines you can put functions, type definitions, constants, and so on." 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": { 170 | "slideshow": { 171 | "slide_type": "fragment" 172 | } 173 | }, 174 | "source": [ 175 | "One or more modules can be stored in a package, and these are managed using the git version control system. Most Julia packages, including the official ones, are stored on GitHub, where each Julia package is, by convention, named with a \".jl\" suffix." 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "metadata": { 181 | "slideshow": { 182 | "slide_type": "slide" 183 | } 184 | }, 185 | "source": [ 186 | "## `using` and `import`\n", 187 | "`import` is similar to `using`, but differs in a few ways, for example, in how you access the functions inside the module. Here's a module with two functions, one of which is exported:" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": { 193 | "slideshow": { 194 | "slide_type": "fragment" 195 | } 196 | }, 197 | "source": [ 198 | "```julia\n", 199 | "module MyModule\n", 200 | "export mycoolfunction\n", 201 | "\n", 202 | "function mycoolfunction()\n", 203 | " println(\"this is my cool function\")\n", 204 | "end\n", 205 | "function mysecretfunction()\n", 206 | " println(\"this is my secret function\")\n", 207 | "end\n", 208 | "\n", 209 | "end\n", 210 | "```" 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": { 216 | "slideshow": { 217 | "slide_type": "slide" 218 | } 219 | }, 220 | "source": [ 221 | "and after importing the module\n", 222 | "```julia\n", 223 | "import MyModule\n", 224 | "mycoolfunction()\n", 225 | "```\n", 226 | "gives `ERROR: mycoolfunction not defined`." 227 | ] 228 | }, 229 | { 230 | "cell_type": "markdown", 231 | "metadata": { 232 | "slideshow": { 233 | "slide_type": "fragment" 234 | } 235 | }, 236 | "source": [ 237 | "However\n", 238 | "```julia\n", 239 | "MyModyle.mycoolfunction()\n", 240 | "```\n", 241 | "prints `\"this is my cool function\"`.\n", 242 | "\n", 243 | "Notice that `mycoolfunction()` could be accessed only with the module prefix. This is because the `MyModule` module was loaded using `import` rather than `using`." 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "metadata": { 249 | "slideshow": { 250 | "slide_type": "slide" 251 | } 252 | }, 253 | "source": [ 254 | "#### What about the non-exported `mysecretfunction()`?\n", 255 | "```julia\n", 256 | "mysecretfunction()\n", 257 | "```\n", 258 | "gives `ERROR: mysecretfunction not defined`\n", 259 | "and \n", 260 | "```julia\n", 261 | "MyModule.mysecretfunction()\n", 262 | "```\n", 263 | "prints `\"this is my secret function\"`." 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": { 269 | "slideshow": { 270 | "slide_type": "slide" 271 | } 272 | }, 273 | "source": [ 274 | "## `import`\n", 275 | "So to summarize:\n", 276 | "\n", 277 | "`import`, like `using`, will load modules and packages for use. Unlike `using`, however, it will not make any exported names available for use.\n", 278 | "\n", 279 | "Another important difference is when you want to modify or extend a function from another module. You can't use using, you have to import the specific function.\n" 280 | ] 281 | }, 282 | { 283 | "cell_type": "markdown", 284 | "metadata": { 285 | "slideshow": { 286 | "slide_type": "slide" 287 | } 288 | }, 289 | "source": [ 290 | "## `include` and `reload`\n", 291 | "#### `include()`:\n", 292 | "\n", 293 | "Evaluate the contents of the input source file in the current context. Returns the result of the last evaluated expression of the input file. \n", 294 | "\n", 295 | "This function is typically used to load source interactively, or to combine files in packages that are broken into multiple source files.\n", 296 | " \n", 297 | "All paths refer to files on node 1 when running in parallel, and files will be fetched from node 1.\n" 298 | ] 299 | } 300 | ], 301 | "metadata": { 302 | "celltoolbar": "Slideshow", 303 | "kernelspec": { 304 | "display_name": "Julia 1.0.3", 305 | "language": "julia", 306 | "name": "julia-1.0" 307 | }, 308 | "language_info": { 309 | "file_extension": ".jl", 310 | "mimetype": "application/julia", 311 | "name": "julia", 312 | "version": "1.0.3" 313 | } 314 | }, 315 | "nbformat": 4, 316 | "nbformat_minor": 2 317 | } 318 | -------------------------------------------------------------------------------- /notebooks/Bonus_metaprogramming.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Metaprogramming\n", 8 | "\n", 9 | "\"Meta\": one level up\n", 10 | "\"Metaprogramming\": programming a program.\n", 11 | "\n", 12 | "Means talking about Julia code within Julia!\n", 13 | "\n", 14 | "Refs: see lecture [slides](https://github.com/alanedelman/18.337_2016/blob/master/lectures/lecture_5_09_21/Introduction%20to%20metaprogramming.ipynb) by Alan Edelman for more." 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": {}, 21 | "outputs": [ 22 | { 23 | "data": { 24 | "text/plain": [ 25 | "quote\n", 26 | " #= In[1]:3 =#\n", 27 | " z = x + y\n", 28 | "end" 29 | ] 30 | }, 31 | "execution_count": 1, 32 | "metadata": {}, 33 | "output_type": "execute_result" 34 | } 35 | ], 36 | "source": [ 37 | "ex =\n", 38 | "quote \n", 39 | " z = x + y\n", 40 | "end" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 2, 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "data": { 50 | "text/plain": [ 51 | "Expr" 52 | ] 53 | }, 54 | "execution_count": 2, 55 | "metadata": {}, 56 | "output_type": "execute_result" 57 | } 58 | ], 59 | "source": [ 60 | "typeof(ex)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 3, 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "data": { 70 | "text/plain": [ 71 | ":block" 72 | ] 73 | }, 74 | "execution_count": 3, 75 | "metadata": {}, 76 | "output_type": "execute_result" 77 | } 78 | ], 79 | "source": [ 80 | "ex.head" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 4, 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "data": { 90 | "text/plain": [ 91 | "2-element Array{Any,1}:\n", 92 | " :(#= In[1]:3 =#)\n", 93 | " :(z = x + y) " 94 | ] 95 | }, 96 | "execution_count": 4, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "ex.args" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "Can also be written as:" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 5, 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "data": { 119 | "text/plain": [ 120 | ":(z = x + y)" 121 | ] 122 | }, 123 | "execution_count": 5, 124 | "metadata": {}, 125 | "output_type": "execute_result" 126 | } 127 | ], 128 | "source": [ 129 | "ex = :(z = x + y)" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 6, 135 | "metadata": {}, 136 | "outputs": [ 137 | { 138 | "data": { 139 | "text/plain": [ 140 | "3" 141 | ] 142 | }, 143 | "execution_count": 6, 144 | "metadata": {}, 145 | "output_type": "execute_result" 146 | } 147 | ], 148 | "source": [ 149 | "x = 1\n", 150 | "y = 2\n", 151 | "eval(ex)" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 7, 157 | "metadata": {}, 158 | "outputs": [ 159 | { 160 | "data": { 161 | "text/plain": [ 162 | ":(z = x + y)" 163 | ] 164 | }, 165 | "execution_count": 7, 166 | "metadata": {}, 167 | "output_type": "execute_result" 168 | } 169 | ], 170 | "source": [ 171 | "ex" 172 | ] 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "metadata": {}, 177 | "source": [ 178 | "## Manipulating expressions" 179 | ] 180 | }, 181 | { 182 | "cell_type": "code", 183 | "execution_count": 8, 184 | "metadata": {}, 185 | "outputs": [ 186 | { 187 | "data": { 188 | "text/plain": [ 189 | ":(3x + 2 * x ^ 2)" 190 | ] 191 | }, 192 | "execution_count": 8, 193 | "metadata": {}, 194 | "output_type": "execute_result" 195 | } 196 | ], 197 | "source": [ 198 | "ex = :(3x + 2x^2)" 199 | ] 200 | }, 201 | { 202 | "cell_type": "markdown", 203 | "metadata": {}, 204 | "source": [ 205 | "Let's replace all `x` by `(x+1)`s." 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": 9, 211 | "metadata": {}, 212 | "outputs": [ 213 | { 214 | "data": { 215 | "text/plain": [ 216 | "3-element Array{Any,1}:\n", 217 | " :+ \n", 218 | " :(3x) \n", 219 | " :(2 * x ^ 2)" 220 | ] 221 | }, 222 | "execution_count": 9, 223 | "metadata": {}, 224 | "output_type": "execute_result" 225 | } 226 | ], 227 | "source": [ 228 | "ex.args" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 10, 234 | "metadata": {}, 235 | "outputs": [ 236 | { 237 | "data": { 238 | "text/plain": [ 239 | ":x" 240 | ] 241 | }, 242 | "execution_count": 10, 243 | "metadata": {}, 244 | "output_type": "execute_result" 245 | } 246 | ], 247 | "source": [ 248 | "ex.args[2].args[3]" 249 | ] 250 | }, 251 | { 252 | "cell_type": "code", 253 | "execution_count": 11, 254 | "metadata": {}, 255 | "outputs": [ 256 | { 257 | "data": { 258 | "text/plain": [ 259 | ":(x + 1)" 260 | ] 261 | }, 262 | "execution_count": 11, 263 | "metadata": {}, 264 | "output_type": "execute_result" 265 | } 266 | ], 267 | "source": [ 268 | "ex.args[2].args[3] = :(x+1)" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 12, 274 | "metadata": {}, 275 | "outputs": [ 276 | { 277 | "data": { 278 | "text/plain": [ 279 | ":(3 * (x + 1) + 2 * x ^ 2)" 280 | ] 281 | }, 282 | "execution_count": 12, 283 | "metadata": {}, 284 | "output_type": "execute_result" 285 | } 286 | ], 287 | "source": [ 288 | "ex" 289 | ] 290 | }, 291 | { 292 | "cell_type": "code", 293 | "execution_count": 13, 294 | "metadata": {}, 295 | "outputs": [ 296 | { 297 | "data": { 298 | "text/plain": [ 299 | "8" 300 | ] 301 | }, 302 | "execution_count": 13, 303 | "metadata": {}, 304 | "output_type": "execute_result" 305 | } 306 | ], 307 | "source": [ 308 | "eval(ex)" 309 | ] 310 | }, 311 | { 312 | "cell_type": "markdown", 313 | "metadata": {}, 314 | "source": [ 315 | "## Parsing from text" 316 | ] 317 | }, 318 | { 319 | "cell_type": "code", 320 | "execution_count": 14, 321 | "metadata": {}, 322 | "outputs": [ 323 | { 324 | "data": { 325 | "text/plain": [ 326 | "\"3x + 3x^2\"" 327 | ] 328 | }, 329 | "execution_count": 14, 330 | "metadata": {}, 331 | "output_type": "execute_result" 332 | } 333 | ], 334 | "source": [ 335 | "s = \"3x + 3x^2\"" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 16, 341 | "metadata": {}, 342 | "outputs": [ 343 | { 344 | "data": { 345 | "text/plain": [ 346 | ":(3x + 3 * x ^ 2)" 347 | ] 348 | }, 349 | "execution_count": 16, 350 | "metadata": {}, 351 | "output_type": "execute_result" 352 | } 353 | ], 354 | "source": [ 355 | "ex = Meta.parse(s)" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 17, 361 | "metadata": {}, 362 | "outputs": [ 363 | { 364 | "data": { 365 | "text/plain": [ 366 | "6" 367 | ] 368 | }, 369 | "execution_count": 17, 370 | "metadata": {}, 371 | "output_type": "execute_result" 372 | } 373 | ], 374 | "source": [ 375 | "eval(ex)" 376 | ] 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": {}, 381 | "source": [ 382 | "Magic, right!" 383 | ] 384 | } 385 | ], 386 | "metadata": { 387 | "kernelspec": { 388 | "display_name": "Julia 1.0.3", 389 | "language": "julia", 390 | "name": "julia-1.0" 391 | }, 392 | "language_info": { 393 | "file_extension": ".jl", 394 | "mimetype": "application/julia", 395 | "name": "julia", 396 | "version": "1.0.3" 397 | } 398 | }, 399 | "nbformat": 4, 400 | "nbformat_minor": 2 401 | } 402 | -------------------------------------------------------------------------------- /notebooks/Bonus_simd-vectorization.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "## SIMD Vectorization\n", 12 | "Does my code vectorize? Let's take a look." 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 1, 18 | "metadata": { 19 | "slideshow": { 20 | "slide_type": "fragment" 21 | } 22 | }, 23 | "outputs": [ 24 | { 25 | "data": { 26 | "text/plain": [ 27 | "add (generic function with 1 method)" 28 | ] 29 | }, 30 | "execution_count": 1, 31 | "metadata": {}, 32 | "output_type": "execute_result" 33 | } 34 | ], 35 | "source": [ 36 | "function add(out, x, y)\n", 37 | " for i in 1:length(out)\n", 38 | " out[i] = x[i] + y[i]\n", 39 | " end\n", 40 | " return out\n", 41 | "end" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 2, 47 | "metadata": {}, 48 | "outputs": [ 49 | { 50 | "name": "stdout", 51 | "output_type": "stream", 52 | "text": [ 53 | "\n", 54 | "; Function add\n", 55 | "; Location: In[1]:2\n", 56 | "; Function Attrs: noreturn\n", 57 | "define nonnull %jl_value_t addrspace(10)* @japi1_add_35688(%jl_value_t addrspace(10)*, %jl_value_t addrspace(10)**, i32) #0 {\n", 58 | "top:\n", 59 | " %3 = alloca %jl_value_t addrspace(10)*, i32 2\n", 60 | " %4 = alloca %jl_value_t addrspace(10)**, align 8\n", 61 | " store volatile %jl_value_t addrspace(10)** %1, %jl_value_t addrspace(10)*** %4, align 8\n", 62 | " %5 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 0\n", 63 | " store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 4625236400 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %5\n", 64 | " %6 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 1\n", 65 | " store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 4587922512 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %6\n", 66 | " %7 = call nonnull %jl_value_t addrspace(10)* @jl_apply_generic(%jl_value_t addrspace(10)** %3, i32 2)\n", 67 | " call void @llvm.trap()\n", 68 | " unreachable\n", 69 | "}\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "@code_llvm add(Vector{Float64}, Vector{Float64}, Vector{Float64})" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": { 80 | "slideshow": { 81 | "slide_type": "slide" 82 | } 83 | }, 84 | "source": [ 85 | "## @inbounds\n", 86 | "Adding `@inbounds` removes the bound-checks and gives LLVM the opportunity to auto-vectorize this function." 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 6, 92 | "metadata": { 93 | "slideshow": { 94 | "slide_type": "fragment" 95 | } 96 | }, 97 | "outputs": [ 98 | { 99 | "data": { 100 | "text/plain": [ 101 | "add2 (generic function with 1 method)" 102 | ] 103 | }, 104 | "execution_count": 6, 105 | "metadata": {}, 106 | "output_type": "execute_result" 107 | } 108 | ], 109 | "source": [ 110 | "function add2(out, x, y)\n", 111 | " @inbounds for i in 1:length(out)\n", 112 | " out[i] = x[i] + y[i]\n", 113 | " end\n", 114 | " return out\n", 115 | "end" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 7, 121 | "metadata": { 122 | "scrolled": false, 123 | "slideshow": { 124 | "slide_type": "slide" 125 | } 126 | }, 127 | "outputs": [ 128 | { 129 | "name": "stdout", 130 | "output_type": "stream", 131 | "text": [ 132 | "\n", 133 | "; Function add2\n", 134 | "; Location: In[6]:2\n", 135 | "; Function Attrs: noreturn\n", 136 | "define nonnull %jl_value_t addrspace(10)* @japi1_add2_35743(%jl_value_t addrspace(10)*, %jl_value_t addrspace(10)**, i32) #0 {\n", 137 | "top:\n", 138 | " %3 = alloca %jl_value_t addrspace(10)*, i32 2\n", 139 | " %4 = alloca %jl_value_t addrspace(10)**, align 8\n", 140 | " store volatile %jl_value_t addrspace(10)** %1, %jl_value_t addrspace(10)*** %4, align 8\n", 141 | " %5 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 0\n", 142 | " store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 4625236400 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %5\n", 143 | " %6 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 1\n", 144 | " store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 4587922512 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %6\n", 145 | " %7 = call nonnull %jl_value_t addrspace(10)* @jl_apply_generic(%jl_value_t addrspace(10)** %3, i32 2)\n", 146 | " call void @llvm.trap()\n", 147 | " unreachable\n", 148 | "}\n" 149 | ] 150 | } 151 | ], 152 | "source": [ 153 | "@code_llvm add2(Vector{Float64}, Vector{Float64}, Vector{Float64})" 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": {}, 159 | "source": [ 160 | "## SIMD.jl\n", 161 | "Other option is to use explicit SIMD vectorization instructions. The [SIMD.jl](https://github.com/eschnett/SIMD.jl) library gives you correct data types for this." 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "## Additionally:\n", 169 | "Look [here](https://slides.com/valentinchuravy/julia-parallelism) for a lecture about levels of parallelism in Julia.\n", 170 | "\n", 171 | "The syntactic loop fusion is discussed [here](https://julialang.org/blog/2017/01/moredots)." 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": {}, 178 | "outputs": [], 179 | "source": [] 180 | } 181 | ], 182 | "metadata": { 183 | "kernelspec": { 184 | "display_name": "Julia 1.0.3", 185 | "language": "julia", 186 | "name": "julia-1.0" 187 | }, 188 | "language_info": { 189 | "file_extension": ".jl", 190 | "mimetype": "application/julia", 191 | "name": "julia", 192 | "version": "1.0.3" 193 | } 194 | }, 195 | "nbformat": 4, 196 | "nbformat_minor": 2 197 | } 198 | -------------------------------------------------------------------------------- /slides/benchmarks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csc-training/julia-introduction/dea74549af892b4181dcf914ca99ed5d59e00fb1/slides/benchmarks.png -------------------------------------------------------------------------------- /slides/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | jupyter nbconvert ../notebooks/00_notebooks.ipynb --to slides --reveal-prefix ../reveal.js 4 | jupyter nbconvert ../notebooks/00_intro-to-julia.ipynb --to slides --reveal-prefix ../reveal.js 5 | jupyter nbconvert ../notebooks/01_basics.ipynb --to slides --reveal-prefix ../reveal.js 6 | jupyter nbconvert ../notebooks/02_control-flow.ipynb --to slides --reveal-prefix ../reveal.js 7 | jupyter nbconvert ../notebooks/03_functions.ipynb --to slides --reveal-prefix ../reveal.js 8 | jupyter nbconvert ../notebooks/04_io.ipynb --to slides --reveal-prefix ../reveal.js 9 | jupyter nbconvert ../notebooks/05_development-practises.ipynb --to slides --reveal-prefix ../reveal.js 10 | jupyter nbconvert ../notebooks/06_ecosystem-I.ipynb --to slides --reveal-prefix ../reveal.js 11 | jupyter nbconvert ../notebooks/07_ecosystem-II.ipynb --to slides --reveal-prefix ../reveal.js 12 | jupyter nbconvert ../notebooks/08_hpc.ipynb --to slides --reveal-prefix ../reveal.js 13 | 14 | 15 | mv ../notebooks/00_notebooks.slides.html . 16 | mv ../notebooks/00_intro-to-julia.slides.html . 17 | mv ../notebooks/01_basics.slides.html . 18 | mv ../notebooks/02_control-flow.slides.html . 19 | mv ../notebooks/03_functions.slides.html . 20 | mv ../notebooks/04_io.slides.html . 21 | mv ../notebooks/05_development-practises.slides.html . 22 | mv ../notebooks/06_ecosystem-I.slides.html . 23 | mv ../notebooks/07_ecosystem-II.slides.html . 24 | mv ../notebooks/08_hpc.slides.html . 25 | 26 | 27 | -------------------------------------------------------------------------------- /slides/tmp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csc-training/julia-introduction/dea74549af892b4181dcf914ca99ed5d59e00fb1/slides/tmp.gif --------------------------------------------------------------------------------