SlideShare una empresa de Scribd logo
1 de 239
Edgar J. Suarez
   http://rails.mx
Ruby
1993
Yukihiro Matsumoto
...computer engineers, focus on the machines. They think, "By
    doing this, the machine will run faster. By doing this, the
   machine will run more effectively..." They are focusing on
  machines. But in fact we need to focus on humans, on how
           humans care about doing programming...

          We are the masters. They are the slaves.
"I hope to see Ruby help every programmer
 in the world to be productive, and to enjoy
 programming, and to be happy. That is the
     primary purpose of Ruby language."
Perl + Smalltalk + Eiffel + Lisp
Dynamic Typing
x = 1
x = "hoge"
x = Class
Duck typing
"When I see a bird that walks like a duck
 and swims like a duck and quacks like a
      duck, I call that bird a duck."
Readable
(human friendly)
3.times do |i|
  puts "Now i is #{i}"
end

@user.is_admin?

@transaction.complete!
Flexible syntax
say_hello()
say_hello

multiply(3, 2)
multiply 3, 2
Reflexive
(metaprogramming)
a = "by_name"

eval <<-eos
  def find_#{a}(name)
    puts "finding by name"
  end
eos

find_by_name("edgar") # => "finding by name"
Iterators / blocks
5.times do
  puts "Hello"
end

['ruby', 'rocks'].each do |word|
  puts word
end

1.upto(3) do |i|
  puts i
end
Exception handling
begin
  this_line.could_throw_an_exception!
rescue Exception => e
  puts "Exception rescued: #{e}"
end
Object oriented
person.say_hi

3.to_s

"a string".capitalize

[].empty?

nil.class # => NilClass
Data types
3.class                      #   =>   Fixnum
4.24.class                   #   =>   Float
"Campus".class               #   =>   String
[1, 2, 3, 4].class           #   =>   Array
(10..15).class               #   =>   Range
:name.class                  #   =>   Symbol
{ :name => "Maria" }.class   #   =>   Hash
Symbols
"name".object_id # => 2156968560
"name".object_id # => 2156964240

:name.object_id # => 68828
:name.object_id # => 68828
Hashes
{
    "name" => "John",
    2      => 54,
    true   => "(345) 434-554"
}
{
    :name => "John",
    :age   => 54,
    :phone => "(345) 434-554"
}
Automatic Garbage
    Collection
Boolean coercion
(everything is true except false and nil)
Open classes
class Person
  def walk
    "walking..."
  end
end

juan = Person.new
juan.walk # => "walking..."

class Person
  def eat
    "eating..."
  end
end

juan.eat # => "eating..."
Default arguments
def multiply(a, b = 2)
  a * b
end

multiply 3, 4 # => 12

multiply 4 # => 8
Splat arguments
def menu_list(*args)
  options = args.pop
  args.each do |arg|
    puts "<a href='#' style='#{options[:style]}'>#{arg}</a>"
  end
end

menu_list   :home, :about, :contact, {:style => "color: green;"}
  # => <a   href=’#’ style=’color: green;’>home</a>
  # => <a   href=’#’ style=’color: green;’>about</a>
  # => <a   href=’#’ style=’color: green;’>contact</a>

menu_list :home, :about, {:style => "color: green;"}
  # => <a href=’#’ style=’color: green;’>home</a>
  # => <a href=’#’ style=’color: green;’>about</a>
Attributes
class Person

  def name=(name)
    @name = name
  end

  def name
    @name
  end

end

a = Person.new
a.name = "Pepe"
a.name # => Pepe
class Person

  attr_accessor :name
  attr_reader   :age
  attr_writer   :phone

end
“Class” methods
class Number
  def self.sum(a, b)
    a + b
  end

  def Number.pow(a, b)
    a ** b
  end
end

Number.sum(2, 2) # => 4
Number.pow(4, 2) # => 16
Self
class Number
  def self.base
    10
  end

  def self.parse(str)
    str.to_i(self.base)
  end
end

Number.parse("30") # => 30
class Person
  attr_accessor :first_name, :last_name

  def full_name
    "#{self.first_name} #{self.last_name}"
  end
end

raul = Person.new
raul.first_name = "Raul"
raul.last_name = "Mendez"
raul.full_name # => Raul Mendez
Inheritance
class Shape
  def area
    @a * @b
  end
end

class Square < Shape
end

sq = Square.new
sq.area
class Shape
  def area
    @a * @b
  end
