Skip to content

Instantly share code, notes, and snippets.

@pawelswiecki
Last active August 4, 2022 16:36
Show Gist options
  • Save pawelswiecki/c44a343ba98db7dfeeef7d49a4f5124c to your computer and use it in GitHub Desktop.
Save pawelswiecki/c44a343ba98db7dfeeef7d49a4f5124c to your computer and use it in GitHub Desktop.
The Quickest Introduction to Julia (for Pythonistas)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"attachments": {
"image.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"![image.png](attachment:image.png)\n",
"# The Quickest Introduction to Julia\n",
"#### (for Pythonistas)\n",
"\n",
"Paweł Święcki"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_This notebook is based on `Julia 0.6.1`._"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_This notebook can be found here:_\n",
"\n",
"### https://gist.github.com/pawelswiecki"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. What is Julia and why should I care?\n",
"\n",
"Julia is:\n",
"\n",
"* **Fast** (like C, C++, ...; unlike Python, Ruby, ...)\n",
"\n",
"* **Easy to learn, quick to prototype with** (like Python, ...; unlike C, C++, Java, ...)\n",
"\n",
"* **Free** (like basically every language; unlike Matlab, Mathematica)\n",
"\n",
"It's designed to perform high performance numerical and scientific computing.\n",
"\n",
"It's **fast** due to **JIT compiler** and **smart type system** that helps the compiler to optimize the code. Mind that the programmer needs to know how to use the type system to achieve high performance. Julia also has powerful **metaprogramming capabilities**. \n",
"\n",
"I won't talk about type system or metaprogramming."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"What I will talk about:\n",
"\n",
"* basic types\n",
"\n",
"* syntax\n",
"\n",
"* defining functions\n",
"\n",
"* control flow\n",
"\n",
"* arrays and indexing\n",
"\n",
"* calling Python modules from Julia code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But first..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### JIT compiler in action"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"add (generic function with 1 method)"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function add(x, y)\n",
" return x + y\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0.001871 seconds (241 allocations: 16.345 KiB)\n"
]
},
{
"data": {
"text/plain": [
"30"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@time add(10, 20)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0.000002 seconds (4 allocations: 160 bytes)\n"
]
},
{
"data": {
"text/plain": [
"230"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@time add(110, 120)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0.004469 seconds (157 allocations: 10.153 KiB)\n"
]
},
{
"data": {
"text/plain": [
"70.0"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@time add(30.0, 40.0)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0.000005 seconds (5 allocations: 176 bytes)\n"
]
},
{
"data": {
"text/plain": [
"270.0"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@time add(130.0, 140.0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Basic types"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.1. Numeric types"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"10"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"i = 10"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Int64"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(i)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"10.1"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f = 10.1"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Float64"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(f)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1//2"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r = 1//2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`//`? What is `r`?"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5//2"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r + 2"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Rational{Int64}"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(r)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"2\n"
]
}
],
"source": [
"println(numerator(1//2))\n",
"println(denominator(1//2))"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4//7"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1//2 / 7//8"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3//10"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(1//2 + 1//4) * 2//5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can use rational numbers with denominator of zero (`0`)."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1//0"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1//0"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1//0"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1//0 + 10"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**In Python** there is no special syntax for rational numbers:\n",
"\n",
"```python\n",
"# Python code\n",
"In [1]: from fractions import Fraction\n",
"\n",
"In [2]: r = Fraction(1, 2) # or Fraction('1/2')\n",
"\n",
"In [3]: r + 2\n",
"Out[3]: Fraction(5, 2)\n",
"\n",
"In [4]: r.numerator, r.denominator\n",
"Out[4]: (1, 2)\n",
"\n",
"In [5]: (Fraction('1/2') + Fraction('1/4')) * Fraction('2/5')\n",
"Out[5]: Fraction(3, 10)\n",
" \n",
"In [6]: Fraction(1, 0)\n",
"ZeroDivisionError: Fraction(1, 0)\n",
" \n",
"In [7]: # ¯\\_(ツ)_/¯\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2. Strings and Chars"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\"Hello there!\""
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# We use double quote `\"` for Strings.\n",
"s = \"Hello there!\""
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"String"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(s)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'q': ASCII/Unicode U+0071 (category Ll: Letter, lowercase)"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# We use single quote `'` for Chars.\n",
"c = 'q'"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Char"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(c)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Indexing strings returns chars."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'l': ASCII/Unicode U+006c (category Ll: Letter, lowercase)"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s[4]"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Char"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(s[1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So in Julia a single element of a String is a Char.\n",
"\n",
"Unlike **in Python**, where it's another string:\n",
"\n",
"```python\n",
"# Python code:\n",
"In [1]: s = \"Hello there!\"\n",
"\n",
"In [2]: s[0]\n",
"Out[2]: 'H'\n",
"\n",
"In [3]: s[0][0]\n",
"Out[3]: 'H'\n",
"\n",
"In [4]: s[0][0][0]\n",
"Out[4]: 'H'\n",
" \n",
"In [5]: s[0][0][0][0]\n",
"Out[5]: 'H'\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Syntax"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.1. Indexing"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Julia uses **1-based indexing**.\n",
"\n",
"This is one of the biggest syntactic differences between Julia and Python (or, as a matter of fact, between Julia and most of the modern programming languages).\n",
"\n",
"Matlab, Mathematica, Fortran use 1-based indexing as well."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\"ABCDEFG\""
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s2 = \"ABCDEFG\""
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"ename": "LoadError",
"evalue": "\u001b[91mBoundsError: attempt to access \"ABCDEFG\"\n at index [0]\u001b[39m",
"output_type": "error",
"traceback": [
"\u001b[91mBoundsError: attempt to access \"ABCDEFG\"\n at index [0]\u001b[39m",
"",
"Stacktrace:",
" [1] \u001b[1mnext\u001b[22m\u001b[22m at \u001b[1m./strings/string.jl:197\u001b[22m\u001b[22m [inlined]",
" [2] \u001b[1mgetindex\u001b[22m\u001b[22m\u001b[1m(\u001b[22m\u001b[22m::String, ::Int64\u001b[1m)\u001b[22m\u001b[22m at \u001b[1m./strings/basic.jl:32\u001b[22m\u001b[22m",
" [3] \u001b[1minclude_string\u001b[22m\u001b[22m\u001b[1m(\u001b[22m\u001b[22m::String, ::String\u001b[1m)\u001b[22m\u001b[22m at \u001b[1m./loading.jl:522\u001b[22m\u001b[22m"
]
}
],
"source": [
"s2[0]"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s2[1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Accessing the last element"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'G': ASCII/Unicode U+0047 (category Lu: Letter, uppercase)"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s2[end]"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'F': ASCII/Unicode U+0046 (category Lu: Letter, uppercase)"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s2[end-1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Slicing"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\"ABC\""
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s2[1:3]"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\"BCDEF\""
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s2[2:end-1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Slicing with _step_ using `start:step:stop` syntax."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\"ACEG\""
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s2[1:2:end]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.2. Functions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.2.1. Defining functions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_Standard notation_"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"add1 (generic function with 1 method)"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function add1(x, y)\n",
" return x + y\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"add1(1, 2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Unlike in Python: \n",
"* `return` keyword is optional, value of the last expression gets returned. We can use `return` to return immediately;\n",
"\n",
"* indentation is optional (`end` keyword defines end of blocks).\n",
"\n",
"So this is equivalent: `function add1(x, y) x + y end`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_Math-like notation_"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"add2 (generic function with 1 method)"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"add2(x, y) = x + y"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"30"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"add2(10, 20)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Just like in Python, functions are first-class objects in Julia.\n",
"\n",
"We also can use **anonymous functions**."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(::#1) (generic function with 1 method)"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"((x, y) -> x + y)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"300"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"((x, y) -> x + y)(100, 200)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can assign an anonymous function to a name."
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(::#5) (generic function with 1 method)"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"add3 = (x, y) -> x + y"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"300"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"add3(100, 200)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.2.2. Operators are functions"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# this is a syntactic sugar\n",
"1 + 2\n",
"\n",
"# for this\n",
"+(1, 2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Also, we can pass operators around, just like any other functions."
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"silly_apply(fn, arg1, arg2) = fn(arg1, arg2)\n",
"\n",
"silly_apply(+, 1, 2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.2.3. Function naming convention"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Julia has a pretty smart naming convention: if a function's name ends with a bang (`!`) we know it may mutate its argument(s)."
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"7-element Array{Int64,1}:\n",
" 1\n",
" 2\n",
" 3\n",
" 4\n",
" 5\n",
" 6\n",
" 7"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"my_array = [1, 2, 3, 4, 5, 6, 7]"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"7-element Array{Int64,1}:\n",
" 7\n",
" 6\n",
" 5\n",
" 4\n",
" 3\n",
" 2\n",
" 1"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"reverse(my_array)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"7-element Array{Int64,1}:\n",
" 1\n",
" 2\n",
" 3\n",
" 4\n",
" 5\n",
" 6\n",
" 7"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"my_array"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"7-element Array{Int64,1}:\n",
" 7\n",
" 6\n",
" 5\n",
" 4\n",
" 3\n",
" 2\n",
" 1"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"reverse!(my_array)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"7-element Array{Int64,1}:\n",
" 7\n",
" 6\n",
" 5\n",
" 4\n",
" 3\n",
" 2\n",
" 1"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"my_array"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.3. Control flow"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.3.1. Conditional syntax"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"how_big_it_is (generic function with 1 method)"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function how_big_it_is(x)\n",
" if x < 2\n",
" println(\"$x is little\")\n",
" elseif x < 7\n",
" println(\"$x is pretty small.\")\n",
" elseif x < 20\n",
" println(\"$x is medium.\")\n",
" elseif x < 100\n",
" println(\"$x is big.\")\n",
" else\n",
" println(\"$x is huge!\")\n",
" end\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 is little\n"
]
}
],
"source": [
"how_big_it_is(1)"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"99 is big.\n"
]
}
],
"source": [
"how_big_it_is(99)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`if-elseif-else-end` blocks are expressions** — they return a value. \"This value is simply the return value of the last executed statement in the branch that was chosen\" [[docs](https://docs.julialang.org/en/release-0.6/manual/control-flow/#man-conditional-evaluation-1)]."
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"is_it_one (generic function with 1 method)"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function is_it_one(x)\n",
" answer =\n",
" if x == 1\n",
" println(\"It equals one! 🎉\")\n",
" true\n",
" else\n",
" println(\"$x doesn't equal one... 😟\")\n",
" false\n",
" end\n",
" return answer\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"25 doesn't equal one... 😟\n"
]
},
{
"data": {
"text/plain": [
"false"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"is_it_one(25)"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"It equals one! 🎉\n"
]
},
{
"data": {
"text/plain": [
"true"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"is_it_one(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3.3.2. For loops"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"2\n",
"3\n"
]
}
],
"source": [
"for n = [1, 2, 3]\n",
" println(n)\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a\n",
"b\n",
"c\n"
]
}
],
"source": [
"# `=` can be replaced with `in`\n",
"for c in ['a', 'b', 'c']\n",
" println(c)\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n"
]
}
],
"source": [
"for i in 1:6\n",
" println(i)\n",
"end\n",
"# what is this `1:6`?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_Range objects_"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1:15"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# a range object\n",
"range1 = 1:15"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"UnitRange{Int64}"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(range1)"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"true"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"10 in range1"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"10"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# accessing range elements by index\n",
"range1[10]"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-10\n",
"-7\n",
"-4\n",
"-1\n",
"2\n",
"5\n",
"8\n",
"11\n"
]
}
],
"source": [
"# range with step: `start:step:stop`\n",
"for i in -10:3:11\n",
" println(i)\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Arrays"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.1. Basics"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Array is the basic and very powerful Julia's collection type.\n",
"\n",
"Julia's Array syntax is inspired by Matlab."
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4-element Array{Int64,1}:\n",
" 1\n",
" 2\n",
" 3\n",
" 4"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array1 = [1, 2, 3, 4]"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Array{Int64,1}"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(array1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That means `array1` is a 1-dimentional array made of `Int64` elements."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`size`** function returns a Tuple of array's dimensions: "
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(4,)"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"size(array1)"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1×3 Array{Int64,2}:\n",
" 1 2 3"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array2 = [1 2 3]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`array2` is a 2-dimensional Array..."
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(1, 3)"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"size(array2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"... of the size 1x3, which means it has 1 row and 3 columns."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's create a 3x4 **2D Array**."
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×4 Array{Int64,2}:\n",
" 1 2 3 4\n",
" 5 6 7 8\n",
" 9 10 11 12"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3 = [\n",
" 1 2 3 4;\n",
" 5 6 7 8;\n",
" 9 10 11 12;\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3, 4)"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"size(array3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Mind that Julia's 2D Array is **not** an \"array of arrays\" (which is, by the way, also possible to create in Julia but it's, most of the times, is not what we want). Number of dimensions is a parameter of every particular Array's type."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's create a **3D Array**!"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3×3 Array{Float64,3}:\n",
"[:, :, 1] =\n",
" 0.0 0.0 0.0\n",
" 0.0 0.0 0.0\n",
" 0.0 0.0 0.0\n",
"\n",
"[:, :, 2] =\n",
" 0.0 0.0 0.0\n",
" 0.0 0.0 0.0\n",
" 0.0 0.0 0.0\n",
"\n",
"[:, :, 3] =\n",
" 0.0 0.0 0.0\n",
" 0.0 0.0 0.0\n",
" 0.0 0.0 0.0"
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array4 = zeros(3, 3, 3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"(**`zeros(s)`** function creates an Array filled with zeroes, in the shape of `s`)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So `array4` is a 3D Array, 3x3x3, filled with zeroes."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"4D Array?"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2×2×2×2 Array{Float64,4}:\n",
"[:, :, 1, 1] =\n",
" 1.0 1.0\n",
" 1.0 1.0\n",
"\n",
"[:, :, 2, 1] =\n",
" 1.0 1.0\n",
" 1.0 1.0\n",
"\n",
"[:, :, 1, 2] =\n",
" 1.0 1.0\n",
" 1.0 1.0\n",
"\n",
"[:, :, 2, 2] =\n",
" 1.0 1.0\n",
" 1.0 1.0"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array5 = ones(2, 2, 2, 2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"(**`ones(s)`** function creates an Array filled with ones, in the shape of `s`)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.2. Linear indexing of Arrays and iterating over them"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can index Arrays linearly:"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×4 Array{Int64,2}:\n",
" 1 2 3 4\n",
" 5 6 7 8\n",
" 9 10 11 12"
]
},
"execution_count": 70,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3[1]"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3[2]"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3[3]"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"12"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3[end]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In consequence, when we iterate over a 2D (or more-D) Array we just get its elements one at a time — no need to create nested loops (remember: 2D Array is not \"array of arrays\"!)."
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"5\n",
"9\n",
"2\n",
"6\n",
"10\n",
"3\n",
"7\n",
"11\n",
"4\n",
"8\n",
"12\n"
]
}
],
"source": [
"for element in array3\n",
" println(element)\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.3. Cartesian indexing "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But we can also use Cartesian indexing, which is indexing with Cartesian coordinates.\n",
"\n",
"This way we can access an element in a specific row and column with `[row, column]` syntax for a 2D Array, or more generally `[axis-1, axis-2, ..., axis-n]` for an n-dimensional Array. "
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×4 Array{Int64,2}:\n",
" 1 2 3 4\n",
" 5 6 7 8\n",
" 9 10 11 12"
]
},
"execution_count": 76,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2"
]
},
"execution_count": 77,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3[1, 2]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To get the whole dimension of the Array use `:`."
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4-element Array{Int64,1}:\n",
" 1\n",
" 2\n",
" 3\n",
" 4"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3[1, :]"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3-element Array{Int64,1}:\n",
" 2\n",
" 6\n",
" 10"
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array3[:, 2]"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3×3 Array{Int64,3}:\n",
"[:, :, 1] =\n",
" 1 4 7\n",
" 2 5 8\n",
" 3 6 9\n",
"\n",
"[:, :, 2] =\n",
" 10 13 16\n",
" 11 14 17\n",
" 12 15 18\n",
"\n",
"[:, :, 3] =\n",
" 19 22 25\n",
" 20 23 26\n",
" 21 24 27"
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6 = reshape(collect(1:27), 3, 3, 3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**`reshape(A, dims...)`** returns an Array containing the same data as A, but with different dimensions.\n",
"\n",
"**`collect(collection)`** returns an Array of all items in a collection or iterator."
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"16"
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6[1, 3, 2]"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3-element Array{Int64,1}:\n",
" 10\n",
" 11\n",
" 12"
]
},
"execution_count": 82,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6[:, 1, 2]"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3 Array{Int64,2}:\n",
" 10 13 16\n",
" 11 14 17\n",
" 12 15 18"
]
},
"execution_count": 83,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6[:, :, 2]"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3 Array{Int64,2}:\n",
" 1 10 19\n",
" 4 13 22\n",
" 7 16 25"
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6[1, :, :]"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3-element Array{Int64,1}:\n",
" 10\n",
" 13\n",
" 16"
]
},
"execution_count": 85,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6[1, :, 2]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.4. Slicing Arrays"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also select parts of Arrays using _range_."
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4×4 Array{Int64,2}:\n",
" 1 5 9 13\n",
" 2 6 10 14\n",
" 3 7 11 15\n",
" 4 8 12 16"
]
},
"execution_count": 86,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array7 = reshape(collect(1:16), 4, 4)"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2×2 Array{Int64,2}:\n",
" 1 5\n",
" 2 6"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array7[1:2, 1:2]"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2×3 Array{Int64,2}:\n",
" 2 6 10\n",
" 3 7 11"
]
},
"execution_count": 88,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array7[2:3, 1:3]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.5. Mutating Arrays"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Using linear indexing"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3×3 Array{Int64,3}:\n",
"[:, :, 1] =\n",
" 1 4 7\n",
" 2 5 8\n",
" 3 6 9\n",
"\n",
"[:, :, 2] =\n",
" 10 13 16\n",
" 11 14 17\n",
" 12 15 18\n",
"\n",
"[:, :, 3] =\n",
" 19 22 25\n",
" 20 23 26\n",
" 21 24 27"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9999"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6[4] = 9999"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3×3 Array{Int64,3}:\n",
"[:, :, 1] =\n",
" 1 9999 7\n",
" 2 5 8\n",
" 3 6 9\n",
"\n",
"[:, :, 2] =\n",
" 10 13 16\n",
" 11 14 17\n",
" 12 15 18\n",
"\n",
"[:, :, 3] =\n",
" 19 22 25\n",
" 20 23 26\n",
" 21 24 27"
]
},
"execution_count": 91,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Using Cartesian indexing"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_Single elements_"
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3×3 Array{Int64,3}:\n",
"[:, :, 1] =\n",
" 1 9999 7\n",
" 2 5 8\n",
" 3 6 9\n",
"\n",
"[:, :, 2] =\n",
" 10 13 16\n",
" 11 14 17\n",
" 12 15 18\n",
"\n",
"[:, :, 3] =\n",
" 19 22 25\n",
" 20 23 26\n",
" 21 24 27"
]
},
"execution_count": 92,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6"
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1111111"
]
},
"execution_count": 93,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6[1,2,3] = 1111111"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3×3 Array{Int64,3}:\n",
"[:, :, 1] =\n",
" 1 9999 7\n",
" 2 5 8\n",
" 3 6 9\n",
"\n",
"[:, :, 2] =\n",
" 10 13 16\n",
" 11 14 17\n",
" 12 15 18\n",
"\n",
"[:, :, 3] =\n",
" 19 1111111 25\n",
" 20 23 26\n",
" 21 24 27"
]
},
"execution_count": 94,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array6"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_Using slicing_"
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2×2 Array{Int64,2}:\n",
" 99 98\n",
" 97 96"
]
},
"execution_count": 95,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array7[1:2, 1:2] = [99 98; 97 96]"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4×4 Array{Int64,2}:\n",
" 99 98 9 13\n",
" 97 96 10 14\n",
" 3 7 11 15\n",
" 4 8 12 16"
]
},
"execution_count": 96,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array7"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.6. Array Comprehensions"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5-element Array{Int64,1}:\n",
" 1\n",
" 2\n",
" 3\n",
" 4\n",
" 5"
]
},
"execution_count": 97,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[n for n in 1:5]"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5×3 Array{Int64,2}:\n",
" 2 3 4\n",
" 3 4 5\n",
" 4 5 6\n",
" 5 6 7\n",
" 6 7 8"
]
},
"execution_count": 98,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[x+y for x in 1:5, y in 1:3]"
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3×5 Array{Tuple{Char,Char,Char},3}:\n",
"[:, :, 1] =\n",
" ('🔴', '🙈', '🙂') ('🔴', '🙊', '🙂') ('🔴', '🙉', '🙂')\n",
" ('🔵', '🙈', '🙂') ('🔵', '🙊', '🙂') ('🔵', '🙉', '🙂')\n",
" ('⚪', '🙈', '🙂') ('⚪', '🙊', '🙂') ('⚪', '🙉', '🙂')\n",
"\n",
"[:, :, 2] =\n",
" ('🔴', '🙈', '😬') ('🔴', '🙊', '😬') ('🔴', '🙉', '😬')\n",
" ('🔵', '🙈', '😬') ('🔵', '🙊', '😬') ('🔵', '🙉', '😬')\n",
" ('⚪', '🙈', '😬') ('⚪', '🙊', '😬') ('⚪', '🙉', '😬')\n",
"\n",
"[:, :, 3] =\n",
" ('🔴', '🙈', '😡') ('🔴', '🙊', '😡') ('🔴', '🙉', '😡')\n",
" ('🔵', '🙈', '😡') ('🔵', '🙊', '😡') ('🔵', '🙉', '😡')\n",
" ('⚪', '🙈', '😡') ('⚪', '🙊', '😡') ('⚪', '🙉', '😡')\n",
"\n",
"[:, :, 4] =\n",
" ('🔴', '🙈', '😂') ('🔴', '🙊', '😂') ('🔴', '🙉', '😂')\n",
" ('🔵', '🙈', '😂') ('🔵', '🙊', '😂') ('🔵', '🙉', '😂')\n",
" ('⚪', '🙈', '😂') ('⚪', '🙊', '😂') ('⚪', '🙉', '😂')\n",
"\n",
"[:, :, 5] =\n",
" ('🔴', '🙈', '😶') ('🔴', '🙊', '😶') ('🔴', '🙉', '😶')\n",
" ('🔵', '🙈', '😶') ('🔵', '🙊', '😶') ('🔵', '🙉', '😶')\n",
" ('⚪', '🙈', '😶') ('⚪', '🙊', '😶') ('⚪', '🙉', '😶')"
]
},
"execution_count": 99,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[(x,y,z)\n",
" for x = \"🔴🔵⚪\",\n",
" y = \"🙈🙊🙉\",\n",
" z = \"🙂😬😡😂😶\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. Calling Python code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Suppose we want to use Python's *requests* library in Julia. \n",
"\n",
"In Python using the library would look like this:\n",
"\n",
"```python\n",
"# Python code\n",
"In [1]: import requests\n",
"\n",
"In [2]: response = requests.get(\"http://httpbin.org/get\")\n",
"\n",
"In [3]: response.status_code\n",
"Out[3]: 200\n",
"\n",
"In [4]: response.headers\n",
"Out[4]: {'Connection': 'keep-alive', 'Server': 'meinheld/0.6.1', 'Date': 'Sat, 18 Nov 2017 19:51:47 GMT', 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true', 'X-Powered-By': 'Flask', 'X-Processed-Time': '0.000778198242188', 'Content-Length': '265', 'Via': '1.1 vegur'}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In Julia we can use **PyCall library**!"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {},
"outputs": [],
"source": [
"# Pkg.add(\"PyCall\")\n",
"using PyCall\n",
"@pyimport requests # given we have requests installed! "
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"PyObject <Response [200]>"
]
},
"execution_count": 101,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"response = requests.get(\"http://httpbin.org/get\")"
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {},
"outputs": [
{
"ename": "LoadError",
"evalue": "\u001b[91mtype PyObject has no field status_code\u001b[39m",
"output_type": "error",
"traceback": [
"\u001b[91mtype PyObject has no field status_code\u001b[39m",
"",
"Stacktrace:",
" [1] \u001b[1minclude_string\u001b[22m\u001b[22m\u001b[1m(\u001b[22m\u001b[22m::String, ::String\u001b[1m)\u001b[22m\u001b[22m at \u001b[1m./loading.jl:522\u001b[22m\u001b[22m"
]
}
],
"source": [
"response.status_code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But..."
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"200"
]
},
"execution_count": 103,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"response[:status_code]"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"PyObject {'Content-Length': '265', 'X-Processed-Time': '0.00068187713623', 'X-Powered-By': 'Flask', 'Server': 'meinheld/0.6.1', 'Connection': 'keep-alive', 'Via': '1.1 vegur', 'Access-Control-Allow-Credentials': 'true', 'Date': 'Thu, 23 Nov 2017 15:25:50 GMT', 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'}"
]
},
"execution_count": 104,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"response[:headers]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can even..."
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Dict{Any,Any} with 14 entries:\n",
" \"elapsed\" => 337 milliseconds\n",
" \"request\" => PyObject <PreparedRequest [GET]>\n",
" \"_content\" => \"{\\n \\\"args\\\": {}, \\n \\\"headers\\\": {\\n \\\"Accept\\\"…\n",
" \"status_code\" => 200\n",
" \"cookies\" => PyObject <RequestsCookieJar[]>\n",
" \"history\" => Any[]\n",
" \"encoding\" => nothing\n",
" \"reason\" => \"OK\"\n",
" \"_next\" => nothing\n",
" \"raw\" => PyObject <urllib3.response.HTTPResponse object at 0x12…\n",
" \"url\" => \"http://httpbin.org/get\"\n",
" \"_content_consumed\" => true\n",
" \"headers\" => PyObject {'Content-Length': '265', 'X-Processed-Time':…\n",
" \"connection\" => PyObject <requests.adapters.HTTPAdapter object at 0x12…"
]
},
"execution_count": 105,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"response[:__dict__]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## BONUS: Special characters in code\n",
"We can easily use LaTeX syntax to get special symbols, like:\n",
"\n",
"`\\phi` - ϕ\n",
"\n",
"`\\Sigma` - Σ\n",
"\n",
"`\\Delta` - Δ\n",
"\n",
"`\\pi` - π\n",
"\n",
"`\\equiv` - ≡\n",
"\n",
"Just type `\\name` and press `Tab`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can use these symbols as names:"
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {},
"outputs": [],
"source": [
"Σ = 1 + 2 + 3 + 4;\n",
"Δ = 100 - 101;"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"10"
]
},
"execution_count": 107,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Σ"
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"-1"
]
},
"execution_count": 108,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Δ"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Stay tuned for a talk(s) about Julia's type system and multiple dispatch!"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 0.6.1",
"language": "julia",
"name": "julia-0.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "0.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment