Skip to main content

Posts

Showing posts from December, 2016

Study Guide 170

HTTP Describe what HTTP is and the role of the request and the response. HTTP is just a text sent over the internet with a set of rules that governs how computer communicates with each other. It follows a model whereby a client makes a request and then wait for a response from a server. HTTP itself doesn't transmit data, it depends on TCP/IP protocol to get request/response from one machine to another.  What are the components of an HTTP request and an HTTP response? HTTP request and response has a header and body.  HTTP response will contain status code ( 200 OK)  and headers which is a metadata that contain information for content-type (text/html),  Content-Encoding:gzip (type of file compression), server (name of the server), Location (new resource location for redirects) and a HTTP body  HTTP request header contain information on HTTP method (GET/POST) , path and parameter to allow server to know how to find information, along with optional headers that include in

The overall process of having user sign in and sign out

you store your username and password in the YAML file --- username: password Then we load the yaml file using YAML.load_file(file_path) This will create a hash of { 'username' => 'password' } Once we have the details, then request user to type in username and password. They are accessible via params[:username] and params[:password] if hash.key('username') return true && hash['username'] return the matching password then it is a match then we save the username into the session like so session[username] = username If we want to sign out , then we delete the username from the session via session.delete(username) If certain process you do not want user to do anything, just check if session[:username] is there or not, if not, then user is not log in, then you want to redirect them to homepage.

Building the sign in system

--- developer: letmein maintain a yaml file that look like above where developer is the username and letmein is the password Signin Create a form that generate a parameter called username, store the username in the session[:username] if the username and password are valid. Signout session.delete(:username) To determine whether to allow user to perform certain action, create a method def require_signed_in_user     unless session.key?(:username)   # which means whether there is a key name after 'username'        session[:message] = "You must be logged in to do that."        redirect "/"     end end Then put into whichever path that requires user login .

Using file system in Sinatra

You need to create a separate /data folder to store all the files. You need to have a root to current folder file by calling this file_path = File.expand_path("..", __FILE__) This will create a file path from root until one level above current file, which is the folder that contains your file. When reading text file, you need to specify headers['Content-Type'] = 'text/plain' File.read(file_path) To edit an existing file or to create a new file, need to File.write(file_path , "content here") To delete a file, File.delete(file_path) To determine whether a file exist or not File.exist?(file_path) File.file?(file_path) To list down all file within a certain directory. The Dir.glob will create an array list of the matching file. File.basename will cut off the last part of the file name. Dir.glob(root + "/data/*").map do |path|     File.basename(path) end As you can see, most File class takes in the file_path as argument.

The difference between modulo and remainder

There are difference in the calculation of modulo and remainder: Modulo is governed by the following equation x % y q = floor(x / y) x = q * y + r if x = 13 and y = 4 13 % 4 q = floor(13/4)    = 3 13 = 3 * 4 + r 13 = 12 + r r = 1 Remainder is governed by the following equation: x.remainder(y) x - y * (x/y).truncate  (truncate means to cut off the decimals) if x = 13 and y = 4 r = 13- 4 * (13/4).truncate r = 13 - 4 * 3 r = 13 - 12 r = 1

Explain code

