Julia Introduction

by "Blag" - Developer Evangelist

Return to Geeky Thursday

What is Julia?


Julia is a high-level, high-performance dynamic programming language for technical computing.


It provides a sophisticated compiler, distributed parallel execution, numerical accuracy and an extensive mathematical function library.


Julia is free and Open Source.


It uses a High-Performance JIT Compiler which often matchs the performance of C.

How to install Julia?


Julia can be downloaded from here Julia

It can be installed on Windows, Linux and MacOS...but I would recommend Linux.

There's no "official" IDE but Julia Studio can be used.

Who uses Julia?


  • McAfee
  • Facebook
  • Capital One
  • IBM
  • Symantec
  • Disney

Starting out...


Once Julia is installed, we can simply call it from the terminal


Package Management

We can easily get new packages on Julia

For the complete list of available packages please go Here


Needed Packages...


Gadfly


DataFrames


CSV


Basic Concepts


One line comments are # and multiple lines comments are #= and =#.


Precedence must be enforced by parenthesis


				
2*3+5 

11


2*(3+5) 

16
				

Basic Concepts


Printing on the screen is easy...


				
text = "This is Julia!"

println(text) 

This is Julia!
				

Arrays are easy...


				
intArray = [1,2,3]

3-element Array{Int64,1}:

1

2

3				


stringArray = String["This","is","Julia!"]

3-element Array{String,1}:

"This"

"is"

"Julia!"
				

Multidimension Arrays are easy too...but the syntax is a little bit different...


				
multiArray = [1 2;3 4]

2x2 Array{Int64,2}:

1 2

3 4				
				

Some fun with Arrays...


				
a = [1,2,3]

3-element Array{Int64,1}:

1

2

3				


push!(a,4)

4-element Array{Int64,1}:

1

2

3

4
				
			
b = [5,6,7]

3-element Array{Int64,1}:

5

6

7			


c = append!(a,b)

7-element Array{Int64,1}:

1

2

3

4

5

6

7				
				
				
pop!(a)

4


a

6-element Array{Int64,1}:

1
 
2
 
3

4

5

6


a[0]

ERROR: BoundsError() 

#Array indices start on 1...weird!
				
				
a[1]

1


a[end]

6


c = popfirst!(a)

1


a

5-element Array{Int64,1}:

2

3

4

5

6
				
				
length(a)

5



4 in a

true


c = [1,2,2]

3-element Array{Int64,1}:

1

2

2


unique(c)

2-element Array{Int64,1}:

1

2
				

For loops iterate over iterables...


				
for language in ["Spanish","English","German"]
			
    println("$language")
    
end				


Spanish

English

German
				
				
for msg in Dict("Spanish"=>"Peru","English"=>"US",

                "German"=>"Germany")
            
    println("$(msg[1]) is spoken in $(msg[2])")
    
end            


English is spoken in US

German is spoken in Germany

Spanish is spoken in Peru
				
				
for (k,v) in Dict("Spanish"=>"Peru","English"=>"US",

                  "German"=>"Germany")
              
    println("$k is spoken in $v")
    
end


English is spoken in US

German is spoken in Germany

Spanish is spoken in Peru
				

Functions always return the last value


				
function concat(a,b)

    msg = a * " " * b
    
end    


concat (generic function with 1 method)


message = concat("Hello","Julia")


"Hello Julia"
				

Making an LED Number App


Finally...we're going to make our first application...


So grab your favorite text editor and get ready...


Name your file "LED_Numbers.jl"


				
leds =  Dict("0" => [" _  ","| | ","|_| "],

             "1" => ["  ","| ","| "],
					 
             "2" => [" _  "," _| ","|_  "],
				     
             "3" => ["_  ","_| ","_| "],
					 
             "4" => ["    ","|_| ","  | "],
					 
             "5" => [" _  ","|_  "," _| "],
				 
             "6" => [" _  ","|_  ","|_| "],
				     
             "7" => ["_   "," |  "," |  "],
					 
             "8" => [" _  ","|_| ","|_| "],
					 
             "9" => [" _  ","|_| "," _| "])
				
				