end

class Square < Shape
  def area
    if @a == @b
      @a * @a
    else
      super
    end
  end
end

sq = Square.new
sq.area
Mixins
module Walkable
  def walk
    puts "I'm walking"
  end
end

module Runnable
  def run
    puts "I'm running"
  end
end

class Person
  include Walkable
  include Runnable
end

joe = Person.new
joe.walk # => I'm walking
joe.run # => I'm running
module Summable
  def sum(a, b)
    a + b
  end
end

class Number
  extend Summable
end

Number.sum 2, 4 # => 6
Namespaces
module ActiveRecord
  class Base

  end
end

ActiveRecord::Base.new
Blocks
3.times do
  puts "hey"
end

3.times { puts "hey" }
3.times do
  puts "hey"
end

class Fixnum

  def times
    i = 0
    while i < self
      yield
      i += 1
    end
  end

end
3.times do
  puts "hey"
end

class Fixnum

  def times(&block)
    i = 0
    while i < self
      block.call
      i += 1
    end
  end

end
3.times do           3.times do
  puts "hey"           puts "hey"
end                  end

class Fixnum         class Fixnum

  def times            def times(&block)
    i = 0                i = 0
    while i < self       while i < self
      yield                block.call
      i += 1               i += 1
    end                  end
  end                  end

end                  end
3.times do |i|
  puts i
end

class Fixnum

  def times
    i = 0
    while i < self
      yield(i)
      i += 1
    end
  end

end
Gems
http://rubygems.org/
$ gem install rails
$ gem list
$ gem uninstall bundler
Implementations
• MRI (Matz)
• JRuby (java)
• Rubinius (Ruby)
• IronRuby (.NET)
• MacRuby (Cocoa)
• REE (Enterprise Edition)
Versions
1.8.7
1.9.2
Installation
Windows
Ruby Installer - http://j.mp/rubywindows
Linux / Mac
 RVM - http://j.mp/installrvm
Live CD
Ubuntu - http://j.mp/railsmxlivecd
Ruby on Rails
July 2004
David Heinemeier
    Hansson
     @ 37signals
$ rails new isshoni -d mysql
+-isshoni/
  +-app/
  +-config/
  +-db/
  +-public/
Bundler
$ gem install bundler
Gemfile
source 'http://rubygems.org'

gem 'rails', '3.0.9'
gem 'mysql2', '0.2.7'
$ bundle install
MVC
+-isshoni/
  +-app/
  | +-controllers/
  | +-models/
  | +-views/
  +-config/
  +-db/
  +-public/
Models
ORM
ActiveRecord
Database
+-isshoni/
  +-app/
  +-config/
  | +-database.yml
  +-db/
  +-public/
login: &login
  adapter: mysql2
  encoding: utf8
  username: root
  password:

development:
  <<: *login
  database: isshoni_development

test:
  <<: *login
  database: isshoni_test

production:
 <<: *login
  database: isshoni_production
$ rails g model User name:string email:string
+-isshoni/
  +-app/
  | +-models/
  | | +-user.rb
  +-config/
  +-db/
  | +-migrate/
  | | +-201107211030001_create_users.rb
  +-public/
class User < ActiveRecord::Base
end
class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string :name
      t.string :email
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end
$ rails g model Profile user_id:integer about:text
+-isshoni/
  +-app/
  | +-models/
  | | +-user.rb
  | | +-profile.rb
  +-config/
  +-db/
  | +-migrate/
  | | +-201107211030001_create_users.rb
  | | +-201107211035002_create_profiles.rb
  +-public/
class Profile < ActiveRecord::Base
end
class CreateProfiles < ActiveRecord::Migration
  def self.up
    create_table :profiles do |t|
      t.integer :user_id
      t.text :about
      t.timestamps
    end
  end

  def self.down
    drop_table :profiles
  end
end
Migrations
$   rake   db:create
$   rake   db:migrate
$   rake   db:rollback
$   rake   db:drop
Associations
has_one
class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy
end
@user = User.new
@user.profile = Profile.new
@user.profile.about = “Me”
belongs_to
class Profile < ActiveRecord::Base
  belongs_to :user
end
@profile.user # => #<User id:1>
has_many
class User < ActiveRecord::Base
  has_many :addresses
end
@user.addresses = []
@user.addresses.push(Address.new)
Persistence
@user = User.new
@user.save

@user = User.create
@user = User.new
@user.new_record? # => true