get "/" do pattern = File . join ( data_path , "*" ) @files = Dir . glob ( pattern ) . map do | path | File . basename ( path ) end erb :index end def data_path if ENV [ "RACK_ENV" ] == "test" File . expand_path ( "../test/data" , __FILE__ ) else File . expand_path ( "../data" , __FILE__ ) end end data_path will check if ENV hash with key "RACK_ENV" has the value of "test". If yes, then return the path from root to cms2/test/data folder. If not , then return the absolute path from root to the folder cms2/data Then, in get "/" block , join the data_path with * . If in development environment, then data_path is home/cms2/data then the return value is home/cms2/data/* We use File.join is good because it will detect the OS, then join with appropriate character.  With the pattern in place, we use Dir.glob to find the files. Here it return home/

Explain the complete_list vs incomplete_list blocks

  def sort_lists(lists, &block)        complete_lists, incomplete_lists = lists.partition { |list| list_complete?(list) }        incomplete_lists.each { |list| yield list, lists.index(list) }        complete_lists.each { |list| yield list, lists.index(list) }   end <ul id="lists">       <% sort_lists(@lists) do |list, index| %>           <li class="<%= list_class(list) %>">                <a href="/lists/<%= index %>">                     <h2><%= list[:name] %></h2>                     <p><%= todos_remaining_count(list) %> / <%= todos_count(list) %></p>                </a>           </li>       <% end %> </ul> We want the list to populate incomplete_list first then completed_list second. So we pass in the partition method that will create one array for values that return true, and another array for values that return false. The list_

Explain blocks

[ 1 , 2 , 3 ] . map do | num | num + 1 end = > [ 2 , 3 , 4 ] ~ [1,2,3] is the calling object ~ .map is the method ~ do....end is the block ~ [2,3,4] is the return object So the block is a kind of argument passed into the method. This chunk of code will add to the individual element in the array by 1. [1,2,3].map(&block) You are passing in the block as an argument. What map does is take each element in the array, run it through the block . It is like the array#include? function, which take each element in the array, then compare it against the argument [1,2,3].include?(2) then return true. In this case, the argument is just a single number. But in our case, the argument is a whole chunk of code. the Map function is to pass in each element into the chunk of code, then make the return value of each block into a new array. Then, return the new array.

Study Guide 170

HTTP Describe what HTTP is and the role of the request and the response HTTP is a system of rules , that serve as a link between application and the transfer of hypertext documents.  It is an agreement of how machines communicate with each other  HTTP follows a model, where client make a request and the server make a response (ie. it is a request response protocol).  What are the components of an HTTP request and an HTTP response? Identify the components of a URL. Construct a URL that contains a few params and values. Explain the difference between GET and POST, and know when to choose each. What is the difference between client-side and server-side code? For each file in a Sinatra project, be able to say which it is. Web How does an HTML form element interact with the server-side code that processes it. Why is user-entered content a security risk? Be aware of how to mitigate this risk. Sinatra Start a new Sinatra project and write simple routes to handle req
def load_list(index)   list = session[:lists][index] if index   return list if list      session[:error] = "The specified list was not found."   redirect "/lists" end # View a single todo list get "/lists/:id" do @list_id = params[:id].to_i @list = load_list(@list_id) erb :list , layout: :layout end load_list method will take in an index of the todo list in the session[:lists]'s array. If there is an index provided, then find the list item in the session[:lists] array. Store the retrieve list in the list local variable. If the list is not nil/false, then return the list and terminate the method. Then store the list hash into @list instance variable.  If list is nil/false, because there is no such index in the session[:lists] array, then list will be nil. So the return function won't be executed. Then, we create a error message and store it in the session[:error] hash. Then we redirect to "/lists" which will render

sort list in todos apps

todo.rb   def sort_lists(lists, &block)     incomplete_lists = {}     complete_lists = {}           lists.each_with_index do |list, index|       if list_complete?(list)         complete_lists[list] = index       else         incomplete_lists[list] = index       end     end          incomplete_lists.each(&block)     complete_lists.each(&block)   end So here, this is under the helpers block. Code in the helpers block is accessible in erb view template and the main ruby files. "sort_lists" takes a lists object and a block. A lists object is a array that contains the hash object {name: "work" , todos: [] }. So now our objective is to break the lists into those that is incomplete list first, then completed second. so we iterate through the lists's array, one by one, which yielded the list hash. Then we pass the list hash into the list_complete? method. Which select list hash who has at least one item in the todos array and also those lis

Explain To do code midway.

This is the to do project code in course 170. sinatra get "/" do   redirect "/lists" end if the user go to homepage app.com/ , it will be redirected to app.com/lists sinatra get "/lists" do   @lists = session[:lists]       erb :lists, layout: :layout end in app.com/lists , the session hash key of :lists will be stored in @lists.  Then the layout lists.erb will be rendered. lists.erb <ul id="lists">   <% @lists.each_with_index do |list, index| %>     <li>       <a href="/lists/<%= index %>">         <h2><%= list[:name] %></h2>         <p><%= list[:todos].size %></p>       </a>      </li>   <% end %> </ul> <% content_for :header_links do %>   <a href="/lists/new">New List</a> <% end %> Actually @list will contain a data structure like this @lists = [{name: "todo" , todo:

common CSS properties

1. color: can be represented by hexadecimals , HSL (hue , saturation, lightness), RGB or keywords 2. length - absolute : px - relative : percentages (based on parent element),  em (equal 1 font-size , if fontsize is 10 px, 5 em is 50 px, if no font-size on current element , based on parent element.) 3. display - block - inline (inline element do not have height and width) - inline-block (behave like block , can be beside another element, won't begin on a new line) - none (totally hide the element) 4. float position an element relative to its parent. Other element will wrap around it. It is taken out of the normal flow of the HTML doc. So it may cause other HTML element to mistakenly wrap around it, we can use `clear` properties to ask the current element to clear away from floated elements.

Explain CSS cascading rules

- within same specificity , the styles further in the bottom take higher precedence, like a water fall cascade. p {     color: red; } p {     color: blue; } The paragraph will be blue. - There are different specificity base on different selector    - ID        1-0-0    - class    0-1-0    - type     0-0-1 ID is the most specific, so its style will take precedence if class and type classed with ID. - You can combine selector , so the highest number will take precedence #num .cili .love {      color: red; } 1-2-0 #num .cili {      color: blue; } 1-1-0 Color will still be black - You can have two class for each element, separated by one space. <p class="btn  btn-success"> </p>

common html element

<head> this tag will list down all metadata of the html doc. Popular metadata include <link> , <title> and <meta> <h1> to <h6> from big heading to subheading , this represents the titles of the HTML document Note: do not use <h1> tag to make text bigger, use CSS. <p> the text paragraph of the HTML doc. block element <div> and <span> these are for styling the html element, div is block , span is inline <a> anchor tag, provide a link to another page.  inline element. <a href="http://www.google.com"> Google </a> <strong> and <b> , both will make text bold , but <strong> means that text is more important. both are inline element <em> and <i>   , <em> is emphasize the text , <i> to speak in alternative tone. both are inline element <nav> is for navigation links , for semantic purpose. <small> to represents fineprint, side

HTML , block vs inline element

Inline element - will have width of the content it wrap and can exist beside another inline element <span> is an inline element block element - its width cover the entire width of the page , can't have another element beside it.  <div> is an inline element

CSS Syntax

selector {     properties : value ; } selector could be the html element (p), id (#id_name) , class (.class_name) or universal selector (*). properties are like color, width or height. value are like 24px, red, #FF0000

Explain Gemfile and Gemfile.lock

Bundler allow you to specify exactly which third party software is required to run your program. Gemfile will list - all the dependencies/third party program required to run your program. - where to source those gems Gemfile.lock will list the exact version of the third party softwarre Gemfile.lock will be generated the first time you run 'bundle install'

Sign in page

AAAA < % if session[: username] % > < form method = " post " action = " /users/signout " > < p class = " user-status " > Signed in as <%= session[:username] %>. < button type = " submit " > Sign Out </ button > </ p > </ form > < % else % > < p class = " user-status " > < a href = " /users/signin " > Sign In </ a > </ p > < % end % > Explanaion: 1. if in the session hash, key :username has a value, then perform this: - create a form , the form will create a HTTP post request to /user/signout - the form will only submit when the button is clicked, that's why it has a type="submit" - otherwise, if the button is not clicked, just display the paragraph/message of "Signed in as username" 2. Without username value - create a link to '/users/signin' page with