Skip to content

Commit 11503ca

Browse files
committed
Course 3, session 3
1 parent 2705335 commit 11503ca

20 files changed

+875
-4
lines changed

_sessions/c3s3/1_arrays.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
title: Arrays
3+
---
4+
5+
An array is a way of storing a list of objects. Unlike in some other languages in ruby you don't need to specify which sort of object the array will hold - it can even hold objects of different types.
6+
7+
Arrays are written with square brackets.
8+
{% highlight ruby %}
9+
my_array = [1,2,3]
10+
11+
empty_array = [] # an array with no elements
12+
{% endhighlight %}
13+
14+
15+
{% exercise %}
16+
Working with a partner, guess what each of the following expressions will give, then try them out in `irb`:
17+
18+
{% highlight ruby %}
19+
a = [3, 39, 1, 0, 5]
20+
21+
a[1]
22+
a.first
23+
a[0]
24+
a[5]
25+
26+
a[-1]
27+
a[-5]
28+
a.last
29+
30+
a[1..3]
31+
a[1..-1]
32+
33+
b = []
34+
35+
a.empty?
36+
b.empty?
37+
a.length
38+
b.length
39+
40+
a.include?(39)
41+
a.include?(49)
42+
43+
a.reverse
44+
a # has this changed a?
45+
a.reverse!
46+
a # has this changed a?
47+
48+
a.sort
49+
a # has this changed a?
50+
a.sort!
51+
a # has this changed a?
52+
53+
a = [1, 2, 3, 4, 5]
54+
55+
a[3] = 6
56+
a # What is a now?
57+
58+
a[7] = 7
59+
a # What else has been added?
60+
61+
a << 9 # This one's important - you'll see it a lot
62+
63+
{% endhighlight %}
64+
{% endexercise %}

_sessions/c3s3/2_array_summary.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
title: Exercise summary
3+
---
4+
5+
Here are some things you learnt in the last exercise:
6+
7+
### Accessing elements
8+
9+
* Arrays start from 0, so that the first elements is `a[0]`
10+
* Arrays also allow indexing from the back, giving the last element as `a[-1]`
11+
* If try to access beyond the end of the array it gives `nil` (instead of an error in other languages)
12+
* You can access multiple elements by specifying a range, e.g. `a[1..-1]` is everything but the first element
13+
14+
### Array methods
15+
16+
Arrays have many useful (and largely self-explanatory) methods, including:
17+
18+
* `empty?` - does the array have any elements, or is it the empty array `[]`
19+
* `length`
20+
* `include?(x)` - is `x` in the array
21+
* `reverse`, `reverse!` - as with strings the `!` permanenty changes the array
22+
23+
### Adding to an array
24+
25+
* You can add to an array by setting a given element explicitly `a[5] = 6`
26+
* If the array isn't long enough the gaps are filled with `nil`:
27+
28+
a = [1, 2]
29+
a[6] = 5
30+
a #=> [1, 2, nil, nil, nil, nil, 5]
31+
32+
* You can also add to the end of an array by doing `a << 5`. This is very 'rubyish' and you'll see it a lot.