@user.save

@user.new_record? # => false
@user = User.create
@user.new_record? # => false
@user = User.new(:name => “Raj”)
@user.save
@user.name # => Raj

@user = User.create(:name => “Penny”)
@user.name # => Penny
Callbacks
class User < ActiveRecord::Base

  before_create :set_profile

  private

  def set_profile
    self.profile = Profile.new
  end

end
@user = User.new
@user.save

@user.profile # => <#Profile id: 1, about: nil>
Validations
class User < ActiveRecord::Base

  validates_presence_of :email
  validates_uniqueness_of :email

end
@user = User.new
@user.save # => false

@user.valid? # => false

@user.errors # => { :email => [“Can’t be blank”] }

@user.email = “foo@bar.com”
@user.save # => true
Finders / Arel / SQL
@user = User.find(3)
# => SELECT * FROM users WHERE id = 3;

@user = User.find_by_name(“Joe”)
# => SELECT * FROM users WHERE name = ‘Joe’ LIMIT 1;

@user = User.first
# => SELECT * FROM users LIMIT 1;
@users = User.all
# => SELECT * FROM users;

@users = User.where(:name => “John”)
# => SELECT * FROM users WHERE name = ‘John’;

@users = User.where(“name LIKE ?”, “Jo%”)
# => SELECT * FROM users WHERE name LIKE ‘Jo%’;
@users = User.order(“created_at DESC”)
# => SELECT * FROM users ORDER BY created_at DESC;

@users = User.joins(:profile).where(“profiles.about IS NULL”)
# => SELECT * FROM users LEFT OUTER JOIN profiles ON users.id =
profiles.user_id WHERE profiles.about IS NULL;
Scopes
class User < ActiveRecord::Base

  scope :with_name, where(“name IS NOT NULL”)

end
User.with_name
# => SELECT * from users WHERE name
IS NOT NULL;
User.with_name.where(“email = ‘foo@bar.com’”)
# => SELECT * FROM users WHERE name IS NOT NULL AND
email = ‘foo@bar.com’;
Controllers
REST
GET /users

GET /users/2
POST /users

PUT /users/2

DELETE /users/2
Routing
+-isshoni/
  +-app/
  +-config/
  | +-routes.rb
  +-db/
  +-public/
Isshoni::Application.routes.draw do

  get '/users'            =>   'users#index'
  get '/users/:id'        =>   'users#show'
  get '/users/new'        =>   'users#new'
  post '/users'           =>   'users#create'
  get '/users/:id/edit'   =>   'users#edit'
  put '/users/:id'        =>   'users#update'
  delete '/users/:id'     =>   'users#destroy'

end
Isshoni::Application.routes.draw do

  resources :users

end
Isshoni::Application.routes.draw do

  resources :users, :only => [:index, :show]

end
Isshoni::Application.routes.draw do

  resources :users do
    resources :ideas
  end

end

# => /users/:id/ideas
Isshoni::Application.routes.draw do

 resources :users do
   match '/activate' => 'users#activate', :on => :member
 end

end

# => /users/:id/activate
Isshoni::Application.routes.draw do

 resources :users do
   match '/active' => 'users#active', :on => :collection
 end

end

# => /users/active
Actions
$ rails g controller users
+-isshoni/
  +-app/
  | +-controllers/
  | | +-application_controller.rb
  | | +-users_controller.rb
  +-config/
  +-db/
  +-public/
class UsersController < ApplicationController

end
class ApplicationController < ActionController::Base
end
Isshoni::Application.routes.draw do

  get '/users'            =>   'users#index'
  get '/users/:id'        =>   'users#show'
  get '/users/new'        =>   'users#new'
  post '/users'           =>   'users#create'
  get '/users/:id/edit'   =>   'users#edit'
  put '/users/:id'        =>   'users#update'
  delete '/users/:id'     =>   'users#destroy'

end
Isshoni::Application.routes.draw do

  resources :users

end
# /users
users_path

# /users/:id
user_path(@user)

# /users/new
new_user_path

# /users/:id/edit
edit_user_path(@user)
class UsersController < ApplicationController

  def index
  end

  def show
  end

  def new
  end

  def create
  end

  def edit
  end

  def update
  end

  def destroy
  end

end
class UsersController < ApplicationController

  # GET /users
  def index
    @users = User.all
  end

end
class UsersController < ApplicationController

  # GET /users/:id
  def show
    @user = User.find(params[:id])
  end