list = ""; line1 = ""; line2 = ""; line3 = "";


print("Enter a number: "); number = chomp(readline())

len = length(number)

for i in 1:len

	list = split(leds[string(number[i])],",")

	global line1 *= list[1]

	global line2 *= list[2]

	global line3 *= list[3]

end



println(line1)

println(line2)

println(line3 * "\n")
				

Open the Terminal and go to your source code folder...

julia "Name_of_File.jl"


When we run it we're going to see...


Random Names


This App will generate 100,000 random names using two 16 elements arrays


We will measure the runtime


Name your file "Random_Names.jl"


				
start = time()


names=["Anne","Gigi","Blag","Juergen","Marek","Ingo",

       "Lars","Julia", "Danielle","Rocky","Julien",
       
       "Uwe","Myles","Mike","Steven","Fanny"]


last_names=["Hardy","Read","Tejada","Schmerder",

            "Kowalkiewicz","Sauerzapf","Karg",
			
            "Satsuta","Keene","Ongkowidjojo",
            
            "Vayssiere","Kylau","Fenlon",
            
            "Flynn","Taylor","Tan"]            

            
full_names=AbstractString[]            
            

full_name = ""
				
				
for i = 1:100000

  full_name = names[rand(1:16)] * " " 
  
              * last_names[rand(1:16)]
  
  push!(full_names,full_name)
  
end


finish = time()


println("Time: ", finish-start)


println(length(full_names), " names generated")			
			

When we run it we're going to see...


How this behaves in Python?

Julia was faster this time!

Decimal to Romans


This App will create a Roman Numeral based on a decimal number


This will include some nice commands...


Name your file "Decimal_to_Roman.jl"


				

Roman_Table = Dict(1000=> "M", 900=> "CM", 500=> "D", 

               400=> "CD", 100=> "C", 90=> "XC", 
			   
               50=> "L", 40=> "XL", 10=> "X", 
			   
               9=> "IX", 5=> "V", 4=> "IV", 1=> "I")
			
				
function Roman_Number(number)

    result = ""
    
    key = sort(collect(keys(Roman_Table)),rev=true)
    
    while number > 0
    
        for value in key
        
            if number >= value
                            
                result *= Roman_Table[value]
                
                number -= value
                
                break
                
            end
            
        end

   end                

   return result
   
end   
			
				
print("Enter a number: "); 

number = chomp(readline())

result = Roman_Number(parse(Int,number))

println(result)				
				

When we run it we're going to see...


Data Science


Now that we might be more comfortable with Julia...we can do more useful stuff...

Julia can use a number of packages that help to manage Data Science situations...

The R Programming Language was the favorite for this job, but Julia is slowly gaining more ground...

While Julia might be slower than R in some aspects...when it's faster...it's way faster...

Name your file "Read_File.jl"


				
start = time()

using DataFrames

using CSV

isdefined(@__MODULE__,:Films) || 

(Films=CSV.read("Films_Table.csv",
				
                 header=true, nastrings=["","NA"]))
                      
println("Records before clean up: " 

        * string(nrow(Films)))

unique!(Films)

dropmissing!(Films,disallowmissing=true)

Films_Info=DataFrame(Movie_Id=Films[:Movie_Id],

                     Name=Films[:Movie_Name],
                     
                     Release_Date=
                     
                     Films[:Release_Date])
			
				
println("Records after clean up: " 
         
         * string(nrow(Films)))

sort!(Films_Info, cols=[:Release_Date])

CSV.write("Films_Info_Julia.csv", Films_Info)

finish = time()

println("Time: ", finish-start)

println("The file was generated successfully!")
			

When we run it we're going to see...

How this behaves in R?

Not bad Julia...not bad at all -;)

Keep in mind that Julia is loading two external packages...

Plotting


We all know (or at least we should know) that R can generate nice plot graphics...what about Julia?


