Me: Josh Bevan - jbevan@bu.edu
Helper: Katia Bulekova - ktrn@bu.edu
Get Help from RCS: help@scc.bu.edu
Our website: rcs.bu.edu
Tutorial eval: rcs.bu.edu/eval
This notebook: http://scv.bu.edu/examples/julia/Intro/
Julia seeks to solve the "two-language" problem. Fast: C, Fortran, etc. / Productive: Python, MATLAB, etc. You can get around this for specific tasks by using a domain specific language, or specialized libraries, but this is not generalizable to a general-purpose approach.
Not convinced? Here are a couple samples showing what I mean:
Julia is a high-level, high-performance, dynamic programming language. With a large and active community and several well-supported IDEs (e.g. Juno, VSCode, etc.)
A good way to introduce yourself to a new language is by trying to solve a "non-trivial" problem; learning the tools and syntax necessary to solve the problem along the way. This motivates the syntax/tools in a "why" versus "what" way!
You may need to setup an IJulia kernel to start a notebook in an existing Jupyter installation: for more info see here.
You will eventually want to run scripts developed in notebooks or at the REPL in a batch mode. You can easily do this by simply calling Julia with the script:
[...]$ julia my_script.jl
If you are working from an existing notebook, you can convert it to a script with:
jupyter nbconvert --to script my_notebook.ipynb
ProjectEuler is a good source of "starter" problems.
"If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000."
Pseudo-code:
1 "total" starts at 0
2 Run over all the numbers 1 to 999
3 Is the number a multiple of 3 or 5?
4 If yes, add to our cumulative sum "total"
5 Try the next number
Line 0: How do we do some basic stuff?
# You can leave single-line comments this way
#= You can
leave multi-line comments
this way =#
# A function optionally takes some input(s) and optionally has some output(s)
# it usually looks like:
# output = myfunctions(input)
println("An easy way to print things, like this!")
# You can use REPL behavior in a notebook, but this cell won't work
?println
This one does though $\downarrow$
?println
You can also use shell commands in the same way:
;pwd
1 "total" starts at 0
2 Run over all the numbers 1 to 999
3 Is the number a multiple of 3 or 5?
4 If yes, add to our cumulative sum "total"
5 Try the next number
Line 1: We need to be able to store "variables". It can also be useful to display variables/info:
# ============Let's play with variables to figure out line 1 =====
total = 0
total = 1
# Here we are using the equals sign "=" to indicate variable assignment
# Only the last assignment is echoed
# You can suppress the echo with a semicolon
total = 2;
total = total + 6
dull_number = 1729
typeof(dull_number)
my_pi = 3.14
typeof(my_pi)
# We can also save things other than numbers to a variable.
# Like a "string" of characters:
my_secret_password = "joshiscool"
typeof(my_secret_password)
Fun sidebar: You can do some neat or unexpected things with strings in Julia
a = "man"
b = "bear"
c = "pig"
string(a,b,c)
a+b+c
a*b*c
# Addition is commutative, but multiplication is not
# Exponentiation is just repeated multiplication
"spam "^100
1 "total" starts at 0
2 Run over all the numbers 1 to 999
3 Is the number a multiple of 3 or 5?
4 If yes, add to our cumulative sum "total"
5 Try the next number
Line 2: We'd like to do the same action over and over, but on varying inputs. This is called a loop; there are several kinds including a "for" loop. We do the actions inside the loop "for" each value that the loop variable takes on
# ======================= Now for line 2 =====================
start_num = 1;
end_num = 4;
for loop_variable in start_num : end_num
println(loop_variable)
end # Julia knows where the loop ends because we "end" the loop.
We can see how we'd use this to solve the problem: we'll loop over all the numbers 1 to 999. Within the loop we'll test to see if they are a multiple of 3 or 5 and if so add it to our "total" variable.
1 "total" starts at 0
2 Run over all the numbers 1 to 999
3 Is the number a multiple of 3 or 5?
4 If yes, add to our cumulative sum "total"
5 Try the next number
Line 3: How do we test if a number is a multiple? How do we take an action depending on some question (in this case if it is a multiple). Let's answer the second question first:
# ======================= Now for line 3 =====================
# Julia represents "true" as 1 and "false" as 0
obvious_fact = 10 > 1
println("Obvious fact is $obvious_fact")
obviously_wrong = 999 < 2
println("Obviously wrong is $obviously_wrong")
a = 10+2
b = 12
also_true = (a==b)
println("also true is $also_true")
# Here "=="re checking for equality, *not* doing variable assignment
# We can take conditional actions using an "if" statement
if a==b
println("I assure you a equals b")
elseif a>b
println("a is greater than b")
else
println("Sadly a doesn't equal b")
end # Just like a "for" loop, we need to "end" an if statement
# We can also combine logical statements
both_arent_true = obviously_wrong & obvious_fact # "and" statement
but_at_least_one_is_true = obviously_wrong | obvious_fact # "or" statement
a = 2 + 2
b = 1 + 3
if a==b
println("a equals b") # What do you expect here?
else
println("a doesn't equal b")
end
c = 0.15 + 0.15
d = 0.10 + 0.20
if c==d
println("c equals d") #What do you expect here?
else
println("c doesn't equal d")
end
println(a-b)
println(c-d)
println(abs(c-d))
println(eps(c))
if abs(c-d)<=1.5*eps(d)
println("c equals d, within floating point tolerance")
else
println("c doesn't equal d, within floating point tolerance")
end
bank_account =1.37
bank_account = bank_account + 10.00
bank_account = bank_account - 11.37
if bank_account == 0
println("Your current balance is: $bank_account")
println("Ooops")
else
println("Your current balance is: $bank_account")
println("Buy even more stuff!")
end
Floating point numbers have limited precision: https://en.wikipedia.org/wiki/Floating-point_arithmetic#Internal_representation
There are many pitfalls to working with floating point numbers: https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
So that answers the second question, but how do we test if something is a multiple? This is more a logic/math question than exclusively programming, but any non-trivial program will need you to figure things like this out. A number is a multiple of 3 if it is evenly divided by 3:
So our problem is now to test for divisibility. Let's cook up a couple ways:
quotient = 13/3
# Test for divisibility
# Way 1
quotient = 13/3
# Way 1: Is the quotient the same rounded or not?
rounded = round(quotient)
# We can round to the nearest whole number
is_multiple = rounded==quotient
println(is_multiple)
quotient = 12/3
rounded = round(quotient)
is_multiple = rounded==quotient
println(is_multiple)
# Can you think of a different way?
What other ways might we do this? Can we think of other functions to use?
# Alternate implementation here
n=41
divisible3 = iszero(mod(n,3))
divisible5 = iszero(mod(n,5))
if divisible3 | divisible5
println("Divisible by 3 or 5")
elseif divisible3 & ~divisible5
println("Divisible by only 3")
elseif ~divisible3 & divisible5
println("Divisible by only 5")
else
println("Not divisible by 3 or 5")
end
1 "total" starts at 0
2 Loop over all the numbers 1 to 999
3 Is the number a multiple of 3 or 5?
4 If yes, add to our cumulative sum "total"
5 Try the next number
This space left intentionally blank
#Total starts at 0
total=0
#Loop over all the numbers 1 to 999
for i = 1:999
#Is the number a multiple of 3 or 5?
divisibleBy3 = iszero(mod(i,3));
divisibleBy5 = iszero(mod(i,5));
if divisibleBy3 | divisibleBy5
#If yes, add to our cumulative sum
total = total + i;
end
#Try the next number
end
total
A = rand(1:10,3,3)
A.+3
broadcast(+,1:10,3)
test=1:10
test.+3
round(n/3)==(n/3) | round(n/5)==(n/5) | round(n/7)==(n/7) | round(n/11)==(n/11)
function test_divis(test,divisor)
round(test/divisor)==(test/divisor)
end
test_divis(13,3)
test_divis2(test,divisor) = round(test/divisor)==(test/divisor)
test_divis2(16,3)