end
class UsersController < ApplicationController

  # GET /users/new
  def new
    @user = User.new
  end

end
class UsersController < ApplicationController

  # POST /users
  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to users_path
    else
      render :new
    end
  end

end
class UsersController < ApplicationController

  # GET /users/:id/edit
  def edit
    @user = User.find(params[:id])
  end

end
class UsersController < ApplicationController

  # PUT /users/:id
  def update
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
      redirect_to user_path(@user)
    else
      render :edit
    end
  end

end
class UsersController < ApplicationController

  # DELETE /users/:id
  def destroy
    @user = User.find(params[:id])
    @user.destroy
    redirect_to users_path
  end

end
class UsersController < ApplicationController
  # GET /users
  def index
    @users = User.all
  end
                                                  # GET /users/:id/edit
  # GET /users/:id
                                                  def edit
  def show
                                                    @user = User.find(params[:id])
    @user = User.find(params[:id])
                                                  end
  end
                                                  # PUT /users/:id
  # GET /users/new
                                                  def update
  def new
                                                    @user = User.find(params[:id])
    @user = User.new
                                                    if
  end
                                                @user.update_attributes(params[:user])
                                                      redirect_to user_path(@user)
  # POST /users
                                                    else
  def create
                                                      render :edit
    @user = User.new(params[:user])
                                                    end
    if @user.save
                                                  end
      redirect_to users_path
    else
                                                  # DELETE /users/:id
      render :new
                                                  def destroy
    end
                                                    @user = User.find(params[:id])
  end
                                                    @user.destroy
                                                    redirect_to users_path
                                                  end
                                                end
Filters
class UsersController < ApplicationController
  before_filter :get_user, :only => [:show, :edit, :update, :destroy]

  def show
  end

  def edit
  end

  def update
    if @user.update_attributes(params[:user])
      redirect_to user_path(@user)
    else
      render :edit
    end
  end

  def destroy
    @user.destroy
    redirect_to users_path
  end

 private

  def get_user
    @user = User.find(params[:id])
  end
end
#   . #around (code before yield)
#   . . #before
#   . . . execute action
#   . . -
#   . #around (code after yield)
#   #after
Views
ERb
<%= "Hello" %>
<p><%= 3 * 2 %></p>


     <p>6</p>
<% ["Joe", "Mei"].each do |name| %>
  <p>Hello <%= name %></p>
<% end %>
<p>Hello Joe</p>
<p>Hello Mei</p>
+-isshoni/
  +-app/
  | +-views/
  | | +-users/
  | | | +-index.html.erb
  | | | +-new.html.erb
  | | | +-edit.html.erb
  | | | +-show.html.erb
  | | | +-_form.html.erb
  | | +-layouts/
  | | | +-application.html.erb
  +-config/
  +-db/
  +-public/
application.html.erb
<!DOCTYPE html>
<html>
<head>
  <title>Isshoni</title>
  <%= stylesheet_link_tag 'style' %>
  <%= javascript_include_tag :defaults %>
</head>
<body>
  <%= yield %>
</body>
</html>
<%= stylesheet_link_tag ‘style’ %>
# /public/stylesheets/style.css
<%= javascript_include_tag ‘application’ %>
# /public/javascripts/application.js
<%= yield %>
users/index.html.erb
<h1>Users</h1>
<p><%= link_to 'Add user', new_user_path %></p>

<% @users.each do |user| %>
  <div class="user"><%= user.name %></div>
<% end %>
users/show.html.erb
<h1><%= @user.name %></h1>

<p>
  <strong>Email:</strong>
  <%= @user.email %>
</p>

<p>
  <strong>About:</strong>
  <%= @user.profile.about %>
</p>
users/new.html.erb
<h1>Add user</h1>

<%= form_for @user do |f| %>
  <p>
    <%= f.label :name %>
    <%= f.text_field :name %>
  </p>

  <p>
    <%= f.label :email %>
    <%= f.email_field :email %>
  </p>

 <% f.fields_for :profile do |p| %>
   <p>
     <%= p.label :about %>
     <%= p.text_area :about %>
   </p>
 <% end %>

  <p>
    <%= f.submit %>
  </p>
<% end %>
users/edit.html.erb
<h1>Edit user</h1>