Of course it can...


This example will use the file that we create in the previous example...


It will show the movies released by year...


Name your file "Plotting.jl"


				
using Gadfly

using DataFrames

isdefined(:Films)||
         
         (Films=readtable("Films_Info_Julia.csv",

          header=true, nastrings=["","NA"]))

Years = Dict{String,Int32}()

for film in Films[:Release_Date]

    try

       Years["$film"] += 1

    catch e              

       Years["$film"] = 1
       
    end
    
end				
				
							
years = {}

count = {}


for (k, v) in Years

    push!(years,k)

    push!(count,v)

end


df = DataFrame(Years=[parse(Int64,s) for s = years],

               Count=count)

        
plot(df,x="Years",y="Count")
				

For this one to work, we need to call from Julia itself...



Serving Web Pages


Yes, Julia can handle simple webpages using the HttpServer package.


But sadly...it's not available on the latest version of Julia -:(


But do not despair...I spend a lot of time searching for something nice...


Genie is kind of new but very promising -;)


For some reason you need to clone it...not install it...


							
using Pkg


Pkg.clone("https://github.com/essenciary/Genie.jl")
				

After that, we can call it like this...


							
using Genie
				

Our first application is simply going to ask for our name and display a greeting...


							
Genie.newapp("WebServer")
				

Once the app is created, open the file WebServer/config/routes.jl


				
using Genie.Router

using Genie.Renderer



route("/login") do

	html!(:home, :form)

end



route("/greet_me", method = POST, 

      named = :greet_me) do

	html!(:home, :greetings, name=@params(:name))

end
				

On the WebServer/app/resources create a new folder called home and inside a folder called views


Create a file called form.jl.html




<form action="$(Genie.Router.link_to(:greet_me))" 

         method="POST">

    <input type="text" name="name" 
	
     placeholder="Enter your name" />
<input type="submit" value="Greet Me!" /> </form>

Create a file called greetings.jl.html





<h1>Welcome to Julia, $(@vars(:name))!
				

Now, just go to http://localhost:8000/login on your favorite browser

When we provide a name and submit...

By the way...if you close your session and want to spin the webserver again...


Simply go to WebServer/



bin/server
				

And the webserver will start again -:)

Of course...that just plain simple...let's try something more interesting...


Name your project "WebServer_Fibonacci"

Once the app is created, open the file WebServer_Fibonacci/config/routes.jl


				
using Genie.Router

using Genie.Renderer

using fibocontroller


route("/fibo") do

	html!(:home, :form)

end


route("/getfibo", fibocontroller.getfibo, 

       method = POST, named = :getfibo_cont)
				

On the WebServer_Fibonacci/app/resources create a new folder called home and inside a folder called views


Create a file called form.jl.html

				


<form action="$(Genie.Router.link_to(:getfibo_cont))" 

      method="POST">

    <input type="text" name="num" 
    
           placeholder="Enter a number" />
<input type="submit" value="Calculate!" /> </form>

Create a file called fiboseq.jl.html

				


The fibonacci sequence is $(@vars(:res))

On the WebServer_Fibonacci/app/resources/home folder create a new file called fibocontroller.jl

				
module fibocontroller



    using Genie.Router

    using Genie.Renderer



    function getfibo()

        result = ""

        fib = 1

        first = 0

        second = 1
				
				
        for i in 1:parse(Int64,(@params(:num)))    

    	   result = result * " " * string(fib)

           fib = first + second

           first = second

           second = fib

        end

    

       html!(:home, :fiboseq, res = result)

    
    end

end
				

For this one to work, we need to run the file and then point to http://localhost:8000/fibo

When we provide a number and submit...

Is that all?


The Grumpy Cat is not impressed...


Well...he should be...


Julia is still a young language...


But it had an amazing growth and an incredible adoption rate...


As it's constantly evolving...some libraries will stop working but there's always a new library to replace the old one -;)


Contact Information


Blag --> blag@blagarts.com

@Blag on Twitter

Go back home...