# Crystal Introduction

### by "Blag" - Senior Developer Evangelist ## Who uses Crystal?

### Even though Crystal is an alpha mode...there are companies using it in production

• Diploid - Human genome interpretation
• NeuraLegion - Machine Learning powered advance protocal fuzzer
• Neopoly GmbH - Online games and services
• Appmonit - Analytics engine
• Blitline - Online image processing
• Manas - Unconventional software for unconventional needs

## Package Management

### Then adding the library information like this...

```				```
dependencies:

toml:

github: manastech/crystal-toml

branch: master
``````

## Basic Concepts

### And only one line comments are allowed...

```				```
puts "This is Crystal!"

#This is a Crystal comment
``````

### Arrays are easy...

```				```
numArray = [1, 2, 3]

puts numArray

#[1, 2, 3]

strArray = %w(this is Crystal)

puts strArray

#["this", "is", "Crystal"]
``````

### Multidimension Arrays are easy too...

```				```
numArray = [[1, 2],[ 3, 4]]

puts numArray

#1

puts numArray

#3

``````

### Some fun with Arrays...

```				```
numArray = [1, 2, 3, 4]

numArray.push(5)

puts numArray # [1, 2, 3, 4, 5]

numArray.pop

puts numArray # [1, 2, 3, 4]

a = [1, 2]

b = [3, 4]

a.concat(b)

puts a # [1, 2, 3, 4]

puts numArray.first # 1

puts numArray.last # 4
``````
```			```
numArray = [1, 2 ,3, 4]

puts numArray.shuffle() # [2, 3, 1, 4]

numArray.map! {|x| x * x}

puts numArray # [1, 4, 9, 16]

numArray.reverse!

puts numArray # [16, 9, 4, 1]

numArray = [[1, 2], [3, 4]] # [1, 2, 3, 4]

puts numArray.flatten
``````

### We can iterate on Arrays and Hashes...For doesn't exit

```				```
lang = ["Spanish","English","German"]

lang.each { |x| puts x }

#Spanish

#English

#German
``````
```				```
lang = {"Spanish" => "Peru",

"English" => "US",

"German" => "Germany"}

lang.each_key{|x| puts "#{x} is spoken in #{lang[x]}"}

#Spanish is spoken in Peru

#English is spoken in US

#German is spoken in Germany
``````

## Functions

### Functions always return the last value

```				```
def concat(a : String, b : String): String

a + " " + b

end

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

puts message # Hello Crystal
``````

## Classes

### In Crystal, everything is an object

• It has a type

• It can respond to some methods
```				```
class Person

property age

def initialize(name : String)

@name = name

@age = 0

end

def name

@name

end

def age

@age

end
``````
```				```
def become_older(by = 1)

@age += by

end

end

blag = Person.new "Blag"

blag.age = 40

puts blag.name # Blag

puts blag.age # 40

blag.become_older

puts blag.age # 41

blag.become_older 5

puts blag.age # 46
``````

## Fibonacci List

### Name your file "fibonacci.cr"

```				```
def fib(num : Int32, a : Int32, b : Int32) : String

result = ""

if a > 0 && num > 1

result = result + " " + (a + b).to_s +

fib(num - 1, a + b, a)

elsif a == 0

result = a.to_s + " " + b.to_s + " " +

(a + b).to_s + fib(num - 1, a + b, b)

end

return result

end

print "Enter a number: "

num = gets.as(String).strip.to_i

puts(fib(num, 0, 1))
``````

## Making an LED Number App

### Name your file "LED_Numbers.cr"

```				```
leds = {0 => [" _  ","| | ","|_| "],

1 => ["  ","| ","| "],

2 => [" _  "," _| ","|_  "],

3 => ["_  ","_| ","_| "],

4 => ["    ","|_| ","  | "],

5 => [" _  ","|_  "," _| "],

6 => [" _  ","|_  ","|_| "],

7 => ["_   "," |  "," |  "],

8 => [" _  ","|_| ","|_| "],

9 => [" _  ","|_| "," _| "]}
``````
```				```
print "Enter a number: "

num = gets.as(String).strip

i = 0

loop do

j = 0

loop do

print leds[num[j].to_i][i]

break if j == num.size - 1

j += 1

end