<%= form_for @user do |f| %>
  <p>
    <%= f.label :name %>
    <%= f.text_field :name %>
  </p>

  <p>
    <%= f.label :email %>
    <%= f.email_field :email %>
  </p>

 <% f.fields_for :profile do |p| %>
   <p>
     <%= p.label :about %>
     <%= p.text_area :about %>
   </p>
 <% end %>

  <p>
    <%= f.submit %>
  </p>
<% end %>
Partials
<h1>Add user</h1>

<%= form_for @user do |f| %>
  <%= render :partial => 'form', :object => f %>
<% end %>
<h1>Edit user</h1>

<%= form_for @user do |f| %>
  <%= render :partial => 'form', :object => f %>
<% end %>
users/_form.html.erb
<p>
  <%= form.label :name %>
  <%= form.text_field :name %>
</p>

<p>
  <%= form.label :email %>
  <%= form.email_field :email %>
</p>

<% form.fields_for :profile do |p| %>
  <p>
    <%= p.label :about %>
    <%= p.text_area :about %>
  </p>
<% end %>

<p>
  <%= form.submit %>
</p>
Nested attributes
<% form.fields_for :profile do |p| %>
  <p>
    <%= p.label :about %>
    <%= p.text_area :about %>
  </p>
<% end %>
class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy

  accepts_nested_attributes_for :profile
end
Helpers
<%= link_to 'Add user', new_user_path %>
<a href=”/users/new”>Add user</a>

<%= form_for @user do |f| %>
<% end %>
<form action=”/users” method=”post”>
</form>

<%= text_field_tag :name %>
<input type=”text” name=”name” id=”name” />

<%= javascript_include_tag 'application' %>
<script type=”text/javascript” src=”/javascripts/application.js”></script>


<%= image_tag 'background.png' %>
<img src=”/images/background.png” alt=”background” />
Mailers
class UserMailer < ActionMailer::Base
  default :from => "no-reply@foobar.com"

  def password_reset_instructions(user)
    @user = user
    mail :to => @user.email, :subject => "Password Reset"
  end

end
UserMailer.password_reset_instructions(@user).deliver
Security
Mass-assignment
class UsersController < ApplicationController

  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to users_path
    else
      render :new
    end
  end

end
<%= form_for @user do |f| %>
  <p>
    <%= f.label :username %>
    <%= f.text_field :username %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>
<%= form_for @user do |f| %>
  <p>
    <%= f.label :username %>
    <%= f.text_field :username %>
  </p>
  <input type="hidden" name="user[is_admin]" value="1" />
  <p>
    <%= f.submit %>
  </p>
<% end %>
# params[:user] => { :username => "joe", :is_admin => true }
@user = User.new(params[:user])
@user.save

@user.is_admin? # => true
class User < ActiveRecord::Base
  attr_protected :is_admin
end
class User < ActiveRecord::Base
  attr_accessible :username
end
SQL injection
@users = User.where("username LIKE '%#{params[:username]}%'")
# params[:username] = "nick' OR 1 = 1 OR username LIKE '%"
@users = User.where("username LIKE '%#{params[:username]}%'")

# SELECT * FROM users WHERE username LIKE '%nick' OR 1 = 1 OR username LIKE '%';
# params[:username] = "nick' OR 1 = 1 OR username LIKE '%"

@users = User.where("username LIKE ?", "%#{params[:username]}%")

# SELECT * FROM users WHERE username LIKE 'nick' OR 1 = 1 OR username LIKE '%';
XSS
mysite.com                  badsite.com




     POST mysite.com/delete_account
class ApplicationController < ActionController::Base
  protect_from_forgery
end
<head>
  <%= csrf_meta_tag %>
</head>


<head>
  <meta name="csrf-param" content="authenticity_token"/>
  <meta name="csrf-token" content="W8oH32123LgvCYNlVjQXsPAcLigB8CtX8eXYBGyp3yE="/>
</head>
Log Filtering
+-isshoni/
  +-app/
  +-config/
  +-db/
  +-public/
  +-log/
  | +-production.log
Started POST "/sessions" for 127.0.0.1 at Sat Jun 25 19:43:44 -0500 2011
  Processing by SessionsController#create as HTML
  Parameters: {"password"=>"123456", "email"=>"foo@bar.com"}
  SQL (0.5ms) SHOW TABLES
  Account Load (0.2ms) SELECT `accounts`.* FROM `accounts` WHERE
`accounts`.`email` = 'foo@bar.com' LIMIT 1
Completed 200 OK in 274ms (Views: 66.3ms | ActiveRecord: 0.7ms)
+-isshoni/
  +-app/
  +-config/
  | +-application.rb
  +-db/
  +-public/
  +-log/