_sessions/c3s3/3_iteration.md

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: Iteration
3+
---
4+
5+
Most programming language have some way of looping, or iterating, over a range of values.
6+
7+
Ruby's approach to this is slightly unusual - instead of you taking elements from the array one-by-one, the ruby array *gives* the elements to you one-by-one. This might seem like a small distinction to make, but it has a significant effect on the feel of the ruby language and how you think about coding with it.
8+
9+
The way you get an array to give you its elements is by calling its `each` method:
10+
11+
{% highlight ruby %}
12+
array = [1, 2, 3, 4, 5]
13+
sum = 0
14+
15+
array.each do |n|
16+
sum = sum + n
17+
end
18+
19+
sum #=> 15
20+
{% endhighlight %}
21+
22+
The `each` method accepts a **block** - in the example above, this is everything between `do ... end`.
23+
24+
* The `each` method sends the elements of the array one-by-one to the block.
25+
* When the element arrives it is assigned to the variable `n`.
26+
* The code on the inside of the block is then run.
27+
28+
In the example above, each element is added to the `sum`. The example shows one method that you can use to sum the values in an array.
29+
30+
Below is another example, which iterates over the elements of an array, separating them into one of two lists:
31+
32+
{% highlight ruby %}
33+
all_words = ['hello', 'how', 'are', 'you', 'today']
34+
long_words = []
35+
short_words = []
36+
37+
all_words.each do |word|
38+
if word.length >= 5
39+
long_words << word
40+
else
41+
short_words << word
42+
end
43+
end
44+
45+
long_words #=> ['hello', 'today']
46+
short_words #=> ['how', 'are', 'you']
47+
{% endhighlight %}
48+
49+
<small>Please note: the summing and categorising examples above can be made much neater with the use of the array methods `inject` and `select`. We'll leave that for another day though ...</small>
50+
51+
{% exercise %}
52+
Take another look through the code examples above. Check you really understand how they work. Try them out in `irb`, to check they work as advertised!
53+
{% endexercise %}
54+