puts ""

break if i == 2

i += 1

end
``````

## Random Names

### Name your file "Random_Names.cr"

```				```
start = Time.now

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 = [] of String
``````
```				```
i = 0

loop do

full_names.insert(0, names[Random.rand(16)] + " " +

last_names[Random.rand(16)])

break if i == 99999

i += 1

end

puts Time.now - start
``````

## Decimal to Romans

### Name your file "Decimal_to_Roman.cr"

```				```
Roman_Table = {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"}
``````
```				```
def roman_number(number : Int32): String

result = ""

while number > 0

Roman_Table.each_key{|x|

if number >= x

result += Roman_Table[x]

number -= x

break

end }

end

return result

end
``````
```				```
print "Enter a number: "

num = gets.as(String).strip.to_i

puts roman_number(num)
``````

## Count Letters

### "This is a text file that we're going to read it using Crystal"

```				```
line = File.read("readme.txt").strip

counter = {} of String => Int32

line.each_char{|x|

if counter.has_key?(x.to_s)

counter[x.to_s] += 1

else

counter = counter.merge({x.to_s => 1})

end }

counter.each do |key, value|

puts "#{key} => #{value}"

end
``````

## Kemal - Web Framework

### Open the generated shard.yml

```				```
name: fibonacci

version: 0.1.0

authors:

-  <a.tejada.galindo@sap.com>

targets:

fibonacci:

main: src/fibonacci.cr

crystal: 0.23.1

license: MIT

dependencies:

kemal:

github: kemalcr/kemal
``````

### Now open fibonacci.cr and copy the following code...

```				```
require "kemal"

def fib(num : Int32, a : Int32, b : Int32) : String

result = ""

if a > 0 && num > 1

result = result + " " + (a + b).to_s +

fib(num - 1, a + b, a)

elsif a == 0

result = a.to_s + " " + b.to_s + " " +

(a + b).to_s + fib(num - 1, a + b, b)

end

return result

end
``````
```				```
get "/" do

render "views/index.ecr"

end

post "/getfibo" do |env|

num = env.params.body["num"]

result = fib(num.to_i, 0, 1)

render "views/getfibo.ecr"

end

Kemal.run
``````

### Create two files one called "index.ecr" and the other one "getfibo.ecr"

```				```
<!doctype html>

<html>

<head>

<title>Fibonacci List</title>

</head>

<body>

<form action="getfibo" method="post">

<input name='num' placeholder='Enter a number' />

<input type="submit" value="Send">

</form>

</body>

</html>
``````
```				```
<!doctype html>

<html>

<head>

<title>Fibonacci List</title>

</head>

<body>

<h3>The fibonacci sequence is: <%= result %></h3>

<a href="/">Go back<a/>

</body>

</html>

``````

## 2D fun with CrSFML

### Finally create a shard.yml and pass the following...

```				```
dependencies:

crsfml:

github: oprypin/crsfml

version: 2.4.10
``````

### ldconfig

```				```
require "crsfml"

window = SF::RenderWindow.new(SF::VideoMode.new(538,

300), "Nyan Cat!")

left_right = 0

up_down = 50

clock = SF::Clock.new

while window.open?

while event = window.poll_event

if event.is_a? SF::Event::Closed

window.close

end

end
``````
```				```
texture = SF::Texture.from_file("NyanCat.png")

texture.smooth = false

sprite = SF::Sprite.new(texture)

sprite.position = SF.vector2(left_right, up_down)

if SF::Keyboard.key_pressed?(SF::Keyboard::Escape)

window.close();

elsif SF::Keyboard.key_pressed?(SF::Keyboard::Left)

if left_right > 0

left_right -= 1

end

elsif SF::Keyboard.key_pressed?(SF::Keyboard::Right)

if left_right < 400

left_right += 1

end
``````
```				```
elsif SF::Keyboard.key_pressed?(SF::Keyboard::Up)

if up_down > 0

up_down -= 1

end

elsif SF::Keyboard.key_pressed?(SF::Keyboard::Down)

if up_down < 220

up_down += 1

end

end
``````
```				```
window.clear(SF::Color.new(64,64,64, 255))

sprite.position = SF.vector2(left_right, up_down)

window.draw(sprite)

window.display

end
``````