module Deli
  class Application < Rails::Application

   config.filter_parameters += [:password]

  end
end
Started POST "/sessions" for 127.0.0.1 at Sat Jun 25 19:43:44 -0500 2011
  Processing by SessionsController#create as HTML
  Parameters: {"password"=>"[FILTERED]", "email"=>"foo@bar.com"}
  SQL (0.5ms) SHOW TABLES
  Account Load (0.2ms) SELECT `accounts`.* FROM `accounts` WHERE
`accounts`.`email` = 'foo@bar.com' LIMIT 1
Completed 200 OK in 274ms (Views: 66.3ms | ActiveRecord: 0.7ms)
I18n / L10n
+-isshoni/
  +-app/
  +-config/
  | +-application.rb
  +-db/
  +-public/
  +-log/
module Deli
  class Application < Rails::Application

   config.i18n.default_locale = :es

  end
end
<h1><%= I18n.t('home.title') %></h1>

<h2><%= t('home.subtitle') %></h2>
+-isshoni/
  +-app/
  +-config/
  | +-locales/
  |   | +-es.yml
  +-db/
  +-public/
  +-log/
es:
  home:
    title: "Ruby en la CP"
    subtitle: "Taller de RoR en CP"
<h1>Ruby en la CP</h1>

<h2>Taller de RoR en CP</h2>
+-isshoni/
  +-app/
  +-config/
  | +-locales/
  |   | +-es.yml
  |   | +-en.yml
  +-db/
  +-public/
  +-log/
en:
  home:
    title: "Ruby at CP"
    subtitle: "RoR workshopt at CP"
class ApplicationController < ActionController::Base
  before_filter :set_language

 private

  def set_language
    I18n.locale = params[:lang].to_sym if params[:lang]
  end
end
http://mysite.com/users?lang=en
<h1>Ruby at CP</h1>

<h2>RoR workshop at CP</h2>
Console
$ rails console
Loading development environment (Rails 3.0.9)
>>
Loading development environment (Rails 3.0.7)
>> User.all
=> []
Loading development environment (Rails 3.0.7)
>> User.all
=> []
>> User.create(:username => 'Testing')
=> #<User id: 2, username: "Testing", email: nil>
Best practices
DRY
(Don’t Repeat Yourself)
KISS
(Keep It Simple Stupid)
Convention over
 configuration
Fat models, thin
  controllers
TDD / BDD
Thanks!
Edgar J. Suarez
  @edgarjs

Más contenido relacionado

La actualidad más candente

Rediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesRediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesSimon Willison
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Evgeny Borisov
 