_sessions/c3s3/4_displaying_lists.md

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
title: Lists of data
3+
---
4+
5+
So far we have only inserted single values and words into an already existing `erb` template. We will now look at using ruby to generate more of the template dynamically.
6+
7+
Suppose you have a ruby array that you want to turn into an html list:
8+
9+
{%highlight ruby%}
10+
# in app.rb
11+
12+
get '/fruit' do
13+
@fruits = ["Bananas", "Apples", "Raspberries"]
14+
erb :fruits_view
15+
end
16+
{% endhighlight %}
17+
18+
We can do this by using the `@fruits` array's `each` method to iterate over the elements and put them into the page one-by-one.
19+
20+
{% highlight html %}
21+
<!-- in views/fruits_view.erb -->
22+
<ul>
23+
<% @fruits.each do |fruit| %>
24+
<li><%= fruit %></li>
25+
<% end %>
26+
</ul>
27+
{% endhighlight %}
28+
29+
You might notice that we've used a different type of erb tag for the `do ... end` block: `<% %>` instead of `<%= %>`. This is really important:
30+
31+
* You need to use `<%= %>` if you want the result of executing that line of ruby to be added to the page.
32+
* You need to use `<% %>` if you don't want the result of executing that line of ruby to be added to the page.
33+
34+
Here, the bits we want adding are the elements of the array, so only they have the `<%= %>` tags. The code will cause the following html to be generated:
35+
36+
{% highlight html %}
37+
<ul>
38+
<li>Bananas</li>
39+
<li>Apples</li>
40+
<li>Raspberries</li>
41+
</ul>
42+
{% endhighlight %}
43+
44+
You can also use the same technique to generate tables and other html (lists of divs etc.).
45+
46+
{% exercise %}
47+
1. **Fork, then clone** the code for this exercise [https://github.com/code61/sinatra_c3s3](https://github.com/code61/sinatra_c3s3).
48+
2. Add the code to the body of `todo.erb`, so that the `@todos` display as an ordered list.
49+
3. Add, commit and push your code to Github.
50+
3. Add the code to the body of `schedule.erb`, so that the items in the `@schedule` display as rows in a table. Note that `@schedule` is an *array of arrays* - you'll need to iterate over the first array, and within the loop use the normal ways of accessing elements of an array pull out the items.
51+
3. Add, commit and push your code to Github.
52+
4. Take a look at the `get '/rsvps'` block. Try the `CSV.read` bit in irb, to see what it does. Have a go at writing the code to categorise rsvps into acceptances/rejections and count them.
53+
5. Update the `rsvps.erb` view, so that the right information is displayed.
54+
3. Add, commit and push your code to Github.
55+
{% endexercise %}

_sessions/c3s3/5_sinatra_static.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: Sinatra static assets
3+
---
4+
5+
Last week we linked Twitter Bootstrap into your view templates, by linking to the online hosted version `<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css">`. What if we want to link to our own files?
6+
7+
When we were building static sites, this was simple: we just created a `main.css` file in our site folder, and linked to it. The problem is that **a sinatra site folder is not like a static site folder**. We've already seen this: `app.rb` controls the url structure, not the folders in the app folder. (Just try going to '/app.rb' or '/views/index.erb'). Because of this, just dropping a `main.css` into the sinatra folder and trying to link to it won't work.
8+
9+
Thankfully sinatra has a solution to this problem: if you create a folder called `public`, any files you put in there will be available from the root url. For example, if I have a file `public/main.css`, I can then link to this from my template files using `<link rel="stylesheet" href="/main.css">`. The two important things to note here are:
10+
11+
1. I'm using a root-relative link (starting with a `/`). If you don't do this, you'll have problems if you ever call that template from a different url route.
12+
2. I'm linking directly to `main.css`, **not** to `public/main.css`.
13+
14+
<div class="panel panel-primary">
15+
<div class="panel-heading">
16+
<h3 class="panel-title">Sinatra conventions</h3>
17+
</div>
18+
<div class='panel-body'>
19+
<ol>
20+
<li>Files inside the <code>public</code> folder will be served at the root of the site. This is where you should put your own stylesheets/images etc.</li>
21+
<li>You call a template with the line <code>erb :template_name</code>.</li>
22+
<li>For this to work, you will need a template called <code>template_name.erb</code> in the <code>views</code> folder.</li>
23+
<li>Instance variables (ones that start with <code>@</code>) will be shared with the template.</li>
24+
<li>You use these shared instance variables in the template by putting them inside an erb tag: <code>&lt;%= @my_variable &gt;</code> </li>
25+
</ol>
26+
</div>
27+
</div>
28+
29+
{% exercise %}
30+
1. Link the bootstrap stylesheet you'll find in `public/dist/css/bootstrap.css` into the `head` of `todo.erb` and `schedule.erb`.
31+
{% endexercise %}

_sessions/c3s3/6_layout_files.md

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
---
2+
title: Sinatra layouts
3+
---
4+
5+
One of the most important principles in software engineering is to stay [DRY](http://en.wikipedia.org/wiki/Don't_repeat_yourself): **don't repeat yourself**.
6+
7+
The basic idea is that you don't want to be copying and pasting the same code into multiple places. If you're doing this, you're making a lot of work for yourself should you ever decide to change that code.
8+
9+
One way of staying DRY that we'll meet soon is writing functions: if there's a task that you do repeatedly, write a function to put the logic for that task in one place and then call the function when you need to do the task.
10+
11+
Another way, that we'll be looking at today, is in the form of layouts.
12+
13+
### The Problem
14+
15+
In the exercise today, you've been using a lot of erb view templates. You have 4 different templates, which all share the same basic outline:
16+
17+
{% highlight html %}
18+
<!-- in views/index.erb -->
19+
<!DOCTYPE html>
20+
<html>
21+
<head>
22+
<title>Event Manager 2.0</title>
23+
</head>
24+
<body>
25+
26+
<h1>Picture Unveiling Evening - Event Managment</h1>
27+
28+
<ul>
29+
<li><a href='/todos'>Todo list</a></li>
30+
<li><a href='/schedule'>Event schedule</a></li>
31+
<li><a href='/rsvps'>RSVPs</a></li>
32+
</ul>
33+
34+
</body>
35+
</html>
36+
{% endhighlight %}
37+
38+
{% highlight html %}
39+
<!-- in views/todo.erb -->
40+
<!DOCTYPE html>
41+
<html>
42+
<head>
43+
<title>Event Manager 2.0</title>
44+
</head>
45+
<body>
46+
<h1>Todo list</h1>
47+
48+
<ul>
49+
<% @todos.each do |todo| %>
50+
<li><%= todo %></li>
51+
<% end %>
52+
</ul>
53+
54+
</body>
55+
</html>
56+
{% endhighlight %}
57+
58+
These files are almost the same - a lot of copy and paste has gone on.
59+
60+
### The solution
61+
62+
Sinatra gets round this problem by allowing you to have a `layout.erb` file in your `views` folder:
63+
64+
{% highlight html %}
65+
<!-- views/layout.erb -->
66+
<!DOCTYPE html>
67+
<html>
68+
<head>
69+
<title>Event Manager 2.0</title>
70+
</head>
71+
<body>
72+
73+
<%= yield %>
74+
75+
</body>
76+
</html>
77+
{% endhighlight %}
78+
79+
You can then write only the bits that change in the other two views:
80+
81+
{% highlight html %}
82+
<!-- in views/index.erb -->
83+
<h1>Picture Unveiling Evening - Event Managment</h1>
84+
85+
<ul>
86+
<li><a href='/todos'>Todo list</a></li>
87+
<li><a href='/schedule'>Event schedule</a></li>
88+
<li><a href='/rsvps'>RSVPs</a></li>
89+
</ul>
90+
{% endhighlight %}
91+
92+
{% highlight html %}
93+
<!-- in views/todo.erb -->
94+
<h1>Todo list</h1>
95+
96+
<ul>
97+
<% @todos.each do |todo| %>
98+
<li><%= todo %></li>
99+
<% end %>
100+
</ul>
101+
{% endhighlight %}
102+
103+
Sinatra knows that if you have a file called `layout.erb` it should use that as a layout. If you call `erb :index`:
104+
105+
* It takes the `layout.erb` file.
106+
* It finds the bit where it says `<%= yield %>`.
107+
* It inserts `index.erb` at that point.
108+
109+
You can find more about Sinatra layouts on [the internet](http://lmgtfy.com/?q=sinatra+layouts).
110+
111+
112+
<div class="panel panel-primary">
113+
<div class="panel-heading">
114+
<h3 class="panel-title">Sinatra conventions</h3>
115+
</div>
116+
<div class='panel-body'>
117+
<ol>
118+
<li>If you have a file <code>views/layout.erb</code> Sinatra will treat it as a layout file: whenever it renders another template, it will try and insert the output into the <code>&lt;%= yield %&gt;</code> part of the layout file.</li>
119+
<li>Files inside the <code>public</code> folder will be served at the root of the site. This is where you should put your own stylesheets/images etc.</li>
120+
<li>You call a template with the line <code>erb :template_name</code>.</li>
121+
<li>For this to work, you will need a template called <code>template_name.erb</code> in the <code>views</code> folder.</li>
122+
<li>Instance variables (ones that start with <code>@</code>) will be shared with the template.</li>
123+
<li>You use these shared instance variables in the template by putting them inside an erb tag: <code>&lt;%= @my_variable %&gt;</code> </li>
124+
</ol>
125+
</div>
126+
</div>
127+
128+
{% exercise %}
129+
*Refactor* your views:
130+
131+
1. Create a layout file, containing the shared material from each view.
132+
2. Remove the shared material from each view.
133+
3. Check that the screens still look the same!
134+
{% endexercise %}

_sessions/c3s3/7_homework.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: Homework
3+
---
4+
5+
6+
{% exercise %}
7+
1. Finish the final exercise from class. If you have time, try and make the app look a bit nicer and practice deploying to heroku.
8+
2. Do the [Codecademy Ruby track](http://www.codecademy.com/tracks/ruby) Sections 5 and 6.
9+
{% endexercise %}

_sessions/c3s3/info.yml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
title: Web Programming with Ruby 3
2+
strapline: Arrays

0 commit comments

Comments
 (0)