An (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to PythonAn (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to PythonNicholas Tollervey
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsDavid Golden
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackVic Metcalfe
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubyJason Yeo Jie Shun
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlSkills Matter
 
Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)Saurabh Nanda
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlinThijs Suijten
 
Automatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsAutomatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsFederico Tomassetti
 
Closure, Higher-order function in Swift
Closure, Higher-order function in SwiftClosure, Higher-order function in Swift
Closure, Higher-order function in SwiftSeongGyu Jo
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapHoward Lewis Ship
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 WorldDaniel Blyth
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perlgarux
 

La actualidad más candente (20)

7li7w devcon5
7li7w devcon57li7w devcon5
7li7w devcon5
 
PubNative Tracker
PubNative TrackerPubNative Tracker
PubNative Tracker
 
Rediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesRediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The Libraries
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2
 
An (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to PythonAn (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to Python
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
 
Ruby 101
Ruby 101Ruby 101
Ruby 101
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in Ruby
 
Barcelona.pm Curs1211 sess01
Barcelona.pm Curs1211 sess01Barcelona.pm Curs1211 sess01
Barcelona.pm Curs1211 sess01
 
jQuery introduction
jQuery introductionjQuery introduction
jQuery introduction
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
 
Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Automatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsAutomatically Spotting Cross-language Relations
Automatically Spotting Cross-language Relations
 
Closure, Higher-order function in Swift
Closure, Higher-order function in SwiftClosure, Higher-order function in Swift
Closure, Higher-order function in Swift
 
Python 1
Python 1Python 1
Python 1
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 World
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
 

Destacado

WorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on Rails
WorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on RailsWorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on Rails
WorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on RailsEdgar Suarez
 
Workshop Camp México 09 - Introducción a Ruby
Workshop Camp México 09 - Introducción a RubyWorkshop Camp México 09 - Introducción a Ruby
Workshop Camp México 09 - Introducción a RubyEdgar Suarez
 
WorkshopCamp México - BDD
WorkshopCamp México - BDDWorkshopCamp México - BDD
WorkshopCamp México - BDDEdgar Suarez
 
Productividad para programadores
Productividad para programadoresProductividad para programadores
Productividad para programadoresEdgar Suarez
 
Productividad en el Equipo de Desarrollo de Software
Productividad en el Equipo de Desarrollo de SoftwareProductividad en el Equipo de Desarrollo de Software
Productividad en el Equipo de Desarrollo de Softwarejuliocasal
 
The Presentation Come-Back Kid
The Presentation Come-Back KidThe Presentation Come-Back Kid
The Presentation Come-Back KidEthos3
 
The Buyer's Journey - by Chris Lema
The Buyer's Journey - by Chris LemaThe Buyer's Journey - by Chris Lema
The Buyer's Journey - by Chris LemaChris Lema
 

Destacado (8)

WorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on Rails
WorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on RailsWorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on Rails
WorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on Rails
 
Workshop Camp México 09 - Introducción a Ruby
Workshop Camp México 09 - Introducción a RubyWorkshop Camp México 09 - Introducción a Ruby
Workshop Camp México 09 - Introducción a Ruby
 
WorkshopCamp México - BDD
WorkshopCamp México - BDDWorkshopCamp México - BDD
WorkshopCamp México - BDD
 
Productividad para programadores
Productividad para programadoresProductividad para programadores
Productividad para programadores
 
Productividad en el Equipo de Desarrollo de Software
Productividad en el Equipo de Desarrollo de SoftwareProductividad en el Equipo de Desarrollo de Software
Productividad en el Equipo de Desarrollo de Software
 
¿Se puede medir la productividad del área de desarrollo?
¿Se puede medir la productividad del área de desarrollo?¿Se puede medir la productividad del área de desarrollo?
¿Se puede medir la productividad del área de desarrollo?
 
The Presentation Come-Back Kid
The Presentation Come-Back KidThe Presentation Come-Back Kid
The Presentation Come-Back Kid
 
The Buyer's Journey - by Chris Lema
The Buyer's Journey - by Chris LemaThe Buyer's Journey - by Chris Lema
The Buyer's Journey - by Chris Lema
 

Similar a Desarrollando aplicaciones web en minutos

Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v RubyJano Suchal
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick touraztack
 
Ruby is Awesome
Ruby is AwesomeRuby is Awesome
Ruby is AwesomeAstrails
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101Nando Vieira
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperJon Kruger
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Brian Hogan
 
Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Andre Foeken
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxDr Nic Williams
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 

Similar a Desarrollando aplicaciones web en minutos (20)

Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
Ruby on Rails
Ruby on RailsRuby on Rails
Ruby on Rails
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Ruby
RubyRuby
Ruby
 
Ruby is Awesome
Ruby is AwesomeRuby is Awesome
Ruby is Awesome
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Ruby Intro {spection}
Ruby Intro {spection}Ruby Intro {spection}
Ruby Intro {spection}
 

Último

Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 

Último (20)

Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 

Desarrollando aplicaciones web en minutos

Notas del editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n
  165. \n
  166. \n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n
  172. \n
  173. \n
  174. \n
  175. \n
  176. \n
  177. \n
  178. \n
  179. \n
  180. \n
  181. \n
  182. \n
  183. \n
  184. \n
  185. \n
  186. \n
  187. \n
  188. \n
  189. \n
  190. \n
  191. \n
  192. \n
  193. \n
  194. \n
  195. \n
  196. \n
  197. \n
  198. \n
  199. \n
  200. \n
  201. \n
  202. \n
  203. \n
  204. \n
  205. \n
  206. \n
  207. \n
  208. \n
  209. \n
  210. \n
  211. \n
  212. \n
  213. \n
  214. \n
  215. \n
  216. \n
  217. \n
  218. \n
  219. \n
  220. \n
  221. \n
  222. \n
  223. \n
  224. \n
  225. \n
  226. \n
  227. \n
  228. \n
  229. \n
  230. \n
  231. \n
  232. \n
  233. \n
  234. \n
  235. \n
  236. \n
  237. \n
  238. \n
  239. \n