diff --git a/Gemfile b/Gemfile index fcd0104f8..19f18afee 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org/" -ruby '2.2.0' +ruby '2.1.2' gem 'activesupport' gem "erector", "~> 0.10.0" @@ -17,7 +17,7 @@ gem "redcarpet" gem "rubyzip" gem "i18n", "~> 0.7" gem 'font-awesome-sass' -gem 'bootstrap-sass' +#gem 'bootstrap-sass' gem 'jquery-cdn' gem 'sprockets' diff --git a/Gemfile.lock b/Gemfile.lock index 8eb56faec..0c285191e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,13 +7,7 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - autoprefixer-rails (5.1.5) - execjs - json backports (3.6.4) - bootstrap-sass (3.3.3) - autoprefixer-rails (>= 5.0.0.1) - sass (>= 3.2.19) celluloid (0.16.0) timers (~> 4.0.0) coderay (1.1.0) @@ -32,7 +26,6 @@ GEM erector (0.10.0) treetop (>= 1.2.3) eventmachine (1.0.7) - execjs (2.3.0) ffi (1.9.6) files (0.3.1) font-awesome-sass (4.3.1) @@ -131,7 +124,6 @@ PLATFORMS DEPENDENCIES activesupport - bootstrap-sass coderay deckrb (~> 0.5.2) erector (~> 0.10.0) diff --git a/app.rb b/app.rb index 4f0faeb8a..7d5b385f1 100755 --- a/app.rb +++ b/app.rb @@ -5,7 +5,7 @@ require 'i18n' require 'i18n/backend/fallbacks' require 'font-awesome-sass' -require 'bootstrap-sass' +#require 'bootstrap-sass' require 'zip' require 'tmpdir' @@ -41,7 +41,7 @@ class InstallFest < Sinatra::Application # todo: use Sinatra::Base instead, wi settings.assets.append_path "assets/stylesheets" settings.assets.append_path "assets/javascripts" settings.assets.append_path "public/fonts" - settings.assets.append_path Bootstrap.javascripts_path +# settings.assets.append_path Bootstrap.javascripts_path JqueryCdn.install(settings.assets) if settings.environment == :development diff --git a/lib/doc_page.rb b/lib/doc_page.rb index 099bdb7b8..63e5b94ed 100644 --- a/lib/doc_page.rb +++ b/lib/doc_page.rb @@ -49,11 +49,7 @@ def src_url end def top_links - [ - TopLink.new(name: "toc", href: "#", extraclass: 'show-when-small', toggle_selector: '#table_of_contents'), - TopLink.new(name: "src", href: src_url, extraclass: 'hidden-sm'), - TopLink.new(name: "git", href: git_url, extraclass: 'hidden-sm'), - ] + [] end def body_attributes @@ -74,12 +70,12 @@ def body_content } } ul(class: "navbar-nav nav") { - widget Flags, locale: @locale +# widget Flags, locale: @locale - li(class: "dropdown") { - a("sites", href: "#", class: "dropdown-toggle", "data-toggle" => "dropdown") - widget SiteIndex, site_name: site_name, locale: @locale - } +# li(class: "dropdown") { +# a("sites", href: "#", class: "dropdown-toggle", "data-toggle" => "dropdown") +# widget SiteIndex, site_name: site_name, locale: @locale +# } top_links.each do |top_link| widget top_link @@ -113,21 +109,31 @@ def body_content } footer { +# p do +# # text "Going through this curriculum on your own? Get help at " +# # a "Code Newbie", href: "http://discourse.codenewbie.org/t/railsbridge-curriculum-questions/594/4" +# # text ", where RailsBridge volunteers can answer your questions." +# end +# p do +# text "If you have a suggestion for improving the docs, please make a " +# a "pull request ", href: "https://github.com/railsbridge/docs" +# text "or " +# a "drop us a note ", href: "https://github.com/railsbridge/docs/issues/new" +# text "via GitHub Issues (no technical knowledge required)." +# end + # p do + # text "Source: " + # url "https://github.com/railsbridge/docs" + # end p do - text "Going through this curriculum on your own? Get help at " - a "Code Newbie", href: "http://discourse.codenewbie.org/t/railsbridge-curriculum-questions/594/4" - text ", where RailsBridge volunteers can answer your questions." + text "Based on the RailsBridge curriculum:" end p do - text "If you have a suggestion for improving the docs, please make a " - a "pull request ", href: "https://github.com/railsbridge/docs" - text "or " - a "drop us a note ", href: "https://github.com/railsbridge/docs/issues/new" - text "via GitHub Issues (no technical knowledge required)." + url "http://curriculum.railsbridge.org/" end p do - text "Source: " - url "https://github.com/railsbridge/docs" + text "Modified for " + a "RailsBridge Chicago", href: "http://railsbridgechi.com/" end } end diff --git a/lib/site_index.rb b/lib/site_index.rb index d6bd8f172..d3f455d8e 100644 --- a/lib/site_index.rb +++ b/lib/site_index.rb @@ -5,9 +5,7 @@ class SiteIndex < Erector::Widget def categorized_sites { 'setup' => ['installfest'], - 'rails' => ['intro-to-rails', 'job-board', 'intermediate-rails'], - 'frontend' => ['frontend', 'javascript-snake-game', 'javascript-to-do-list', 'javascript-to-do-list-with-react'], - 'ruby' => ['learn-to-code', 'ruby'] + 'rails' => ['intro-to-rails'] } end diff --git a/sites/en/docs/docs.step b/sites/en/docs/docs.step index df5acdd32..d25d528ee 100644 --- a/sites/en/docs/docs.step +++ b/sites/en/docs/docs.step @@ -1,7 +1,3 @@ -message <volunteer-created Railsbridge curriculum." -site_desc 'ruby', <<-MARKDOWN -A ruby-specific curriculum, expanded from the "Ruby for Beginners" slide deck. Still new, with room for your contributions. -MARKDOWN - -h1 'Other' - -site_desc 'workshop', <<-MARKDOWN -The Railsbridge junkyard! Slide decks for opening/closing presentations, teacher training. -MARKDOWN - -message <" - message <<-MARKDOWN - -looks like a radio button: , but - - MARKDOWN - source_code :html, "" - message <<-MARKDOWN - -looks like a password text input: even though they use the same **tag**. - -## IDs and Classes - -Two of the most important attributes that an element can have are its `id` and its `class`. With these attributes, -we can assign names to elements and groups of elements, then apply CSS styles using the names we give them. - -MARKDOWN - - source_code :html, <<-MARKDOWN -

- This is my intro paragraph! -

-MARKDOWN - - message <<-MARKDOWN -In our CSS, we use special syntax to tell the browser if we're talking about an ID or a class name. IDs are indicated with a -hash, like this: `#intro`. Classes are indicated with a dot: `.special` - MARKDOWN - - tip do message <<-MARKDOWN -## When should I use a class, and when should I use an ID? - -**ID** attributes are unique labels, for identifying things you'll only ever have one -of. For example, if you ran a news website, you might have an masthead element -that only appears once, so you could give it an id -like `handsome-header`. - -**Class** attributes should be used to group together similar elements; for example, you might give certain -paragraphs a class of `special` and use that class to highlight them. - -In general, only use `id` if you're certain that it will only appear on a single element. For everything else, -use `class`. - - MARKDOWN - end - message <<-MARKDOWN - -Let's look at IDs and classes in action. So far we've only applied styles to HTML tags like `

` and `

`. But what if we want to apply a style to only a few of the instances of a given tag? We don't want _every_ paragraph to look special, so we can't add our style directly to the `

` tag. - -MARKDOWN - -end - -steps do - - step do - message "Let's add some classes and ids to our HTML. Start by adding one or two more paragraphs of text to the bottom of your HTML document. The last lines might look like this:" - source_code :html, <Hello World!

-

My name is Rachel.

-

I like:

- -

I hear RailsBridge needs volunteers, should I volunteer!?!

-HTML - end - - step do - message "Add the class 'special' to your first paragraph. It'll look something like this:" - source_code :html, <Hello World! -

My name is Rachel.

-

I like:

- -

I hear RailsBridge needs volunteers, should I volunteer!?!

-HTML - message "Refresh the page in the browser. You should see any new paragraphs you added, but no styling changes." - message "Many HTML attributes, like classes and ids, don't directly convey visual information. Your site will look the exact same until we use the class to add CSS styling." - end - - step do - message "To add a style rule that will apply to a class, use the syntax `.class-name` for your selector. It will be almost the same as the styles that you added to `

` and `

`, but with a period at the beginning of your class name." - message "Try giving the 'special' class a green border. Add this rule inside of your `style` tag:" - source_code :css, <Hello World!

-

My name is - Rachel -

-

I like:

- -

I hear RailsBridge needs volunteers, should I volunteer!?!

-HTML - message "Save and refresh the page in the browser. Again, you shouldn't see any difference." - end - - step do - message "Now, add the corresponding style rule for your ID, using the syntax `#id-name` for your selector. Try making the 'user-name' id look bold. Add this rule inside of your `style` tag:" - source_code :css, <` is called the doctype, and it tells the browser which flavor of HTML you're using. `` tells your browser you're using HTML5, the latest version of HTML. - -(You may see older doctypes out there that are longer and a lot more complicated, from when people -used various HTML and XHTML versions, but those are annoying, and you can usually just -use this short version for new websites.) - -The `` encloses all the rest of your page, and states unequivocally, "Here is my HTML!!!" - -## Pages, Like People, Have a Head and a Body - - MARKDOWN - source_code :html, < - - Invisible, Important Stuff - Actual Visible Content - -HTML - message <<-MARKDOWN - -### The Head - -The head contains information _about_ the document, including: - -* what language or character set you're using -* what the page title should be -* what CSS and JavaScript files to include (and where they are) - -Information in the `` section is __not__ displayed. - -It can also contain metadata tags that can tell a search engine or another -program more about the file, like who wrote it or what keywords are relevant. - -### The Body - -The Body contains the actual content of your file, the things you'll want your users -to be able to see, read, or interact with! - - MARKDOWN - -end - -steps do - - step do - message <<-MARKDOWN -Let's add the doctype, HTML, head, and body tags to your file. It should look like this: - - - -Save the file and refresh your browser. Everything should look mostly the same. - - MARKDOWN - end - - step do - message "Let's add a title to our page within the `` section. Add this line:" - source_code :html, "My Sample HTML page" - message <<-MARKDOWN -When you refresh your browser, you should see the title on the tab in Chrome. - - - -(If it doesn't show up, double check that you put the line between the opening and closing head tags, and that you saved your file before refreshing.) - MARKDOWN - end - -end - -next_step "basic_CSS" - diff --git a/sites/en/frontend/HTML_tags.step b/sites/en/frontend/HTML_tags.step deleted file mode 100644 index 260881d78..000000000 --- a/sites/en/frontend/HTML_tags.step +++ /dev/null @@ -1,216 +0,0 @@ -goals do - goal "Add some tags to your HTML file" - goal "Learn more about available tags" -end - -overview do - - message <<-MARKDOWN - -## Use Tags to Separate Blocks of Content - - -Tags convey meaning. And in order to display your content well, everything should be inside of a tag, not just words you want emphasized. So let's use the paragraph tag `

` and the header 1 tag `

`. - -You'll notice that even if you put in extra lines and spaces, HTML will treat any number of -new line or space characters like there's just one space there. When you're getting started -with HTML, this can seem like a pain, because you have to type - MARKDOWN - - source_code :html, <first sentence

-

second sentence

-HTML - message <<-MARKDOWN - -when all you want is a blank line between two sentences. But as you get more advanced, this -aspect of HTML will feel more useful, because it means you can format your code however is -most readable for **you**, without worrying about what the browser will think of your blank -lines and spaces. - -## Nested Tags - -It's common for an HTML tag to be nested inside another tag. In the example above, you saw: - MARKDOWN - - source_code :html, "

" - - important do - message "Just make sure that the tags are correctly _nested_. For example, you can't do:" - - source_code :html, "

Hello World!

I like you!" - - message "The inner tag, `em`, needs to close before the outer tag closes." - end -end - -steps do - - step do - message "Add some more lines of content to your HTML file. Introduce yourself." - - source_code :html, <<-HTML -Hello World! - -My name is Rachel. - HTML - - message "Now save the file and refresh your browser." - img src: 'img/hello_world_2line.png' - end - - step do - message "Even though we put in some blank lines, the browser ignored them. So we'll have to use tags to break up our content." - message "Update your HTML with an `h1` tag and a `p` tag:" - - source_code :html, <<-HTML -

Hello World!

-

My name is Rachel.

- HTML - - message "Now save the file and refresh your browser." - img src: 'img/hello_world_2line2.png' - end - - step do - message "Now let's add a list of things we like." - - source_code :html, <<-HTML -

Hello World!

-

My name is Rachel.

-

I like:

-
    -
  • Polka Dots
  • -
  • Soccer
  • -
  • Programming
  • -
- HTML - - message "Now save the file and refresh your browser." - img src: 'img/html_tags_list.png' - end - -end - - -explanation do - - message <<-MARKDOWN - -## Tags for Every Occasion - -The meteoric rise in popularity of the world-wide-web and the recent proliferation of web -applications has made HTML hugely popular. While originally used only for simple documents, -HTML now has tags for embedded video and music playback, embedding images, filling out -web forms, and all kinds of other useful tags. - -You just used two well-known tags, `h1` for a headline and `p` for a paragraph. But there -are a ton of other tags you might use: - -## More Tags - - MARKDOWN - - table border: "1", cellspacing: "0", cellpadding: "3", align: "center" do - tr { - th "Tag" - th "Purpose" - } - tr { - td "a" - td "A link (the 'a' stands for Anchor)" - } - tr { - td "h1-h6" - td "Various headers, h1 is the most important, h6 the least." - } - tr { - td "ul" - td "Start a bulleted list (an 'unordered list')" - } - tr { - td "ol" - td "Start a numbered list (an 'ordered list')" - } - tr { - td "li" - td "A single thing within a list (a 'list item')" - } - tr { - td "table, tr, td" - td "You can make tables (like this one) with table rows and data cells" - } - tr { - td "form" - td "A form that can collect data from user input" - } - tr { - td "input" - td "A text input, a button, or a checkbox in a form" - } - tr { - td "div" - td "A section marker that doesn't do anything specific to the contents itself, but does make a new line after. (More on this later.)" - } - tr { - td "span" - td "Another section marker that doesn't do anything to its contents, but is inline - it does not make a new line after." - } - end - - message <<-MARKDOWN - - And HTML5 introduced lots of new HTML tags to make the HTML more *semantic*, meaning the tags should describe the content they describe. Some of the new elements introduced by HTML5 include: - - MARKDOWN - - table border: "1", cellspacing: "0", cellpadding: "3", align: "center" do - tr { - th "Tag" - th "Purpose" - } - tr { - td "section" - td "A section of a document" - } - tr { - td "nav" - td "A navigation section" - } - tr { - td "header" - td "The header for a page. (This is different from the head element, which contains metadata about the page!)" - } - tr { - td "footer" - td "The footer for a page" - } - tr { - td "main" - td "The important content on a page" - } - tr{ - td "aside" - td "Content not essential to the main content" - } - end - - message <<-MARKDOWN - -Don't try to memorize all the tags! You can always look them up on sites like: - -* [Sitepoint](http://reference.sitepoint.com/html) -* [Mozilla Developer Network](https://developer.mozilla.org/en/HTML/Element) - -## Try This -What happens if you change the `
    ` to `
      `? (Don't forget to change the closing tag, too.) - -Can you link your favorite things to their respective Wikipedia pages? Here's an example link for you: `Ruby` - -CLASS DISCUSSION: What are all the individual parts of the code to add a link? - - MARKDOWN - -end - -next_step "HTML_structure" diff --git a/sites/en/frontend/_consider_deploying_to_github.step b/sites/en/frontend/_consider_deploying_to_github.step deleted file mode 100644 index 1403ca1b6..000000000 --- a/sites/en/frontend/_consider_deploying_to_github.step +++ /dev/null @@ -1,7 +0,0 @@ -div :class => "deploying" do - h1 "Deploying" - blockquote do - message "Before the next step, you could try deploying your page to Github!" - link 'deploying_to_github_pages' - end -end diff --git a/sites/en/frontend/_developer_tools.step b/sites/en/frontend/_developer_tools.step deleted file mode 100644 index f24056dd3..000000000 --- a/sites/en/frontend/_developer_tools.step +++ /dev/null @@ -1,67 +0,0 @@ -goals do - goal "Get oriented with your browser's developer tools. They're a great jumping-off point for continuing to build your HTML, CSS, and JavaScript knowledge." - tip "The screenshots below are specific to the Chrome web browser, which is available for Mac, PC, and Linux and has great developer tools. But if you're partial to another browser, there's usually a similar set of tools you can use." -end - -steps do - - step do - message <<-MARKDOWN - First, you've got to turn on your developer tools. They're hidden by default. - - - - In Chrome, you can do this by clicking _View > Developer > Developer Tools_. - MARKDOWN - end - - step do - message <<-MARKDOWN - Click on the 'Elements' button to check out your HTML. - - - - Clicking on an HTML tag in the elements panel will highlight that element in the browser window. It's a great tool for debugging styling problems. On the right side of the panel, you'll even get a list of styles that are being applied to that element. - MARKDOWN - tip "Chrome's Elements panel will update to match the state of your DOM as you modify it with JavaScript. Some elements panels don't do this — they just show what the HTML looked like on page load." - end - - step do - message <<-MARKDOWN - In the 'Network' panel, you can see what other files and resources your HTML page is loading. - - - - If you click on a file name, you can take a look at the contents of that file. This panel is a great place for debugging script linking or loading issues. (You can see HTTP headers and request params here too, with a little digging.) - MARKDOWN - end - - step do - message <<-MARKDOWN - The 'Console' is the JavaScript developer's secret weapon. It lets you run JavaScript by typing it in directly — and it runs your scripts _in the context of your page_, so you can interact directly with objects and functions you've defined. It's helpful for debugging and experimenting. - - - MARKDOWN - end - - step do - message <<-MARKDOWN - The 'Sources' panel is another JavaScript pro tool. If you're used to working with an IDE that has a debugger, you'll be able to use many of the same techniques (like breakpoints, stack traces, and watch expressions) right here in the browser. - - - MARKDOWN - end -end - -explanation do - - message <<-MARKDOWN - -## Keep Learning with Developer Tools - -With good browser developer tools, you can pick apart every website you visit. If you see cool -CSS styles or JavaScript animations, you can always look under the hood and figure out how -they're done. It's a great way to keep learning as a front end developer. - - MARKDOWN -end diff --git a/sites/en/frontend/_working_effectively_and_efficiently.md b/sites/en/frontend/_working_effectively_and_efficiently.md deleted file mode 100644 index dbae24fbb..000000000 --- a/sites/en/frontend/_working_effectively_and_efficiently.md +++ /dev/null @@ -1,15 +0,0 @@ -### Working Effectively and Efficiently - -We highly recommend you do the following: - -* Open your browser fresh or hide any windows you already have open. - * Bring up one window with two tabs - * One for this content - * One for interacting with your app. -* Open your text editor and _do not ever close it_. We're not quitters. -* Hide all extra applications. Turn off twitter, IM, and all other distractions. - -By minimizing the number of things you interact with, you reduce the -amount of time spent switching between them and the context lost as -you work through the lessons. Having 50 tabs open in your web -browser gets confusing and wastes time. \ No newline at end of file diff --git a/sites/en/frontend/add_more_elements.step b/sites/en/frontend/add_more_elements.step deleted file mode 100644 index 5f60a6c92..000000000 --- a/sites/en/frontend/add_more_elements.step +++ /dev/null @@ -1,66 +0,0 @@ -goals do - message "WOOHOO, you made it to page 10! Now that we're here, we'll switch from simple steps to doing **challenges**. There will still be something to do at each step, but it will take some figuring out to do correctly. (If you get stuck, you can still ask a TA or instructor for hints. : ) You will:" - goal "Fill in more content" - goal "Add an image tag" - goal "Use two different kinds of anchor tags" -end - -steps do - - step do - message <<-MARKDOWN -CHALLENGE: The index.html page you downloaded is a simple profile page. Do a quick read through of the HTML and see if you can guess from the context what any unfamiliar tags might do. - -Take 5 or 10 minutes to replace some of the existing text with some info about yourself. You don't have to write a novella, but filling in some tags is a good way to get oriented in the file. Then, save the page and refresh the browser. - MARKDOWN - end - - step do - message <<-MARKDOWN -CHALLENGE: Add an image tag to the page, right above the word 'Contents'. There's a sample image in the resources folder that you can use called 'picture.jpg', but if you want to personalize your page, copy a picture of yourself into the resources folder and add that to the page instead. - -Two hints: images are usually included with an `img` tag, and the tag's `src` attribute provides the path to the actual file. When you're done, you'll have something like this: - - - -Don't forget that, because it doesn't wrap text content, the `img` tag is self-closing, meaning it doesn't need an ending tag. You should never code ``. - MARKDOWN - end - - step do - message <<-MARKDOWN -CHALLENGE: Add two kinds of anchor links. - -Links in html are created by the `a` tag. Add an `a` tag somewhere in the document that creates a link to another page on the web. - -If you're not sure what attributes an `a` tag can have, see if you can look it up on [MDN](https://developer.mozilla.org/en/HTML/Element/a). - -You can also make links that stay on the current page and just point to another block of content. Instead of linking to a url, they'll link to the id of an element you want to jump to, with an attribute like `href='#id-name'` - -See if you can turn the list items under the word 'Contents' into links that jump down the page to the relevant content. They'll look like this: - - - MARKDOWN - end - - -end - -explanation do - - message <<-MARKDOWN - -## Woohoo HTML - -Now that you know the basics of working with HTML, the trickiest part is remembering -what tags are available. Here are some good sites you can use for reference: - -* [Sitepoint](http://reference.sitepoint.com/css) -* [Mozilla Developer Network](https://developer.mozilla.org/en/HTML/Element) - - MARKDOWN -end - -insert 'consider_deploying_to_github' - -next_step 'make_columns' diff --git a/sites/en/frontend/add_starter_files.step b/sites/en/frontend/add_starter_files.step deleted file mode 100644 index 797894203..000000000 --- a/sites/en/frontend/add_starter_files.step +++ /dev/null @@ -1,43 +0,0 @@ -goals do - goal "Add some starter files to your project" -end - -steps do - step do - message <<-MARKDOWN - Download the .zip file from [this link](https://github.com/eanakashima/front-end-lesson/archive/master.zip) - When the file download finishes, find it on your computer and unzip it. - MARKDOWN - end - - step do - message <<-MARKDOWN - The zip file should contain a file called index.html and a directory of resources." - - - - Drag the file called index.html and resources folder into your project folder. Go ahead and replace the index.html file you may already have in there. - MARKDOWN - end -end - -explanation do - message <<-MARKDOWN - -## What Are These Files? - -Just to save you some time, we've supplied a bare bones HTML document, a CSS stylesheet, -a JavaScript file, and a placeholder image. But you could have typed up these files yourself -with your text editor, if you'd wanted to. - -If you are starting a new project in the future, try typing it all out by hand a few times -to get the hang of it, and then try starting with some other people's HTML boilerplate code -that they've shared: - -* [HTML5 Boilerplate](http://html5boilerplate.com/), a blank template with lots of tips for high-performance best practices. -* [Twitter Bootstrap](http://twitter.github.com/bootstrap/), an HTML / CSS base with a big library of styles to test out. - - MARKDOWN -end - -next_step "make_a_web_page" diff --git a/sites/en/frontend/basic_CSS.step b/sites/en/frontend/basic_CSS.step deleted file mode 100644 index 4e80576e9..000000000 --- a/sites/en/frontend/basic_CSS.step +++ /dev/null @@ -1,127 +0,0 @@ -goals do - goal "Learn basic CSS syntax" - goal "Write some basic CSS styles" -end - -overview do - message <<-MARKDOWN -## What is CSS? - -CSS stands for __C__ascading __S__tyle__s__heets. It's a language for creating **rules** that -can **select** various elements on the page and change their **visual properties**. - -* __C__ascading - this is how the browser determines the correct style rules to apply to - each element on the page. As we'll see, CSS has many ways to match rules to elements, and - some of those ways count for more than others. The browser allows more important rules to - _cascade_ over less important ones. - -* __S__tyle__s__heets - CSS files are called 'stylesheets' because they are separate documents - their - file type is .css - that only deal with styling information. We add special tags in our HTML files to - link them to our stylesheets. - -Unlike HTML, which is concerned with the _meaning_ of the content, CSS is **presentational**: -it's concerned with how that content should look. - - -MARKDOWN - - tip do - message "## Why are HTML and CSS separate?" - message <<-MARKDOWN -There are many good reasons to keep HTML and CSS separate. A typical website will reuse styles -- like the color of links or the sizes of buttons - over and over again; by keeping them separate from the markup, we can -use the same styles across a site. - -This makes our code more efficient and easier to maintain, and keeps the site visually consistent. It also makes it easier to use -different styles for different devices, so a site can have different looks for desktop and mobile browsers. -MARKDOWN - end - - message <<-MARKDOWN -## CSS Rules Are Made of a Selector and Attributes - -The **selector** is the first part of a CSS rule - it tells the browser how to find, or _select_, the element we want to style. -On this page, we'll use `h1` and `p` as our selectors, which match the `h1` and `p` elements in our HTML. - - - -The **attributes** are the parts of the rule inside the curly braces - they tell the browser how the elements -we've selected should appear. - -Take a look at the attributes for the `h1` rule above. The part before the colon — `font-size` — is the **property**, -and the part after it — `20px` — is the **value**. This attribute tells the browser that all `h1` elements -should have a `font-size` of 20 pixels. - -The semicolons at the end of each attribute are important - if we forget them, the CSS won't work. - - -MARKDOWN -end - -steps do - - step do - message "Initially, we're going to add our CSS inside the `` tag, below the line with the page title." - message "A standard style tag might look like this:" - source_code :html, < -My Sample HTML page - - -HTML - message "Now save the file and refresh your browser. Everything should look the same." - end - - step do - message "Add some styles that will apply to your `h1` and `p` tags." - source_code :html, < -h1 { - font-size: 20px; - border-bottom: 1px solid #cccccc; -} - -p { - padding: 10px; - background-color: papayaWhip; -} - -HTML - message <<-MARKDOWN -When you save and refresh your browser, you should see the styles you added: - - - -The `type` and `media` attributes inside of the ` - HTML - message <<-MARKDOWN - -* A CSS tag looks like this when it's a link: - - MARKDOWN - source_code :html, <<-HTML - - HTML -end - -insert 'consider_deploying_to_github' - -next_step "add_more_elements" diff --git a/sites/en/frontend/make_columns.step b/sites/en/frontend/make_columns.step deleted file mode 100644 index 9979ca5c1..000000000 --- a/sites/en/frontend/make_columns.step +++ /dev/null @@ -1,49 +0,0 @@ -goals do - message "These challenges will have you diving into the CSS side of things. Open up that layout.css file and take a look." - goal "Give your main content a border" - goal "Make two columns and line them up side by side" -end - -steps do - - step do - message "CHALLENGE: Find the div with the id 'main' in your HTML. See if you can give it a one-pixel border on its left hand side by modifying the existing stylesheet, 'layout.css'." - message "If you get hung up on what CSS property to use, see if you can look it up on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference)." - end - - step do - message "CHALLENGE: If you styled the #main div in the previous step by using a style rule like `#main { property: value; }`, see if you can come up with a second rule that could also apply the same style, but use a different selector." - message "Hint: You can select an element that's _inside_ of another element by listing one selector after another. The selector `.content div {}` would apply to any divs inside of an element with class `content`" - end - - step do - message "CHALLENGE: See if you can turn the page into a two-column layout. Make the 'nav' div the left column, and the 'main' div the right column." - message "Two hints: it may be helpful to give these divs a fixed width, and you may need the `float` property." - end - - message "" -end - -explanation do - - message <<-MARKDOWN - -## More CSS! - -For some great examples of the power of CSS, check out the [CSS Zen Garden](http://www.csszengarden.com/). It takes -the same HTML, but shows it with stylesheets from a bunch of different designers applied to -it. Here are two different designers' interpretations of the same HTML: - - - -### CSS Reference Sites - -* [Sitepoint](http://reference.sitepoint.com/css/elements-structural) -* [Mozilla Developer Network](https://developer.mozilla.org/en/CSS) - - MARKDOWN -end - -insert 'consider_deploying_to_github' - -next_step "basic_javascript" diff --git a/sites/en/frontend/resources.step b/sites/en/frontend/resources.step deleted file mode 100644 index 4e6f5c9d9..000000000 --- a/sites/en/frontend/resources.step +++ /dev/null @@ -1,16 +0,0 @@ -message <" - end - - step "Choose your operating system" do - option "Windows" do - message "On Windows, the easiest way to install git and set everything up is with the Rails Installer. " - span "Head over to our " - a "Rails Installer instructions", :href => "/installfest/windows", :class => 'link' - span " (courtesy the Rails workshop Installfest instructions). Come back at the end of the page. Do not make a Heroku account!" - important "For real: come back at the bottom of the page, after step 9!" - span "After getting done with RailsInstaller, come back here and " - a 'create a GitHub account', :href => "#github-account" - span "." - end - - option "Mac OS X" do - step "Check if Git is already installed" do - message "If you've been to a RailsBridge before, you might have git installed. Try the following" - console "git --version" - message "If you see something like the git version below, then you can return to the mini-installfest" - fuzzy_result "git version {FUZZY}2.x.x{/FUZZY}" - message "If you see something like `git: command not found` then proceed" - end - - step "Check if XCode is installed" do - message "Look in your Applications folder for an application called XCode." - message "If you see XCode, choose __Installing Homebrew__." - message "If you do __not__ see XCode, choose __Installing binary Git__." - - option_half "Installing Homebrew" do - div do - a "Instructions for Installing Homebrew", :href => "http://brew.sh/", :class => "link" - end - - message "After installing homebrew, use it to install git" - console "brew install git" - end - - option_half "Installing binary git" do - message "In another browser tab open the link below and download the latest (topmost) release of Git for OS X." - a "Git OS X Installer Downloads", :href => "http://code.google.com/p/git-osx-installer/downloads/list?can=3" - end - end - - step "Install a text editor" do - a "Download and install Sublime Text 2", :href => "http://www.sublimetext.com/2" - message "Install Sublime Text 2 by double clicking the file you downloaded, then dragging the Sublime Text 2 icon into the Applications folder. Finish up by clicking the eject icon for Sublime Text 2 in your finder window." - a "or install a different editor", :href => "/installfest/editors" - message "FYI: Sublime Text 2 is a paid program that you can download and try out for free. If you keep using Sublime Text 2 after the workshop, you'll need to buy a license. There are other editors available you can find on [our editors page](/installfest/editors)." - end - end - end - - a :name => "github-account" - step "Create a GitHub account" do - message "In your web browser open ." - message "GitHub is is a service for hosting and sharing source code with others. They also host static web pages for free! We'll be using them to put our web page up later today." - - message "Click the big blue signup button in the middle of the page. On the next page select a Free account. Make a note of your username, you'll be using it a lot." - - tip "A note about your password. In order to push to GitHub, you'll need to type your password in at the terminal. So make it something easy to remember and type but hard to guess." - end - - next_step "get_a_sticker" -end - diff --git a/sites/en/intermediate-rails/add_other_features_of_your_choosing.step b/sites/en/intermediate-rails/add_other_features_of_your_choosing.step deleted file mode 100644 index 83987c310..000000000 --- a/sites/en/intermediate-rails/add_other_features_of_your_choosing.step +++ /dev/null @@ -1,16 +0,0 @@ -message <<-MARKDOWN -What other features do you want? - -Suggestions: - -* Profile pages for users (enter user’s name or details, have it display alongside posts). -* Post/Comment history for individual users (on their profile page?). -* Easy user profile pictures with [Gravatar](https://gravatar.com/). -* Add login options with [Omniauth](https://github.com/intridea/omniauth), including Twitter, Facebook, Github, Google, and more. - * Check out the Devise [documentation for integrating with Omniauth](https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview). -* Fiddle with the layout of the show page so it doesn't look bad. If it looks bad. It probably looks great. -* Perhaps fancier post markup with Markdown or something similar. -* Deploy to Heroku and send your message board to all your friends! - -## ...and that's that! Good luck! Make more things! Come back again! -MARKDOWN diff --git a/sites/en/intermediate-rails/add_pages_to_create_and_look_at_individual_posts.step b/sites/en/intermediate-rails/add_pages_to_create_and_look_at_individual_posts.step deleted file mode 100644 index 08f09b0fa..000000000 --- a/sites/en/intermediate-rails/add_pages_to_create_and_look_at_individual_posts.step +++ /dev/null @@ -1,58 +0,0 @@ -requirements do -message <<-MARKDOWN -* The user should be able to create a post with a title, author, date published, and content. The author should be the current user. -* The complete post should appear on its own page (aka its show page). -* If the user doesn't submit all required fields, they should see some error messaging, but shouldn't lose any of their work. -MARKDOWN - table do - tr do - td do - h2 'Create View', class: 'centered' - end - td do - h2 'Show View', class: 'centered' - end - end - tr do - td do - img class: 'noborder', src: 'img/create_post.png' - end - td do - img class: 'noborder', src: 'img/show_post.png' - end - end - end -end - -discussion do -message <<-MARKDOWN -* How do you create a resource? What parameters do you need to pass? -* Then: what did rails make for you when you used the resource generator? Find all the new files. Maybe even list them out on a whiteboard. -* How do you associate a user with a post? - * What did you have to put in the migration to create posts? - * How is this association communicated to the User and Post models? - * How will you associate the current user with a post when you create it? -* What's the difference between the `new` and `create` methods in the posts controller and how do these relate to the form to create a new post? -MARKDOWN -end - -tools_and_references do -message <<-MARKDOWN -* RailsGuides - Active Record Associations: . -* RailsGuides - Form Helpers, section 2.2: -* RailsGuides - Routes - CRUD, Verbs, and Actions: . -* RailsGuides - Active Record Validations and Callbacks: -MARKDOWN -end - -hints do -message <<-MARKDOWN -* Rails has some built in ways to associate one model with another. See the RailsGuides link above for hints on how to make a user the owner of a post! -* Don't hand code the form! You don't have to! Rails will help. See RailsGuide link above! -* Rails has a built-in way to note when something was stored in the database. Probably handy for showing the date / time a post was created. -* For now, we're going to use the user's email address when displaying a post's author. You can add names or other identifiers later! (Also, even though you're going to get the current user's email address from the User model, you'll still need a user parameter for your Post resource.) -* You need a `create` method to store your post data - scroll down a little bit in this section of the Getting Started guide for very helpful information and to see an example of a create method: . -MARKDOWN -end - -next_step "make_a_posts_index_page" diff --git a/sites/en/intermediate-rails/add_replying.step b/sites/en/intermediate-rails/add_replying.step deleted file mode 100644 index 0df64b867..000000000 --- a/sites/en/intermediate-rails/add_replying.step +++ /dev/null @@ -1,42 +0,0 @@ -requirements do -message <<-MARKDOWN -* The user should see a 'New Reply' link or button on a post's show page which takes them to a form. The form should include the title of the post being replied to. -* The user should be able to create a new reply to a post using the 'New Reply' form. -* The user should see all the replies to a post on the post’s show page. -* If the user doesn't submit all required fields, they should see some error messaging, but they shouldn't lose any of their work. -MARKDOWN - table do - tr do - td do - h2 'Create View', class: 'centered' - end - td do - h2 'Show View', class: 'centered' - end - end - tr do - td do - img class: 'noborder', src: 'img/create_reply.png' - end - td do - img class: 'noborder', src: 'img/show_replies.png' - end - end - end -end - -discussion do -message <<-MARKDOWN -* What is a nested resource? When is it appropriate and how does it help? -* How do the `RepliesController` and `PostsController` interact? -* What should happen to the routes file for this nesting business to work? -MARKDOWN -end - -tools_and_references do -message <<-MARKDOWN -* RailsGuides - Rails Routing from the Outside In http://guides.rubyonrails.org/routing.html -MARKDOWN -end - -next_step "inline_replying_on_a_post" diff --git a/sites/en/intermediate-rails/commands.md b/sites/en/intermediate-rails/commands.md deleted file mode 100644 index 83810651c..000000000 --- a/sites/en/intermediate-rails/commands.md +++ /dev/null @@ -1,79 +0,0 @@ -## Ruby - -Open an interactive Ruby terminal (type 'exit' to quit) - - irb - -Run a ruby program named FILENAME.rb - - ruby FILENAME.rb - -Installs a gem called GEMNAME - - gem install GEMNAME - -Installs gems listed in the `Gemfile` - - bundle install - -## Rails - -Create a new rails project called `NAME` - - rails new NAME - -Auto-generate routes (this can also be done manually) - - rails generate scaffold - -Create a new [Rails model] - - rails generate model MODELNAME - -Update the database to match what you have described in your code - - rake db:migrate - -Run the application locally (Ctrl-C to quit) - - rails server - -Start an interactive Ruby session that knows about your Rails models (type 'exit' to quit) - - rails console - -Print the routes for your application - - rake routes - -## Browser - -Go to the root page of your rails application - - http://localhost:3000 - -## Git - -Creates a new git repository in your current directory. - - git init - -Add the current directory, and all sub directories, to your git repository. - - git add . - -Tells you what you've added, deleted, and changed between your current directory and you local git repository. - - git status - -Prints the difference between FILENAME and what is in your local git repository. - - git diff FILENAME - -Commit the files you've added to the local repository. - - git commit -m "Describe what has changed, and why" . - -Push *committed* changes to the remote server. - - git push diff --git a/sites/en/intermediate-rails/create_a_new_rails_app_with_a_static_home_page.step b/sites/en/intermediate-rails/create_a_new_rails_app_with_a_static_home_page.step deleted file mode 100644 index 59e49917d..000000000 --- a/sites/en/intermediate-rails/create_a_new_rails_app_with_a_static_home_page.step +++ /dev/null @@ -1,35 +0,0 @@ -requirements do -message <<-MARKDOWN -* You should have a new rails app with with a static home page that's under your control. Make sure the controller for this page is called **HomeController**. -* You, the developer, should explain to a teacher, TA, or fellow student how Rails knows to render the home view. -MARKDOWN - img class: 'noborder', src: 'img/static_home_page.png' -end - -discussion do -message <<-MARKDOWN -* In order to have a static home page, you will need a route, a controller, a view. Discuss! - * Seriously. If you don't discuss this stuff, things will be SO much harder. -* Generators! Rails has lots of them. Try exploring the output of `rails generate`. -* We’re not using `rails generate scaffold` in this curriculum. Because you will generate all your Models, Views and Controllers yourself, this will force you, to do more understanding-building brain work. The teacher/TAs can perhaps comment on what they would do in the real world and their thoughts on the excellence of this choice for learning-purposes. -* What do you need to add to your home controller (after you've made it) to have a static home page? -* How does the home/index.html.erb view file relate to the layouts/application.html.erb view file? -* What’s the significance of yield in the application view? -* What does the home controller do? -MARKDOWN -end - -tools_and_references do -message <<-MARKDOWN -* RailsGuides - Setting the Application Home Page: . -* RailsGuides - controllers overview: . -MARKDOWN -end - -hints do -message <<-MARKDOWN -* If you have no idea what to put in your home controller, maybe try looking back at a past-Railsbridge app? Or another rails app you have lying about? -MARKDOWN -end - -next_step "install_devise" diff --git a/sites/en/intermediate-rails/creating_a_new_controller.md b/sites/en/intermediate-rails/creating_a_new_controller.md deleted file mode 100644 index b459ee313..000000000 --- a/sites/en/intermediate-rails/creating_a_new_controller.md +++ /dev/null @@ -1,79 +0,0 @@ -## Getting Started - -**1\.** Create your project - -**2\.** View your project in the browser. You should see a default page. - -## Create your Controller - -Controllers are classes that inherit from ApplicationController. - -Controllers in Rails have one or many **actions**. -Each action is defined as a method inside the controller. -Some standard actions are **index, create, new, edit, show, update,** and **destroy**. But you're not limited to using those names. - -We will start with index, which can be used to display the main page in your application. - -**3\.** Create your first controller called **HomeController**. - -Create a controller file in the app/controller folder. *The file should always be named with lower case letters and underscores.* - -``` -app/controllers/home_controller.rb -``` - -**4\.** Create your controller, with an empty index method. In the home_controller.rb file add: - -``` -class HomeController < ApplicationController - def index - end -end -``` - -## Create your View - -**5\.** Create your first view, to be associated with the `Home` controller and the `index` action. - -Create a new folder in app/views. *The folder name should always be lower case and the name of your controller.* - -``` -app/views/home -``` - -Create a file for your first action in the app/views/home folder. *The filename should always be lower case and the name of the action.* - -``` -app/views/home/index.html.rb -``` - -Each view created is associated with one controller action. You don't even really need to define a method in the associated controller: as long as the associated controller and route exist, Rails will pretend that the method exists, and is empty, and render as such. - -## Create your Route - -A **route** is a path that points to an action for a specific controller. This controller and action pair (often stylized as **controller#action**) also indicates which view should be used, via the file naming conventions mentioned above. - -**6\.** Edit routes.rb so that the base url points to your application entry point - -``` -root 'home#index' -``` - -NOTE: This says that your base url (i.e. root) should use the `index` action of the `home` controller. The view used will be the file in the app/views/home folder with name `index` (e.g. app/views/home/index.html.erb). - -Each subsequent route should be defined in a similar way: - -``` -get 'about' => 'home#about' -``` - -NOTE: This says that the base url with /about on the end will direct to the `about` action in the `home` controller. - -## Test your new Controller - -**7\.** Go back to your project in the browser and confirm that on the root path you now see the content from your index.html.erb file instead of the default Rails welcome page. - -**8\.** Add an `about` action to the Home controller and test that you can see it at the /about path in the web browser. - - - \ No newline at end of file diff --git a/sites/en/intermediate-rails/img/create_post.png b/sites/en/intermediate-rails/img/create_post.png deleted file mode 100644 index 34664b6bc..000000000 Binary files a/sites/en/intermediate-rails/img/create_post.png and /dev/null differ diff --git a/sites/en/intermediate-rails/img/create_reply.png b/sites/en/intermediate-rails/img/create_reply.png deleted file mode 100644 index 9f8ebcd66..000000000 Binary files a/sites/en/intermediate-rails/img/create_reply.png and /dev/null differ diff --git a/sites/en/intermediate-rails/img/header.png b/sites/en/intermediate-rails/img/header.png deleted file mode 100644 index cb2b50638..000000000 Binary files a/sites/en/intermediate-rails/img/header.png and /dev/null differ diff --git a/sites/en/intermediate-rails/img/inline_reply.png b/sites/en/intermediate-rails/img/inline_reply.png deleted file mode 100644 index 446da115e..000000000 Binary files a/sites/en/intermediate-rails/img/inline_reply.png and /dev/null differ diff --git a/sites/en/intermediate-rails/img/post_index.png b/sites/en/intermediate-rails/img/post_index.png deleted file mode 100644 index f0732dee9..000000000 Binary files a/sites/en/intermediate-rails/img/post_index.png and /dev/null differ diff --git a/sites/en/intermediate-rails/img/request-cycle.jpg b/sites/en/intermediate-rails/img/request-cycle.jpg deleted file mode 100644 index 53ac5ed5b..000000000 Binary files a/sites/en/intermediate-rails/img/request-cycle.jpg and /dev/null differ diff --git a/sites/en/intermediate-rails/img/show_post.png b/sites/en/intermediate-rails/img/show_post.png deleted file mode 100644 index 41c83e72c..000000000 Binary files a/sites/en/intermediate-rails/img/show_post.png and /dev/null differ diff --git a/sites/en/intermediate-rails/img/show_replies.png b/sites/en/intermediate-rails/img/show_replies.png deleted file mode 100644 index fa6d23278..000000000 Binary files a/sites/en/intermediate-rails/img/show_replies.png and /dev/null differ diff --git a/sites/en/intermediate-rails/img/static_home_page.png b/sites/en/intermediate-rails/img/static_home_page.png deleted file mode 100644 index dab159e02..000000000 Binary files a/sites/en/intermediate-rails/img/static_home_page.png and /dev/null differ diff --git a/sites/en/intermediate-rails/inline_replying_on_a_post.step b/sites/en/intermediate-rails/inline_replying_on_a_post.step deleted file mode 100644 index f74d53888..000000000 --- a/sites/en/intermediate-rails/inline_replying_on_a_post.step +++ /dev/null @@ -1,22 +0,0 @@ -requirements do -message <<-MARKDOWN -* The user should see the 'New Reply' form at the bottom of a Post's show page. -* The user should be able to make replies using the inlined 'New Reply' form. -* Error handling (trying to reply without any content) should still work the same way as when replying was a separate page. -MARKDOWN -img class: 'noborder', src: 'img/inline_reply.png' -end - -discussion do -message <<-MARKDOWN -* What needs to happen in the posts controller to allow inline replying? What needs to happen in the view? -MARKDOWN -end - -tools_and_references do -message <<-MARKDOWN -* RailsGuides - Form Helpers, section 2.2: -MARKDOWN -end - -next_step 'add_other_features_of_your_choosing' \ No newline at end of file diff --git a/sites/en/intermediate-rails/install_devise.step b/sites/en/intermediate-rails/install_devise.step deleted file mode 100644 index dc5d3272e..000000000 --- a/sites/en/intermediate-rails/install_devise.step +++ /dev/null @@ -1,46 +0,0 @@ -requirements do -message <<-MARKDOWN -* The user should be able to create an account and log in. -* The user should see a prompt to log in if they aren't logged in. -* Once logged in, the user should see a static page with some kind of greeting. -* The page should display the logged-in user's email address and a link to log out. -* You, the developer, should explain to a teacher, TA, or fellow student how Rails knows to render the home view. -MARKDOWN -end - -important do - h2 "Timebox It!" - p "The purpose of this section is to allow users to log in to your app and demonstrate how to add external libraries like Devise using the Gemfile. If you find yourself needing to write more than a couple of lines of code to make that happen, you may have gone too far. Talk to a TA!" -end - -discussion do -message <<-MARKDOWN -* What is devise? -* What files did devise add to your rails app? -* Someone Who Knows: explain how to read the output of the command `rake routes`. What does it give you? How is it helpful? -* How will you add the log out link? What's the syntax for a DELETE action? -* You're going to be editing your application layout to add error messaging. If you haven't already, discuss the relationship between the application layout and all the other views you'll be creating. -MARKDOWN -end - -tools_and_references do -message <<-MARKDOWN -* Devise: authentication magic! Learn more about it here: https://github.com/plataformatec/devise - * In the readme, scroll down to "Getting Started." You'll need to add it to your gem file. If you don't remember how, ask your neighbor! - * You probably don't want to just start typing commands from the devise readme. You probably want to read through that whole section first. (i.e., don't skip bundle!) -MARKDOWN -end - -hints do -message <<-MARKDOWN -* Readme files are your best friends! Love them! -* The convention for naming models is to capitalize the first letter, like: User. -* When you run `rails generate devise:install`, you get five instructions for things to configure. 3 & 4 are good to do. -* The routes file goes through many common types of routes in the comments. This is also your friend. -* Devise has some magic that will help you with your logout link. Run `rake routes` and look for a route that helps you sign out. -* You'll probably want to show the current user's email address only if they are presently signed in, right? Devise has a helper for you. -* Optional: any time you generate a model in rails, you can use Rails Console to look at that model's methods and behavior interactively. -MARKDOWN -end - -next_step "make_it_pretty_with_bootstrap" diff --git a/sites/en/intermediate-rails/intermediate-rails.step b/sites/en/intermediate-rails/intermediate-rails.step deleted file mode 100644 index bf2d7e1c8..000000000 --- a/sites/en/intermediate-rails/intermediate-rails.step +++ /dev/null @@ -1,40 +0,0 @@ -message <<-MARKDOWN -# Let's build a message board! - -## Assumptions made by this curriculum -* You’ve gone through the standard RailsBridge installfest and have successfully completed the Get a Sticker step. -* You’ve gone through the RailsBridge Suggestotron curriculum at least once before, or maybe a couple of times, or maybe you feel decently comfortable with Rails for some other reason. -* You want to learn more Rails!!! - -## Goals -* Make a thing! -* Understand what the models, views, and controllers of a Rails app do and how they work together. -* Get more comfortable using error messages as guideposts and not as scary things. - -## What’s Going to Happen? -* We’re going to build a message board system, where there are posts on the front page and you click through to see the original post plus discussion below. - -* We’ve divided this into challenges: - * Challenge 1: create a new rails app with a static home page - * Challenge 2: install devise - * Challenge 3: make it pretty with bootstrap - * Challenge 4: add pages to create and look at individual posts - * Challenge 5: make a posts index page - * Challenge 6: add replying - * Challenge 7: inline replying on a post - * Challenge ∞: other features of your choice - -* Each time you get your app into a functional state, before adding any more features, COMMIT TO GIT! The new features will probably break things, which is neat, but you’ll want to be able to roll back to a prior version if necessary. - -MAJORLY IMPORTANT NOTE: We called the sections challenges because they are challenging! This curriculum will be most fun as a collaboration — talk things through with your teacher, TAs, and other students. This is a very different style of curriculum than Suggestotron, so don’t be discouraged if you aren't quite sure what to do next. - -## How to use this curriculum -* Challenges are the big chunks of stuff to work on at a given time. These are gated by requirements — once you (or your group) has completed a set of requirements, go on to the next set. -* Requirements in this curriculum are not entirely divorced from what a requirement is in the agile software development methodology — things that should be in the application as defined by whoever is designing/deciding things about the product. Except here, we’ve also thrown in some non-application requirements, like the ability to explain a concept to a peer. -* Discussions are led by the teacher; this is the closest this curriculum gets to lecture-y teaching. -* Hints are what they sound like, as are Tools & References. - -* Teachers only!: there's a teaching guide at http://bit.ly/int-railsbridge-guide -MARKDOWN - -next_step "create_a_new_rails_app_with_a_static_home_page" diff --git a/sites/en/intermediate-rails/make_a_posts_index_page.step b/sites/en/intermediate-rails/make_a_posts_index_page.step deleted file mode 100644 index 6f3557a45..000000000 --- a/sites/en/intermediate-rails/make_a_posts_index_page.step +++ /dev/null @@ -1,24 +0,0 @@ -requirements do -message <<-MARKDOWN -* The user should be able to see each post’s name, author, and date published on the overview page (aka the index page). -* The name of the post should link to the post show page. -* The index page should include a “New Post” link or button. -MARKDOWN - img class: 'noborder', src: 'img/post_index.png' -end - -discussion do -message <<-MARKDOWN -* Maybe now would be a good time to discuss Active Record! Can anyone explain it? -MARKDOWN -end - -tools_and_references do -message <<-MARKDOWN -* RailsGuides - Listing All Posts: http://guides.rubyonrails.org/getting_started.html#listing-all-posts - * Feel free to disregard the JSON stuff on this page, if you're so inclined. -* Bootstrap - Style that table! http://twitter.github.com/bootstrap/base-css.html#tables -MARKDOWN -end - -next_step "add_replying" \ No newline at end of file diff --git a/sites/en/intermediate-rails/make_it_pretty_with_bootstrap.step b/sites/en/intermediate-rails/make_it_pretty_with_bootstrap.step deleted file mode 100644 index 12579dc7c..000000000 --- a/sites/en/intermediate-rails/make_it_pretty_with_bootstrap.step +++ /dev/null @@ -1,58 +0,0 @@ -requirements do - message <<-MARKDOWN -* The site should use Bootstrap for a superfun modern look. -* When logged in, the user's email address should appear in the upper-right corner of a navigation bar. -MARKDOWN - img class: 'noborder', src: 'img/header.png' -end - -important do - h2 "Timebox It!" - p "The purpose of this section is to make your app a bit prettier and demonstrate how to add CSS frameworks like Bootstrap using the Gemfile. Don't get snagged on the details of getting your CSS exactly right, unless that's valuable to you." -end - -discussion do -message <<-MARKDOWN -* Chrome developer tools / Firefox Firebug plugin — how to use ’em! -* What’s Bootstrap and (optional) why is everyone totally in love with it (or at least using it all over the place)? -* Maybe review the home/index.html.erb view file as it relates to the layouts/application.html.erb view file again, and where you might want to make some edits to take advantage of bootstrap. -* Someone should explain how erb works — you'll be using it to show the user email address in right side -MARKDOWN -end - -tools_and_references do -message <<-MARKDOWN -* A gem for Bootstrap!! Here's where to get it https://github.com/twbs/bootstrap-sass -* Bootstrap docs: http://getbootstrap.com/css/ -* Here's a link to the navbar section: http://getbootstrap.com/components/#nav -* Reference for HTML and CSS: http://www.htmldog.com/ -MARKDOWN -end - -hints do -message <<-MARKDOWN -* Don't forget to read the readme! -* There are a couple of Bootstrappy ways to move text around — look for "Component alignment" in the docs. -* Devise has a helper method for accessing the current user - go back to the devise readme to find it. -MARKDOWN -end - -h1 "Really Big Hint" -message "If you can't get the right HTML mojo for the Bootstrap nav bar, or want to move on quickly to the next page, here's some code you can drop into your layout (after installing Bootstrap!) that should work. The code should go immediately after your <body> tag." -pre <<-MARKDOWN - -MARKDOWN - -message "***You still have to add code to show the real logged in user and add a real log out button!***" - -next_step "add_pages_to_create_and_look_at_individual_posts" diff --git a/sites/en/intermediate-rails/mvc_overview.md b/sites/en/intermediate-rails/mvc_overview.md deleted file mode 100644 index 17808b1ce..000000000 --- a/sites/en/intermediate-rails/mvc_overview.md +++ /dev/null @@ -1,24 +0,0 @@ -## Explaining MVC and Records - -![MVC Overview](/intro-to-rails/img/mvc.png) - -Rails implements a very specific notion of the **Model/View/Controller** pattern, which guides how you structure your web applications. - -

      Model

      - -* saves data to the database -* accesses data from the database -* bridge between the database and objects - -

      View

      - -* display the data for human (or machine) consumption -* webpages are views - -

      Controller

      - -* acts as the glue between the models and the views -* combines data from multiple models -* summarizes and filters data - -In MVC, models, views, and controllers have very specific jobs. Separating responsibilities like this make it easy to maintain and extend rails applications. When responsibilities become muddied it gets much harder to debug issues and add new functionality. \ No newline at end of file diff --git a/sites/en/intermediate-rails/the_request_cycle.md b/sites/en/intermediate-rails/the_request_cycle.md deleted file mode 100644 index 432c3b9c5..000000000 --- a/sites/en/intermediate-rails/the_request_cycle.md +++ /dev/null @@ -1,12 +0,0 @@ -### How does typing in a URL result in a web page being rendered? Here's a rough overview. - - - -1. The user types in a URL, hoping for a cool website. -1. After the DNS gets resolved (a topic for another day), the request hits a web server, which asks Rails what it's got. -1. Rails goes to the routes file first, which takes the URL and calls a corresponding controller action. -1. The controller goes and gets whatever stuff it needs from the database using the relevant model. -1. With the data the controller got from the model, it uses the view to make some HTML. -1. Rails packages up the response and gives it to the web server. -1. The web server delivers the response to the browser to display a cool website to the user. - diff --git a/sites/en/intro-to-rails/CRUD_with_scaffolding.step b/sites/en/intro-to-rails/CRUD_with_scaffolding.step deleted file mode 100644 index bd59c21b0..000000000 --- a/sites/en/intro-to-rails/CRUD_with_scaffolding.step +++ /dev/null @@ -1,107 +0,0 @@ ---- -goals { - - message <<-MARKDOWN - At the core, most database driven web sites are the same. They need to store records and provide a way to do the following: - - * **C**reate new records in the database - * **R**ead or show the records in the database - * **U**pdate existing records - * **D**estroy or delete records - - Because these 4 actions (CRUD) are so common, Rails includes the scaffold command to make creating them easier. - MARKDOWN -} - -steps { - - step { - console "rails server" - } - - step { - message "Point your browser to [http://localhost:3000/topics](http://localhost:3000/topics)" - message "You should see the \"Listing topics\" page with headers for title and description, and a link to add a new topic:" - - img src: "img/Seattle_topic_list_page.png", alt: "Screenshot of topic list page" - } - - step { - message <<-MARKDOWN - * Click "New Topic" - * Fill in the form and click "Create Topic" - * You should see a page showing your new topic with a message that your topic was successfully created: - MARKDOWN - - img alt: "Screenshot of topic detail page with confirmation message", src: "img/Seattle_topic_created.png" - } - - step { - message <<-MARKDOWN - * Click "Back" - * You should see the topic list again, this time with your new topic listed: - - ![Screenshot of topic list with new topic](img/Seattle_list_with_topic.png) - - * Try the "Show", "Edit", and "Destroy" links to see what they do - * You've created a basic database driven web site, congrats! - MARKDOWN - } -} - -explanation { - - message <<-MARKDOWN - How did all those pages get created and hooked together? The Rails scaffold did it for you. - - Let's take a closer look at some of the files Rails created: - - * `app/models/topic.rb` - * This file contains code for our topic model. If you look at it, - it's nearly blank. Creating, reading, updating, and deleting - records are built into Rails. - - * `app/views/topics` - * This folder contains all the views for our topics model. This is - where the code for the forms you used above is stored. Rails - created all of these pages as part of the scaffold. - * If you've written HTML before, many lines in the views should - look familiar. Rails views are HTML with some extra code added - to display data from the database. - - * `app/views/topics/index.html.erb` - * This is the code for the page that lists all the topics. - * Index is the name given to the "default" page for a web site or a - section of a web site. When you navigate to - http://localhost:3000/topics the topics index page is what is - sent to your computer. - - * `app/views/topics/show.html.erb` - * This is the page you get when you click the "Show" link on the - "Listing topics" page. - - * `app/views/topics/new.html.erb` - * This is the page you get when you click "New Topic". - - * `app/views/topics/edit.html.erb` - * This is the page you get when you click "Edit". - - * `app/views/topics/_form.html.erb` - * You may have noticed that the page for new topics and the page - to edit topics looked similar. That's because they both use the - code from this file to show a form. This file is called a - partial since it only contains code for part of a page. Partials - always have filenames starting with an underscore character. - - * Challenge question: Can you find the line of code in new.html.erb - and edit.html.erb that makes the form partial appear? - - * `app/controllers/topics_controller.rb` - * This is the controller file that Rails created as part of the scaffold - * If you look you'll see a method (a line beginning with - def) for each of the views listed above (except - `_form.html.erb`) - MARKDOWN -} - -next_step "setting_the_default_page" diff --git a/sites/en/intro-to-rails/add_the_project_to_a_git_repo.step b/sites/en/intro-to-rails/add_the_project_to_a_git_repo.step index 8b52a6464..674d1424a 100644 --- a/sites/en/intro-to-rails/add_the_project_to_a_git_repo.step +++ b/sites/en/intro-to-rails/add_the_project_to_a_git_repo.step @@ -67,4 +67,4 @@ By checking your application into git now, you're creating a record of your star MARKDOWN end -next_step "running_your_application_locally" +next_step "dog_scaffold" diff --git a/sites/en/intro-to-rails/allow_people_to_vote.step b/sites/en/intro-to-rails/allow_people_to_vote.step deleted file mode 100644 index 151a49a2a..000000000 --- a/sites/en/intro-to-rails/allow_people_to_vote.step +++ /dev/null @@ -1,85 +0,0 @@ -goals { - message "Now we're going to add a button people can click to cast a vote." -} - -steps { - - step "Add a new controller action for voting" do - message "Edit `app/controllers/topics_controller.rb` and add this method at the end of the controller, above the `private` keyword:" - - source_code :ruby, <<-RUBY - def upvote - @topic = Topic.find(params[:id]) - @topic.votes.create - redirect_to(topics_path) - end - RUBY - - message <<-MARKDOWN - * `@topic = Topic.find(params[:id])` finds the topic in the database with that id and stores it in the variable `@topic`. - * `@topic.votes.create` creates a new vote for the current topic and saves it in the database. - * `redirect_to(topics_path)` tells the browser to go back to `topics_path` (the topics list). - MARKDOWN - end - - step "Add a new route for voting" do - message "Open `config/routes.rb` and find the section that looks like this:" - source_code :ruby, <<-RUBY - resources :topics - RUBY - - message "Replace that line so it looks like this:" - source_code :ruby, <<-RUBY - resources :topics do - member do - post 'upvote' - end - end - RUBY - - message <<-MARKDOWN - Verify that upvote route was added successfully by checking the output of `rake routes` or [http://localhost:3000/rails/info](http://localhost:3000/rails/info). You should see a line that looks like this: - - ``` - Prefix Verb URI Pattern Controller#Action - upvote_topic POST /topics/:id/upvote(.:format) topics#upvote - ``` - MARKDOWN - end - - step "Add the button to the view" do - - message "Edit `app/views/topics/index.html.erb` so that the bottom loop looks like this:" - - source_code :erb, <<-HTML - <% @topics.each do |topic| %> - - <%= topic.title %> - <%= topic.description %> - <%= pluralize(topic.votes.count, "vote") %> - <%= button_to '+1', upvote_topic_path(topic), method: :post %> - <%= link_to 'Show', topic %> - <%= link_to 'Edit', edit_topic_path(topic) %> - <%= link_to 'Destroy', topic, method: :delete, data: { confirm: 'Are you sure?' } %> - - <% end %> - HTML - - message <<-MARKDOWN - * `pluralize(topic.votes.count, "vote")` displays the number of votes the topic has, plus the word "vote" or "votes" accordingly. - * `button_to '+1'` creates an HTML button with the text "+1". - * `upvote_topic_path(topic)` creates the appropriate URL for the action we want to invoke. In this case, we want to upvote the current topic. - * `upvote_topic_path(topic)` would return `/topics/42/upvote` (if topic.id was 42) - * `method: :post` ensures we do the create action of CRUD, not the read action. - MARKDOWN - end - - step "Confirm your changes in the browser" do - message "Go back to and play." - message "Revel in the fact that you didn't have to restart the server to see these changes. Hawt, no?" - end -} - -insert 'consider_deploying' - -next_step "redirect_to_the_topics_list_after_creating_a_new_topic" diff --git a/sites/en/intro-to-rails/clean_up_links_on_the_topics_list.step b/sites/en/intro-to-rails/clean_up_links_on_the_topics_list.step deleted file mode 100644 index 4c33b2723..000000000 --- a/sites/en/intro-to-rails/clean_up_links_on_the_topics_list.step +++ /dev/null @@ -1,44 +0,0 @@ -goals { - - message "Our app is nearly done! The main topics listing page is pretty busy. There are a lot of links that aren't necessary." - - message "Let's clean up the topics list page by doing the following:" - - goal "Remove the 'show' link" - goal "Remove the 'edit' link" - goal "Change 'destroy' to 'delete'" -} - -steps { - step "Remove the 'show' and 'edit' links" do - message "Open `app/views/topics/index.html.erb` and remove these two lines:" - source_code :erb, <<-HTML -<%= link_to 'Show', topic %> -<%= link_to 'Edit', edit_topic_path(topic) %> - HTML - end - - step "Change 'destroy' to 'delete'" do - - message "Change the line with the word 'Destroy' to this:" - source_code :erb, "<%= link_to 'Delete', topic, method: :delete, data: { confirm: 'Are you sure?' } %>" - end - - step "Confirm your changes" do - - message "Now save your file and try reloading in your browser to see the changes." - end -} - - -explanation { - message <<-MARKDOWN - * The two links we removed were show and edit. We did this because the title now links to the show page and from the show page you can reach the edit page. - - * The second change we made was to make the link text 'Delete' instead of 'Destroy'. - MARKDOWN -} - -insert 'consider_deploying' - -next_step "credits_and_next_steps" diff --git a/sites/en/intro-to-rails/creating_a_migration.step b/sites/en/intro-to-rails/creating_a_migration.step deleted file mode 100644 index da81c8759..000000000 --- a/sites/en/intro-to-rails/creating_a_migration.step +++ /dev/null @@ -1,47 +0,0 @@ -goals { - - model_diagram header: 'Topics', fields: %w(id title description) - - message "The suggestotron has a list of topics that people can vote on. We'll store our topics in the database. In this step you'll do the following:" - - goal "Create a simple *Table* in the database for topics with a title and a description" - goal "Automatically generate the corresponding *Scaffold* in Rails (namely, the *Model*, the *View*, and the *Controller*)." - -} - -steps { - - step { - console "rails generate scaffold topic title:string description:text" - message <<-MARKDOWN -* `generate scaffold` tells Rails to create everything necessary to get up and running with topics. -* `topic` tells Rails the name of the new model. -* `title:string` says that topics have a title, which is a "string". -* `description:text` says that topics have a description which is a "text". (What's the difference between "string" and "text"? Basically "text" is for strings that might be very long.) - - MARKDOWN - message "If you want, take some time to poke around the files listed in this step. You can learn about them in the [Rails Architecture](rails_architecture) page." - link "rails_architecture" - } - - step { - console "rake db:migrate" - message "This tells Rails to update the database to include a table for our new model." - } -} - -explanation { - - h2 "Rake" - message <<-MARKDOWN -`rake` (**r**uby m**ake**) is a tool that allows you to run small Ruby programs (**tasks**) that you use often in your application. - -Here, `rake db:migrate` is a task provided by the Rails framework. It uses the migration file we just created (`db/migrate/201xxxxxxxxxxx_create_topics.rb`) to change the database. Database migration files can be crucial to code collaboration. - - MARKDOWN - - tip "You can run `rake -T` to see a list of all the `rake` commands your app currently responds to, along with a short description of each task." -} - - -next_step "CRUD_with_scaffolding" diff --git a/sites/en/intro-to-rails/credits_and_next_steps.step b/sites/en/intro-to-rails/credits_and_next_steps.step deleted file mode 100644 index ac41c8088..000000000 --- a/sites/en/intro-to-rails/credits_and_next_steps.step +++ /dev/null @@ -1,39 +0,0 @@ -message < Datatypes: Visual Guide" + +goals do + goal "Add more information to our dogs table" + message "Now that we have a table full of dogs with names, we'd like to add some more information! Just having a list of names isn't that interesting. But we know lots of things about our dogs -- age, color, date they entered the shelter, whether or not they're fixed -- that we'd like to have available for our potential adopters. + +In this module, we will learn how to add fields to a database table, and we will learn a bit about the data types that are our options. A _data type_ refers to the way we define the field in our database table, which indicates what kind of values can then be stored in that field. For example, when we named our dogs in the last module, we used the data type `string`, which refers to anything that can be put in quotes (like `\"Fido\"` or `\"hello world\"` or `\"My, that's a cute dog you have there!\"`). But for things like age or shelter entrance date, an `integer` or `date` data type will be more appropriate." +end +steps do + step "Add a field to the database to store dogs' ages" do + console "rails g migration AddAgeToDogs age:integer" + console "bundle exec rake db:migrate" + explanation do + message "When you first generated your `dogs` table, you put `name:string` in your generating code -- this created for you a field in your `dogs` table called `name` that stores `string` values. + +A string is a common type of value used in programming -- a short amount of text that can be contained within quotes. So `\"Fido\"` is a string, `\"Hello World\"` is a string, `\"asdf!1!eleventyone\"` is a string. + +An integer is another common type of value that is more appropriate to use for the dog's age. +As you may remember from math class, an integer is any number without a fractional part -- e.g. `1`, `0`, `205`, `-53`, etc. + +By using `age:integer` when generating your migration, you added a field called `age` that stores `integer` values; just like by using `name:string` earlier, you added a field called `name` that stores `string` values. + +[This reference page](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html#method-i-column) lists the data types that we can use in Rails migrations -- it's a good idea to become familiar with most of these options. +" + end + end + step "Edit your controller to add `age` to the permitted parameters" do + message "Open `/app/controllers/dogs_controller.rb` and change the line:" +message "```ruby +params.require(:dog).permit(:name) +```" +message "to" + +message "```ruby +params.require(:dog).permit(:name, :age) +```" + explanation do + message " This is telling our controller code what parameters to accept for the `dog` object. + +This means that if we send part of the `DogsController` a request which asks to change or set a dog's `name` or `age`, the controller will pass those along; but if we ask to change a dog's `admin_status` or `fblrg`, the controller will not allow this. + +Why is this important? Because it's easy for someone with bad intentions to send whatever parameters they want to our request. So we don't want to allow just arbitrary parameters to be set by request -- then malicious users could do things like send `is_admin=true` when updating their own account, and gain access to everything! + +[This page](http://api.rubyonrails.org/classes/ActionController/Parameters.html) discusses how the latest versions of Rails handle parameters -- the default behavior is the most secure, i.e. not accepting any parameters not explicitly allowed in the code. So each time we add a new field to our model, if we want the existing `edit`/`new`/`update` code to accept input for that field, we need to add it to the permitted parameters." + +tip "If you are using Rails 3.x, you can skip this step." + end + end + step "Edit `_form.html.erb` to add an input field for the dog's age" do + message "add to `/app/views/dogs/_form.html.erb`:" + message "```erb +
      + <%= f.label :age %>
      + <%= f.number_field :age %> +
      +```" + explanation do + message " + Now, when you go to edit one of your dogs, you'll be able to set their age! +`number_field` is a Rails form helper; this creates a field that accepts numbers in the form the user sees in their browser. + +[Here] (http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html) you can view a list of the various form helpers available in Rails. +" + end + end + step "Edit the index page to display the dog's age" do + message "edit `/app/views/dogs/index.html.erb` + +add `Age` after `Name` +add `<%= dog.age %>` after `<%= dog.name %>` +" + end +end +message " Now, we should be fully prepared to add ages to our dogs. Here's what we did: + +* add a field in the database to store the age +* tell the controller to accept the :age parameter +* add a field in the form where we can enter the age +* add a field in the index to display the age + +Go into your application and make sure you can add and view dogs' ages! (If you can't, review the above to see where you went wrong, and/or ask a TA.) +Now is also a good time to commit your changes and push to Heroku. +" +message " +Next: learn about some other datatypes! Use the [Rails documentation ](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html#method-i-column) to review your options. +Try to choose the right datatypes for: + +* the date a dog arrived in the shelter +* the color of the dog +* a description of the dog's temperament +* whether or not the dog is fixed + +Then, try to add those fields to your application, using the same steps we used to add age to our dogs; make sure you can edit each of these fields and see them listed on your homepage. + +Ask a TA or work with another student if you run into issues! + +" +next_step 'pictures' diff --git a/sites/en/intro-to-rails/deploying_to_heroku.step b/sites/en/intro-to-rails/deploying_to_heroku.step index db9067f0d..9063472dd 100644 --- a/sites/en/intro-to-rails/deploying_to_heroku.step +++ b/sites/en/intro-to-rails/deploying_to_heroku.step @@ -1,3 +1,7 @@ +goals do + goal "Deploy your application to Heroku so you and your friends can keep a dog list on the internet." +end + h2 do span "If you haven't yet deployed to Heroku, start at " a 'First-time setup', href: '#first-time' @@ -26,7 +30,7 @@ gem 'sqlite3' message "**Remove that line** and replace it with:" - source_code :ruby, <<-RUBY + message "```ruby group :development, :test do gem 'sqlite3' end @@ -35,9 +39,18 @@ group :production do gem 'pg' gem 'rails_12factor' end - RUBY - end +``` " + + explanation do + message "The `Gemfile` manages our dependencies on other people's code and libraries. `group :development, :test` means these gems will only be used in your development/test environments (in this case, your local machine). `group :production` means these gems will only be used in your production environment (in this case, Heroku). + + `sqlite` and `pg` are two different kinds of database software. Heroku only supports `pg`, which is why you need to make this change; this is a Heroku-specific quirk. Rails tries to be database-agnostic, so most of the time you won't even need to know what kind of database you're using." + tip "You may have heard of or even worked with *MySQL*, especially if you've done some programming before -- MySQL is a database software just like `sqlite` and `pg`, and it's pretty common. Generally, you can use MySQL with Rails; but today, we're just working with `sqlite` and `pg`." + + end + end + step "Apply the Gemfile changes" do console "bundle install --without production" message "Every time the `Gemfile` changes, you need to run ``bundle install`` for the changes to be processed. The processed version of the changes is stored in another file called ``Gemfile.lock``." @@ -50,9 +63,13 @@ git add . git commit -m "Changed Gemfile for Heroku" SHELL tip "There is a period after the word add in the first line." + explanation do + message "Git is back! You are updating your git repository with your gemfile changes. This is important to do before the next step, because the state of your git repository will be the state of your heroku project." + end end end + a name: 'every-time' situation "Every time" do step "Commit any pending changes to git" do @@ -65,14 +82,21 @@ git add . git commit -m "Some helpful message for your future self" SHELL message "Your commit message should reference whatever your outstanding -changes are: something like \"Added votes to the topics index\"." +changes are: something like \"Added ages to dogs\"." end step "Push changes to Heroku" do console "git push heroku master" message "This takes all changes you've committed locally and pushes them to Heroku." - end + explanation do + message "`git push` sends a copy of your git history and your code somewhere else -- in this case, the Heroku servers. + + `heroku` here is the name of the place to send the code. `master` is the name of the branch -- `master` is the default when you have only one git branch, and multiple branches are beyond today's project. + Usually `git push` just sends a copy of the code; Heroku does something extra, by deploying the code and running it on a webserver every time you push a new version. +" + end + end step "Run database migrations on Heroku" do console "heroku run rake db:migrate" message "This tells Heroku to run your migrations on its database, like @@ -80,34 +104,27 @@ running `rake db:migrate` locally." message "Heroku's database is separate from the one on your computer, which means it needs to be updated every time you make changes to the structure of your database." - message "It also means that you'll not see any of the data you entered into + message "It also means that you won't see any of the data you entered into the `sqlite3` database on your computer." end step "Visit your application" do console "heroku open" message "This opens the new application in your browser." +explanation do + + message "This opens up a browser window showing your real, live app on the real, live internet! + + You may notice that there are no dogs here, even if you added dogs on your local copy. This is because the Heroku copy of your app has a separate database from your local project. They run on the same code, but have their own databases. + + Try adding/removing some dogs on Heroku and on your local machine; then compare your Heroku dogs to your local dogs. The two instances of your app show a totally different set of dogs, even though they use the same code to store and display them! + +Make sure that you can visualize this difference: the contents of the database are separate from the code running the application. + " +end end end -explanation do - message <<-MARKDOWN - First, we had to do some work to make Heroku happy with our application. This -required updating the `Gemfile` and bundling. - - * The `Gemfile` is a list of all the Ruby libraries your application needs. - What we've declared here is that we want to use the `sqlite3` library - while we're developing on our computer (the development group) but when - deploying to Heroku (the production group) we want to use the `pg` library, - which is made for the type of database that Heroku uses. - - * Bundler is how Ruby projects keep track of the gems that they use. We told - Bundler what we wanted to use in the `Gemfile`, now we need to make sure those - gems are installed. Since we don't have the type of database Heroku does, we - skip the production gems. Don't worry though! Bundler still logs them so - Heroku will install them when they get your code. - MARKDOWN - message "You should be able to deploy your application any time it's in a good, working state. Your typical workflow will look like:" img src: "img/workflow.png", alt: "Diagram showing git workflow of making changes, committing them, and pushing to Heroku.", style: "border: none" ol do @@ -116,4 +133,8 @@ required updating the `Gemfile` and bundling. li { message "(repeat)" } end message "Any time your changes are committed, you should feel free to `git push heroku master` and boom! Your changes are live!" -end + + + message "Now would be a good time to take a stretching break; also, you can send your Heroku url to your friends, who can add their own dogs to your database and marvel at this cool thing you made!" + +next_step 'datatypes' diff --git a/sites/en/intro-to-rails/dog_scaffold.step b/sites/en/intro-to-rails/dog_scaffold.step new file mode 100644 index 000000000..53f0027a0 --- /dev/null +++ b/sites/en/intro-to-rails/dog_scaffold.step @@ -0,0 +1,175 @@ +goals do + goal "Make an application that lists all the dogs in the shelter, and allows the user to create, edit, or delete dogs." + +end +steps do + # step "Create a new Rails application" do + # console "rails new railsbridge_dogs" + # explanation do + # message "This creates a folder called 'railsbridge_dogs' that will hold all the code for your application." + # message "A whole lot of files are generated! These files are the code that makes up the Rails framework. When you execute this command, you will see a list in your terminal of all the files that were just created." + # message "You will be editing some of these files, and creating some new ones as we go." + # end + # end + # step "Check your application into Git version control" do + # console "git init; git add .; git commit -a -m 'first commit'" + # message "(Make sure you are in the railsbridge_dogs directory when you do this.)" + # explanation do + # message "We initialized a git repository, added all our files to it, and committed." + # message "This means we have stored the state of files as of this commit -- with our 'first commit' message. This state is now accessible via our git history, no matter what changes we make." + # message "So we can always get back to this pristine app if we want!" + # end + end + step "Use scaffolding to create the basic files needed to create, read, update, and delete `dog` resources" do + console "rails g scaffold dog name:string" + tip "`rails g` is short for `rails generate`; whenever you see `rails g` or `rails generate`, you're seeing a command that is going to create some files." + explanation do + message "The Rails framework includes code to create *scaffolding*: scaffolds are files with the basic code needed to create, edit, and delete resources." + message "Usually, you will edit your scaffolds significantly to create your final product." + message "Scaffolding creates a lot of files (as you can see in your terminal output.) +Some important ones include: + +* database migrations: `db/migrate/[date_and_time]_create_dogs.rb` + +`dogs name:string` means our table is called `dogs` and has a value called `name` for each row + +* models: `app/models/dog.rb` +* views: `app/models/views/dogs` +* controllers: `app/controllers/dogs_controller.rb` + +The basic CRUD features for `dogs` are already in the model, view, and controller files. +" + end + end + step "Use migrations to create a database that stores your `dogs`" do + console "bundle exec rake db:create; bundle exec rake db:migrate +" + +explanation do + message <<-MARKDOWN +`rake` (**r**uby m**ake**) is a tool that allows you to run small Ruby programs (**tasks**) that you use often in your application. + +Here, `rake db:migrate` is a task provided by the Rails framework. It uses the migration file we just created (`db/migrate/201xxxxxxxxxxx_create_topics.rb`) to change the database. Database migration files can be crucial to code collaboration. + + MARKDOWN + + tip "You can run `rake -T` to see a list of all the `rake` commands your app currently responds to, along with a short description of each task." + + message "`db:create` created a database called `railsbridge_dogs` on your local development machine (usually, there is one database per application)" + message "`db:migrate` ran any pending migrations from the `db/migrate` folder; in this case, the `create_dogs` migration. You should see terminal output explaining what happened: the `dogs` table was added to your database. (Usually, there is one table per type of resource in the application.) +" + end + end + step "View your app in your browser" do + step "Start the server" do + console "rails server" + + explanation do + message "`rails server` started a webserver running on your computer that will turn your code into webpages" + message "While the server is running, whatever you type in that terminal tab +will be ignored." + message "To get back to the terminal, you can stop the server by typing +`Control-c`." + result <<-STOPPING_RAILS_SERVER +^C[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] INFO going to shutdown ... +[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] INFO WEBrick::HTTPServer#start done. +Exiting + STOPPING_RAILS_SERVER + explanation do + message "`rails server` ran your application locally just like Heroku will be running it on their servers." + message "This provides a very simple means to see your changes before you commit and push them to Heroku." + message "`Control-c` is a way of closing or cancelling terminal programs. Since +`rails server` runs forever, you need to interrupt it with `Control-c`." +end + + end + end + step "Visit the app" do + message "Open your web browser and go to `http://localhost:3000/dogs`" + message "In the browser, you should see an empty list of dogs. What you are seeing is the `dogs/index.html.erb` view." + end +tip "If you killed the server with `Control-c` in the last step, you may need to run `rails server` in your terminal again before you can see the app in your browser." + end + step "Create a new dog" do + message "Follow the 'new' link to go to the 'New Dog' page, and fill out the form. Then, go 'back' to your list of dogs." + explanation do + message "You just used your application's web interface to add a new record to your database. Now, you can see this record in the list of all `dog` records." + end + end + step "Edit this dog" do + message "Follow the 'edit' link next to your dog to go to the 'Edit Dog' page; change the dog's name in the form. Then, go 'back' to your list of dogs. +" + explanation do + message "You just used your application's web interface to change a record in your database. The changes should be reflected on your list of dogs." + end + message "Play around with creating, reading, updating, and deleting your dog records -- asking a TA if you need clarification on anything -- until you feel confident that you understand what this application does." + end + + step "Edit the view that displays your `dog` list" do + message "Edit the file `app/views/dogs/index.html.erb`; put `` tags on either side of the code `<%= dog.name %>`. +" + explanation do + message "Rails views use a combination of HTML and ERB (which is a kind of Ruby code)." + message "Anything within a `<%= %>` is interpreted as Ruby code when the page is printed; for example, `<%= dog.name %>` will print whatever is in the `name` column for that `dog` record. + +Anything within a `<% %>` is interpreted as Ruby code, but not printed out. For example, this page uses a *loop* to print out the same information for each `dog` record: the loop begins with `<% for @dogs.each %>` and ends with `<% end %>`. + +All of the code within the loop gets executed once for each record stored in the `@dogs` array variable. Since you added the `` tags within the loop, the boldness is applied to all the dogs in your database. (Add some more dogs to your database if you have less than two dogs right now, so you can see the loop in action.) +" + end + end + +# step "Deploy to Heroku" do +# step "Commit your changes" do +# console "git add .; git commit -a -m 'added dogs'" +# explanation do +# message "This may look familiar! You set up your Git repository earlier; now, you've added your new files and committed your changes. This puts a new save point for your code into your Git repository. In the terminal output, you should see a list of the files that have been added or changed since your last commit -- several of them should look familiar! + +# Committing your code also sets you up for deploying to Heroku, which will use this save point to deploy your code. +# " +# end +# end +# step "Create a heroku instance" do +# console 'heroku create' +# message "Use the browser to open the URL heroku gave you." +# explanation do +# message "Heroku is a hosting service that will enable you to have your code running on the internet. This command sets up a heroku instance that will store and serve your app." +# end +# end +# step "Edit your Gemfile" do +# message "Edit the file `Gemfile`, and replace the line `gem 'sqlite3'` with: " +# message "``` ruby +# group :development, test do +# end +# ``` " +# end +# step "Update your local gems" do +# console 'bundle install --without production' +# explanation do +# message "This will update your locally installed gems based on the `Gemfile` (which you just changed). You should see a list of the gems that are being installed output in the console." +# end +# end +# step "Commit your changes again" do +# console "git add .; git commit -a -m 'Gemfile change'" +# end +# step "Send code to heroku" do +# console 'git push heroku master' +# " +# end +# end +# step "Run database migrations on the heroku server" do +# console 'heroku run rake db:migrate' +# message "This does the same thing that `db:migrate` did on our local machine (create a database, and add and format the `dogs` table); but this time, on Heroku's servers. +# " +# end +# step "Open your new app" do +# console 'heroku open' +# explanation do +# end +# end +# end + + # end + + message "When you're ready:" +next_step 'setting_the_default_page' diff --git a/sites/en/intro-to-rails/getting_started.step b/sites/en/intro-to-rails/getting_started.step index bcfd44fdb..6492d9a23 100644 --- a/sites/en/intro-to-rails/getting_started.step +++ b/sites/en/intro-to-rails/getting_started.step @@ -1,3 +1,5 @@ +message "Getting Started: Visual Guide" + img src: "img/Start_page.png", alt: "Screenshot of a Ruby on Rails default home page" goals do @@ -23,37 +25,28 @@ steps do end step do - message "Check to see if you have any existing suggestotron apps from a previous workshop." - console "ls" - message "`ls` stands for **l**i**s**t." - message "It lists the contents of the current directory." - message "If you have any old suggestotron apps in that list, you can remove them to prevent hiccups:" - console "rm -rf suggestotron" - end - - step do - console "rails new suggestotron" + console "rails new railsbridge_dogs" message "`rails new` creates a new Rails project with the name you give." - message "In this case we told it to create a new project called `suggestotron`. We'll go into detail on what it created shortly." + message "In this case we told it to create a new project called `railsbridge_dogs`. We'll go into detail on what it created shortly." message "This will print a lot of stuff to the screen and can take a while to finish." end step do - console "cd suggestotron" - message "`cd suggestotron` makes suggestotron our current directory." + console "cd railsbridge_dogs" + message "`cd railsbridge_dogs` makes railsbridge_dogs our current directory." end step do message <<-MARKDOWN -Open the suggestotron folder as a project in your text editor. +Open the `railsbridge_dogs` folder as a project in your text editor. In **Sublime Text 2**, you can use the `Project > Add Folder to Project...` menu option: ![Sublime Text Project menu screenshot](img/sublime_add_folder_to_project.png) -Select your `suggestotron` folder from the file picker that opens. If everything works out Sublime should show the directories of your app in a tree structure on the left: +Select your `railsbridge_dogs` folder from the file picker that opens. If everything works out Sublime should show the directories of your app in a tree structure on the left: -![Screenshot of Suggestotron project folder tree in Sublime Text](img/sublime_project_as_folder.png) +![Screenshot of project folder tree in Sublime Text](img/sublime_project_as_folder.png) MARKDOWN end @@ -90,6 +83,8 @@ Select your `suggestotron` folder from the file picker that opens. If everything end message "There is a lot more that `rails new` created. Probably enough to fill a book, so we're going to ignore them for now." + message "These files are part of the Rails *framework*, and most of them are written in the Ruby *programming language*. A framework is a collection of already-written code designed to make your life easier!" + end next_step "add_the_project_to_a_git_repo" diff --git a/sites/en/intro-to-rails/hooking_up_votes_and_topics.step b/sites/en/intro-to-rails/hooking_up_votes_and_topics.step deleted file mode 100644 index 550676cbb..000000000 --- a/sites/en/intro-to-rails/hooking_up_votes_and_topics.step +++ /dev/null @@ -1,127 +0,0 @@ -goals { - - div(style: 'margin: 0 auto; width: 250px; height: 120px;') do - model_diagram header: 'Topics', fields: %w(id title description), style: "float: left;" - div(style: 'float: left; position: relative; width: 60px; height: 100px;') do - div(class: 'arrow-left', style: 'left: 0; top: 30px;') - div(class: 'horiz-line', style: 'left: 5px; top: 37px; width: 25px;') - div(class: 'vert-line', style: 'left: 30px; top: 38px; height: 25px;') - div(class: 'horiz-line', style: 'right: 0; top: 62px; width: 30px;') - end - model_diagram header: 'Votes', fields: %w(id topic_id), style: "float: left;" - end - - message "Because there is an explicit relationship between a topic and its - votes, we need to specify that. In this step, we'll explicitly - declare the relationship between votes and topics." -} - -steps { - - step "Teach the Topic model about Votes" do - message "Edit `app/models/topic.rb` so that it looks like this:" - - source_code :ruby, <<-RUBY -class Topic < ActiveRecord::Base - has_many :votes, dependent: :destroy -end - RUBY - end - - step "Teach the Vote model about Topics" do - message "Edit `app/models/vote.rb` so that it looks like this:" - source_code :ruby, <<-RUBY -class Vote < ActiveRecord::Base - belongs_to :topic -end - RUBY - end - - step "Play around with Topics and Votes in the Rails console" do - message "First, make sure you've made at least one topic on the site." - - console_with_message "Next, open a Rails console in a terminal window:", "rails c" - - result <<-CONSOLE - $ rails c - Loading development environment (Rails 4.2.0) - 2.1.5 :001 > - CONSOLE - - message "At the console, try the following things" - - console_with_message "See how many topics exist:", "Topic.count" - - console_with_message "Save the first topic into a variable:", "my_topic = Topic.first" - - tip "`my_topic` here could have been any variable name, but we'll stick with `my_topic` for consistency." - - console_with_message "Change the title of that topic to something else:", "my_topic.update_attributes(title: 'Edited in the console')" - - console_with_message "Add a vote to that topic:", "my_topic.votes.create" - - console_with_message "See how many votes that topic has:", "my_topic.votes.count" - - console_with_message "Remove a vote from that topic:", "my_topic.votes.first.destroy" - - message "Note that the things you can do to **Model classes** (like **Topic** and **Vote**), differ from the things you can do to **Model instances** (like my\\_topic, here). **my\\_topic.votes** is an **association**, and here behaves mostly like a model class." - - div do - half_width "Model class / association methods" do - ul class: 'no-style-type' do - li "Topic.first" - li "Topic.last" - li "Topic.all" - li "Topic.count" - li "Topic.find_by_id(5)" - li "Topic.destroy_all" - li "my_topic.votes.count" - li "my_topic.votes.create" - li "my_topic.votes.destroy_all" - end - end - - half_width "Model instance methods" do - ul class: 'no-style-type' do - li "my_topic.title" - li "my_topic.title = 'New title'" - li "my_topic.update_attributes(title: 'New title')" - li "my_topic.save" - li "my_topic.save!" - li "my_topic.destroy" - li "my_topic.votes.first.destroy" - end - end - end - - message <<-TEXT - An exhaustive list of things you can do to models and associations can be found in the Active Record Query Interface RailsGuide. - TEXT - end -} - -explanation { - - message <<-MARKDOWN - -`has_many` and `belongs_to`: - -* In Rails, relationships between models are called associations. -* Associations (usually) come in pairs. -* A topic will have many votes so we put `has_many :votes` in the - topic model. - * When you ask a topic for its votes, you get an array of votes - for that topic. -* A vote is for a particular topic, so we put `belongs_to :topic` - in the vote model. - * When you ask a vote for its topic, you get the topic for that - vote. - -It can still be important to clean up after yourself! `dependent: :destroy` - on `has_many :votes` means when a **Topic** gets destroyed, all - the **votes** that correspond to it will be destroyed, too. Without - `dependent :destroy`, those votes would live on the database forever. - MARKDOWN -} - -next_step "allow_people_to_vote" diff --git a/sites/en/intro-to-rails/intro-to-rails.step b/sites/en/intro-to-rails/intro-to-rails.step index 51df25b3c..86da7a53e 100755 --- a/sites/en/intro-to-rails/intro-to-rails.step +++ b/sites/en/intro-to-rails/intro-to-rails.step @@ -1,67 +1,24 @@ message <<-MARKDOWN ### Goal -To teach you Ruby on Rails we are going to use a "Real World" -example. You've decided to create a voting system for you and your -friends to play with. You've decided at a minimum, you'd like to -allow users to: +Today, we're going to learn the basics of creating and interacting with a database using the Rails framework and the Ruby language. A database is a way of storing structured information in a computer; usually, a database is organized into tables, where each table represents a kind of thing, each row represents an instance of that thing, -* view the topics sorted by number of votes -* vote on topics -* create, edit, and destroy topics +For now, we're just going to create one table, so we're just going to have one type of thing in our database. Choose a type of thing that your database will focus on. During this step, you will create a database that will store a list of things, and you will be able to view and edit your list of things on a webpage. You can work with the example scenario, any of the alternative scenarios, or any scenario you’d like to make up where having a list of things would be useful. -You've sketched up an initial screenshot of what you want it to look like: +EXAMPLE SCENARIO: You are making a list of adoptable dogs for an animal shelter. -![Browser window with topic titles that can be voted on, ordered by number of votes](img/finished_app.png) +ALTERNATIVE SCENARIOS: You are making a list of cities to consider relocating to; you are making a list of staff in your office; you are making a list of records in your record collection. -### Meta-Goal +If you want to be able to use the exact code from these instructions or from our example on GitHub, use the example scenario and create a list of dogs. If you’re up for a bit more challenge, use whatever scenario you’d like -- just make sure to use the right table and file names for your choice. E.g. for the animal shelter example, our table is named “dogs”; for the city example, you would use the same code but replace “dog/dogs” with “city/cities”. -When you have completed today's goal of getting the basic -application online you should understand: - -* Basic Ruby syntax -* How to try your Ruby code (IRB) -* How to go from requirements to a new working Rails application -* How to get your application online -* The basic tools a RoR developer uses (source control, editor, console, local server) - -### Schedule - -* 1-ish hour of Ruby -* 4-ish hours of Rails, broken up in 1-ish hour steps - -This is just a rough guideline, not a mandate. Some steps you'll go -over and some you'll go under. It'll all work out by the end of the -day. Probably. - -### Requirements - -We're going to be working with: - -* Ruby 2.1 or 2.2 installed via RVM (Mac or Linux) or RailsInstaller (Windows) -* Rails 4.2.x -* Bundler -* SQLite -* The text editor of your choice +### Before you get started, make sure you have everything installed correctly. Everything should be set up the night before during our install-fest. Please ensure you have everything working _before_ you -show up for RailsBridge on Saturday. +show up for RailsBridge on Saturday. *If you do not have an installation sticker by Saturday morning, you may not be able to participate.* -You can verify that you have everything working by trying this out in your terminal: +Check your installation here. -
      -$ irb
      ->> 1 + 2
      -=> 3
      ->> require "active_support"
      -=> true
      ->> exit
      -$
      -
      -
      - -If you can do that, you are probably good to go. MARKDOWN insert 'working_effectively_and_efficiently' @@ -98,4 +55,3 @@ end MARKDOWN next_step "ruby_language" - diff --git a/sites/en/intro-to-rails/make_the_topic_title_a_link.step b/sites/en/intro-to-rails/make_the_topic_title_a_link.step deleted file mode 100644 index b27772f59..000000000 --- a/sites/en/intro-to-rails/make_the_topic_title_a_link.step +++ /dev/null @@ -1,59 +0,0 @@ -goals { - message "Your friends recommended two changes for the site:" - goal "Don't show the description on the list page" - goal "Make the title a link and when it's clicked show the description" -} - -steps { - - - step("Remove the description") { - - message "Let's start by removing the description. Open `app/views/topics/index.html.erb` and delete the line that looks like this:" - - source_code :erb, "<%= topic.description %>" - - message "Also delete the line that looks like this:" - source_code :erb, "Description" - - message "If you save and try to load it in the browser you should see that the description no longer appears." - - } - - step("Make the title a link") { - - message "Now make the title a link by editing `app/views/topics/index.html.erb` (again) and replacing this line:" - - source_code :erb, "<%= topic.title %>" - - message "with this:" - - source_code :erb, "<%= link_to topic.title, topic %>" - } -} - -explanation { - - source_code :erb, "<%= topic.description %>" - - message "This line was getting the description using `.description` and just printing it out." - - source_code :erb, "Description" - - message " - `` stands for table header and everything between `` and - `` was being printed as a table header (bold). We removed it - since we removed the description and it would look funny to have the - header and the wrong thing below it." - - hr - - source_code :erb, "<%= link_to topic.title, topic %>" - - message " - Here's another use of `link_to` to create a link on the page. This - `link_to` creates a link using the text from the topic title and goes - to the topic show page." -} - -next_step "clean_up_links_on_the_topics_list" diff --git a/sites/en/intro-to-rails/one_to_many.step b/sites/en/intro-to-rails/one_to_many.step new file mode 100644 index 000000000..aaedaf24d --- /dev/null +++ b/sites/en/intro-to-rails/one_to_many.step @@ -0,0 +1,117 @@ +goals do +goal "You would like to be able to sort dogs by breed — but you don't want to just add a `breed` field as a string. You want `breeds` to be first-class resources in your app — you want to be able to store information about the breed in a `breeds` table, just like you stored information about dogs in your `dogs` table." +goal "For this, you will learn how to add a second table, and how to create an *association* between two tables." +end + +steps do +step do + message "Let's add a new table to our application! So far you have just one table, _dogs_." + console "rails g scaffold breed name:string description:text" + explanation do + message "Just like when you created the `dogs` table at the beginning of this project -- the scaffold generation here created views, models, and controllers for you. + +It also generated a migration that will add this table to the database for you with the fields you specified." + end +end +step do +message "Run the migration." +console "bundle exec rake db:migrate" +tip "Remember to start your rails server if it's not already running." +message "Now you should be able to visit `localhost:3000/breeds` and add some breeds and their descriptions. Clicking 'Show' next to a breed on the `/breeds` page should take you to the breed's *view*, where you can see its name and description." +explanation do + message "This process should be familiar and you should remember all the steps from earlier -- so far, setting up breeds via scaffolding has worked exactly the same as setting up dogs via scaffolding." +end +end +step do + message "So now you have breeds set up, but you don't have a connection between breeds and dogs. The next step is to *associate* the breeds and dogs tables." + message "For now, you will use a *one-to-many* relation." + message "Enter the `/app/models/dog.rb` file and, under the line `class Dog < ActiveRecord::Base`, add: " +message "```ruby +belongs_to :breed +``` +" +message "Next, edit the `/app/models/breed.rb` file, and, under the line `class Breed < ActiveRecord::Base`, add: " +message "```ruby +has_many :dogs +```" +explanation do + message "Adding these lines to `breed.rb` and `dog.rb` tells your application about the relationship between these two things. Now the application knows that each dog can be associated with one breed, and each breed can have many dogs associated with it." +end +end +step do + message "You will need to add a place for your database to store this information." + console "rails g migration AddBreedIdToDogs breed_id:integer" + console "rake db:migrate" + explanation do + message "The `breed_id` here is called a *foreign key*. For a one-to-many relationship, you only need to put the foreign key in one of your tables. Put the key in the table that `belongs_to` the other association. Each `breed` `has_many` `dogs`, and each `dog` has one unique `breed_id`, so you need to add `breed_id` to the `dogs` table in order to store this relationship. + Now, each `dog` can find its breed via the `breed_id` stored in its table — and each `breed` can find the `dogs` associated with it by looking for their matching `breed_id`. +" + end +end +step do + message "Open `/app/views/dogs/_form.html.erb` and add, above another one of the lines saying `
      `:" + message "```erb +
      + <%= f.collection_select(:breed_id, Breed.all, :id, :name) %> +
      +```" + message "Open `/app/controllers/dogs_controller.rb` and change your `dog_params` method to include `:breed`:" + message "```ruby + def dog_params + params.require(:dog).permit(:name, :age, :picture, :breed_id) + end +```" + tip "Don't forget to keep any fields you added earlier in `dog_params`, if your `dogs` have other attributes like `description` or `birthdate`." + message "Open `/app/views/dogs/index.html.erb` and add:" + message "```html +Breed +```" + message "after" + message "```html +Age +```" + message "and" + message "```erb + <%= dog.breed.try(:name) %> +```" + message "after" + message "```erb + <%= dog.age %> +```" + tip "Adding `.try` means that you won't get an error if any of your dogs' `breed` is nil -- which it will be for all of them, at first." + explanation do + message "This should remind you of the process of adding fields like `age` to your `dogs`! That process also involved adding a field to the form, adding a new permitted parameter in the controller, and adding a field to the display. Once you've completed this step, you should be able to edit your `dogs` to add breeds, and then see those breeds displayed in the main list. " + end +end +step do + message "Next, you want to let the shelter visitors browse dogs by the breed they would like. + +There are many possible ways of doing this; outlined here are the steps for using a list of links on the index page, which is similar to what you did in the 'Sorting' lesson. + +If you're feeling up for more challenge, see if you can use a different approach to allow people to view all the dogs in a breed — maybe by showing all the dogs in a breed on the breed's `show` page, or maybe by grouping the dogs on the `index` page by breed." + message "Open `/app/views/dogs/index.html.erb` and add breed links at the top:" + message "```erb + <% Breed.all.each do |b| %> + <%= link_to b.name, dogs_path(breed_id: b.id) %> + <% end %> +```" + message "Edit the `index` method in `/app/controllers/dogs_controller.rb`:" + tip "Your method may look slightly different if you skipped the 'Sorting' lesson or took a different approach there. The main change you want to make now is adding a check for the `breed_id` parameter and defining `@dogs` based on this." + message "```ruby + def index + if params[:sort_by] + @dogs = Dog.all.sort_by(¶ms[:sort_by].to_sym) + elsif params[:babies] + @dogs = Dog.all.select{|d| d.age < 5 } + elsif params[:pictures] + @dogs = Dog.all.select{|d| !(d.picture_url.blank?) } + elsif params[:breed_id] + @dogs = Breed.find(params[:breed_id]).dogs + else + @dogs = Dog.all + end + end +```" + tip "Bonus challenge! Can you figure out how to display the breed's description when dogs are filtered by breed?" +end +end diff --git a/sites/en/intro-to-rails/pictures.step b/sites/en/intro-to-rails/pictures.step new file mode 100644 index 000000000..6336e0021 --- /dev/null +++ b/sites/en/intro-to-rails/pictures.step @@ -0,0 +1,165 @@ +goals do + goal "What's a dog website without cute pictures? In this lesson you will learn to use gems to enable pictures on your website." + message "We will use the storage service Cloudinary and the image-modification gem CarrierWave to implement the most important part of a shelter website -- cute pictures!" +end +steps do + step do + message "Edit your `Gemfile` and add the line:" + message "```ruby +gem 'carrierwave'" + explanation do + message "This gem comes with built-in abilities to process, resize, and store images. When we configure this, we'll have a choice of whether our pictures are stored on our filesystem or in a cloud storage system." + end + end + step do + console 'heroku addons:add cloudinary' + tip do + message "Heroku might ask you to enter a credit card at this step; Cloudinary's starter plan is free and you _will not_ be charged." + end + + message "Edit your `Gemfile` and add the line:" + message "```ruby +gem 'cloudinary'" + explanation do + message "Since Heroku doesn't let us store images on our filesystem, we will need to use cloud storage. Cloudinary will give us a place to store our images where they'll be accessible via Heroku." + message "`heroku addons:add cloudinary` activates Cloudinary via your Heroku account." + end + end + step do + console 'bundle install' + explanation do + message "This step installs the `carrierwave` and `cloudinary` gems to your application." + end + console 'rails g uploader picture' + explanation do + message "`rails g` is short for `rails generate` (you can type either; they do the same thing). You may remember this from `rails g migration` or `rails g scaffold` -- a generator creates code files for you with some things pre-filled in." + message "The `uploader` generator was added to your app by the `carrierwave` gem; it generated the file `app/uploaders/picture_uploader.rb`, which you can now open to edit the configuration of your picture upload system." + end + end + step do + message 'Open `app/uploaders/picture_uploader.rb:`' + message 'Add the code' + message '```ruby + include Cloudinary::CarrierWave' + message 'under the line `class PictureUploader < CarrierWave::Uploader::Base`' + explanation do + message "This line tells the uploader to include some code from the `cloudinary` gem which enables CarrierWave to use Cloudinary as a storage system." + end + end + step do + message 'comment out this line:' + message '``` ruby +# storage :file +```' + message 'comment out these lines:' + message '```ruby +# def store_dir +# "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" +# end +```' + explanation do + message "If we were storing the pictures on our own filesystem, rather than in the cloud, we would want to keep these lines, and our pictures would be stored in the `uploads/` directory; however, since we're going to use Cloudinary instead, we'll need to comment out the lines about filesystem storage." + end + + message 'uncomment the line' + message "```ruby + version :thumb +``` " + explanation do + message "This line means the uploader will automatically create resized thumbnail versions of your pictures -- so that your users won't have to worry about what size their pictures are when they upload them." + end + end + + step do + message 'open `app/models/dog.rb`' + message 'add the code:' + message '```ruby +mount_uploader :picture, PictureUploader +```' +message "under the line" +message '```ruby +class Dog < ActiveRecord::Base +```' + console 'rails g migration add_picture_to_dogs picture:string' + console 'bundle exec rake db:migrate' + end + step do + message 'open `app/controllers/dogs_controller.rb`' + message 'Change the line in `dog_params` to:' + message '```ruby +require(:dog).permit(:name, :age, :picture) +```' + explanation do + message "Like when you added `age` to your dogs, you will need to specify in your controller that users are allowed to modify the dog's `picture`" + end + tip do + message "If you added any fields to your `dogs` table before *besides* `name` and `age`, make sure to keep those in the `permit` arguments so that they will keep working." + end + end + step do + message 'open `app/views/dogs/_form.html.erb` and, above one of the other lines saying `
      `, add:' + message '```ruby +
      + <%= f.label :picture %> + <%= f.hidden_field(:picture_cache) %> + <%= f.file_field(:picture) %> +
      +```' + explanation do + message "This adds a file upload field to the form where you create or edit dogs, so that you will be able to add a picture." + end + end + step do + message 'Open `app/views/dogs/index.html.erb` and add:' + message '```erb + + <%= image_tag(dog.picture_url(http://github.com/:thumb)) unless dog.picture_url(http://github.com/:thumb).blank? %> + +```' + explanation do + message "This line adds an image tag to your HTML, which looks for the URL to the thumbnail picture of your dog and uses that as the image source. + +Adding `unless dog.picture_url(http://github.com/:thumb).blank?` will keep your app from trying to display broken images for any dogs that haven't had pictures uploaded for them." + end + end + + step do + message 'Add `cloudinary.yml` to your `/config` folder.' + message "If you are logged in to Heroku in your browser, you should be able to download it from `http://cloudinary.com/console/cloudinary.yml`." +message "Save this file to the `/config` folder under your app's main folder." +message "The contents of `cloudinary.yml` should look something like this:" +message "```ruby +--- +development: + cloud_name: [something] + api_key: [something] + api_secret: [something] + enhance_image_tag: true + static_image_support: false +production: + cloud_name: [something] + api_key: [something] + api_secret: [something] + enhance_image_tag: true + static_image_support: true +test: + cloud_name: [something] + api_key: [something] + api_secret: [something] + enhance_image_tag: true + static_image_support: false +```" +end + +step do + message 'Commit your changes and push to heroku:' + console 'git commit -a -m "added pictures to dogs"' + console 'git push heroku master' + console 'heroku run rake db:migrate' + message "And now, you should be able to open your Heroku application, upload a picture to your dogs, and see that picture displayed in your list of dogs! + +Try exchanging Heroku URLs with other students in your group and uploading dog pictures to each others' apps. +" +end +end +next_step 'sorting' diff --git a/sites/en/intro-to-rails/rails_architecture.step b/sites/en/intro-to-rails/rails_architecture.step index 3d20142ee..8266ab110 100644 --- a/sites/en/intro-to-rails/rails_architecture.step +++ b/sites/en/intro-to-rails/rails_architecture.step @@ -1,6 +1,6 @@ goals { - goal "Create a database table for topics with a title and a description" + goal "Learn the basics of Rails architecture" message "In this step we'll learn a bit about Rails architecture. By the end of this step you should understand the following concepts:" @@ -51,3 +51,5 @@ Models, Views and Controllers each have specific jobs. Separating responsibilit If you want to learn more about Rails Architecture, you may want to watch this video explanation (3 min 30 sec) [MVC architecture *Youtube*](https://www.youtube.com/watch?v=eTdVkgF_Slo) MARKDOWN } + +next_step 'getting_started' diff --git a/sites/en/intro-to-rails/redirect_to_the_topics_list_after_creating_a_new_topic.step b/sites/en/intro-to-rails/redirect_to_the_topics_list_after_creating_a_new_topic.step deleted file mode 100644 index 8c60ed7c1..000000000 --- a/sites/en/intro-to-rails/redirect_to_the_topics_list_after_creating_a_new_topic.step +++ /dev/null @@ -1,74 +0,0 @@ -goals { - - message <<-MARKDOWN - When a user creates a new topic, or edits an existing topic, they are - currently shown a page with just that topic. For our voting app it makes - more sense that they would be taken back to the topic list. - - In this step we'll change the flow of our app so that the user is taken back to the topics list after they add a new topic (create) or - edit an existing topic (update). - MARKDOWN -} - -steps { - - step "Change the topics controller" do - - message "Open `app/controllers/topics_controller.rb` and look at the create method. " - - message "Find the line:" - - source_code :ruby, "format.html { redirect_to @topic, notice: 'Topic was successfully created.' }" - - - message 'and change `@topic` to `topics_path` like this:' - - source_code :ruby, "format.html { redirect_to topics_path, notice: 'Topic was successfully created.' }" - - message 'so that the file looks like this:' - - source_code :ruby, <<-RUBY -def create - @topic = Topic.new(topic_params) - - respond_to do |format| - if @topic.save - format.html { redirect_to topics_path, notice: 'Topic was successfully created.' } - format.json { render :show, status: :created, location: @topic } - else - format.html { render :new } - format.json { render json: @topic.errors, status: :unprocessable_entity } - end - end -end - RUBY - -message "In the same file, locate the update method. " - - message "Find the line:" - - source_code :ruby, "format.html { redirect_to @topic, notice: 'Topic was successfully updated.' }" - - - message 'and change `@topic` to `topics_path` like before:' - - source_code :ruby, "format.html { redirect_to topics_path, notice: 'Topic was successfully updated.' }" - end - - step "Confirm your changes" do - message "Look at ." - end -} - - -explanation { - - message <<-MARKDOWN - * `format.html { redirect_to topics_path, notice: 'Topic was successfully created.' }`: - * `format.html` means that the server should send HTML back to the browser - * `redirect_to topics_path` means show the **topics list page** when we're done creating or updating a topic - * `notice: 'Topic was successfully created/updated.'` puts the message into the flash so it will be displayed on the topics list - MARKDOWN -} - -next_step "make_the_topic_title_a_link" diff --git a/sites/en/intro-to-rails/ruby_language.step b/sites/en/intro-to-rails/ruby_language.step index 8b091bc4e..940519a70 100644 --- a/sites/en/intro-to-rails/ruby_language.step +++ b/sites/en/intro-to-rails/ruby_language.step @@ -1,3 +1,5 @@ +message "Before you start your Rails project, here is a brief introduction to the Ruby programming language." + goals do goal "Be able to use the basic building blocks of Ruby code" goal "Use IRB to run Ruby code" @@ -154,4 +156,4 @@ my_opinion(["apple", "pizza", "orange"]) end end -next_step "getting_started" +next_step "rails_architecture" diff --git a/sites/en/intro-to-rails/running_your_application_locally.step b/sites/en/intro-to-rails/running_your_application_locally.step deleted file mode 100644 index 87aa5467c..000000000 --- a/sites/en/intro-to-rails/running_your_application_locally.step +++ /dev/null @@ -1,38 +0,0 @@ -goals do - goal "Let's fire up the application locally" -end - - -steps do - step do - console "rails server" - message "This will print some stuff and stay running forever, printing more stuff -every time you visit a page in your app." - end - step do - text "Point your web browser to " - url "http://localhost:3000/" - message "See your web app actually running!" - end - - step do - message "While the server is running, whatever you type in that terminal tab -will be ignored." - message "To get back to the terminal, you can stop the server by typing -`Control-c`." - result <<-STOPPING_RAILS_SERVER -^C[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] INFO going to shutdown ... -[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] INFO WEBrick::HTTPServer#start done. -Exiting - STOPPING_RAILS_SERVER - end -end - -explanation do - message "`rails server` ran your application locally just like Heroku will be running it on their servers." - message "This provides a very simple means to see your changes before you commit and push them to Heroku." - message "`Control-c` is a way of closing or cancelling terminal programs. Since -`rails server` runs forever, you need to interrupt it with `Control-c`." -end - -next_step "creating_a_migration" diff --git a/sites/en/intro-to-rails/setting_the_default_page.step b/sites/en/intro-to-rails/setting_the_default_page.step index 89d70142b..9595f9489 100644 --- a/sites/en/intro-to-rails/setting_the_default_page.step +++ b/sites/en/intro-to-rails/setting_the_default_page.step @@ -5,7 +5,7 @@ goals { Currently when you go to you see the "Welcome aboard" message. - It would be easier to use our app if went directly to the topics list. + It would be easier to use our app if went directly to the dogs list. In this step we'll make that happen and learn a bit about routes in Rails. MARKDOWN @@ -18,28 +18,28 @@ steps { message "Search the file for **root**, it should be near the top if you are using Rails 4." - message "Uncomment the line that contains the example command by removing the `#` sign in front of it, and change it to read `root 'topics#index'`. When you are done the line should look like this:" + message "Uncomment the line that contains the example command by removing the `#` sign in front of it, and change it to read `root 'dogs#index'`. When you are done the line should look like this:" source_code :ruby, <<-RUBY -root 'topics#index' +root 'dogs#index' RUBY em do - message "(Rails 3.x users should add `root to: 'topics#index'` and will need to remove their `public/index.html` file)." + tip "(Rails 3.x users should add `root to: 'dogs#index'` and will need to remove their `public/index.html` file)." end end step "Confirm your changes" do - message "Go back to . You should be taken to the topics list automatically." + message "Go back to . You should be taken to the dogs list automatically." end } explanation { message <<-MARKDOWN - * `root 'topics#index'` is a Rails route that says the default - address for your site is `topics#index`. `topics#index` is the topics - list page (the topics controller with the index action). + * `root 'dogs#index'` is a Rails route that says the default + address for your site is `dogs#index`. `dogs#index` is the dogs + list page (the dogs controller with the index action). * Rails routes control how URLs (web addresses) get matched with code on the server. Similar to how addresses match with houses and apartments. @@ -56,15 +56,15 @@ explanation { $ rake routes Prefix Verb URI Pattern Controller#Action - topics GET /topics(.:format) topics#index - POST /topics(.:format) topics#create - new_topic GET /topics/new(.:format) topics#new - edit_topic GET /topics/:id/edit(.:format) topics#edit - topic GET /topics/:id(.:format) topics#show - PATCH /topics/:id(.:format) topics#update - PUT /topics/:id(.:format) topics#update - DELETE /topics/:id(.:format) topics#destroy - root GET / topics#index + dogs GET /dogs(.:format) dogs#index + POST /dogs(.:format) dogs#create + new_dog GET /dogs/new(.:format) dogs#new + edit_dog GET /dogs/:id/edit(.:format) dogs#edit + dog GET /dogs/:id(.:format) dogs#show + PATCH /dogs/:id(.:format) dogs#update + PUT /dogs/:id(.:format) dogs#update + DELETE /dogs/:id(.:format) dogs#destroy + root GET / dogs#index ```` This shows all the URLs your application responds to. The code that starts with colons are variables so :id means the id number of the record. The code in parenthesis is optional. @@ -77,14 +77,14 @@ explanation { ### Exploring Routes (optional) Now you can have a look at the paths that are available in your app. - Let's try looking at one of the topics routes we just generated. + Let's try looking at one of the dogs routes we just generated. Open up your Rails console and play: $ rails console - >> app.topics_path - => "/topics" - >> app.topics_url - => "http://www.example.com/topics" + >> app.dogs_path + => "/dogs" + >> app.dogs_url + => "http://www.example.com/dogs" `app` is a special object that represents your entire application. You can ask it about its routes (as we just did), play with its @@ -94,6 +94,6 @@ explanation { MARKDOWN } -insert 'consider_deploying' +message "Next, let's put your application on the real internet!" -next_step "voting_on_topics" +next_step "deploying_to_heroku" diff --git a/sites/en/intro-to-rails/sorting.step b/sites/en/intro-to-rails/sorting.step new file mode 100644 index 000000000..1287a4303 --- /dev/null +++ b/sites/en/intro-to-rails/sorting.step @@ -0,0 +1,113 @@ +steps do + + step do + message "In `dogs_controller#index`, we have `@dogs = Dog.all`. Let's explore a little further what this is and how we can manipulate it." + console 'rails console' + console 'Dog.all' + console 'Dog.all.class' + message "If you are using Rails 4, this will be `ActiveRecord::Relation`. While this is not *exactly* like an array, it is able to do most of the things that an array can do. We can use it like an array in many ways. Like an array, it is a manipulable list -- you can sort it, filter it, reverse it, etc. If you have programmed before in another language, these methods may be familiar." + message "The `.all` method comes from ActiveRecord, which is a Rails-specific way of interacting with databases." + tip 'It may be helpful to check out the [official Ruby documentation on Array methods](http://ruby-doc.org/core-2.2.0/Array.html)' + console "@dogs = Dog.all.sort_by{|d| d.name }" + explanation do + message "The `sort_by` method is passed a *block* -- this tells the method how to sort the objects. In this case, it sorts them alphabetically by name." + tip "ActiveRecord also gives you the `.order` method, which is not something you can use on a non-ActiveRecord array. You can optionally use this here instead of `.sort_by` -- [check out the documentation](http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-order)." + end + console "@dogs = Dog.all.select{|d| d.age < 5 }" + explanation do + message "The `select` method is also passed a *block* -- the `{|d| d.age < 5 }` part. This describes a function to use to select -- the whole thing will fill the `@dogs` variable with all of the dogs from `Dog.all` for which the block returns true. In this case, the block compares the dog's age with the number 5; it is true if the dog is under 5 years old. + +The `|d|` sets the temporary variable used in the comparison. You could have said `{|pickle| pickle.age < 5}` instead with the same results, but using `d` for dog makes it a lot easier to follow and remember what the code does! +" + end + end + + step do + message 'Open app/views/dogs/index.html.erb, and look at where the `@dogs.each` code is used.' + message "`@dogs` is `Dog.all` (set in `dogs_controller`), so it's an `ActiveRecord::Relation` -- again, this works basically like an array for your purposes." + message "`.each` is an array method that we can also use on `ActiveRecord::Relation` -- it executes the code within the block (either `do..end` or `{..}`) after `.each` once using each item from the list of `@dogs`. " + message "Look at the loop in the view, and make sure you can visualize how the code executes once for each dog in `@dogs`." + end + + step do + message 'Open `app/views/dogs/index.html.erb` and add links at the top to sort your dogs.' + message ' +```erb +

      Sort: + <%= link_to "by name", dogs_path(sort_by: :name) %> + <%= link_to "by age", dogs_path(sort_by: :age) %> +

      +

      Filter: + <%= link_to "dogs under 5yo", dogs_path(babies: :true) %> + <%= link_to "dogs with pictures", dogs_path(pictures: :true) %> +

      +```' + explanation do + message '`dogs_path` is Rails-ese for the URL of the dogs index page. You can pass arguments to this function, which are then used as parameters -- so `dogs_path(babies: :true)` will translate to `/dogs?babies=true`. Then, when the `dogs#index` action in the controller is run, `params[:babies]` will be true, so a filtered list will be displayed. + +Notice how you use `dogs_path` for all the sort/filter links, but pass different arguments each time -- and these arguments match the conditions you set up in your controller. +' +tip "These links won't do anything until you edit your controller in the next step." + end + end + + + step "Sorting and selecting" do + message "Open `/app/controllers/dogs_controller.rb`." + explanation do + message "The controller uses `Dog.all` to populate our list of dogs; if you change this to `Dog.all.sort_by{|d| d.name}`, you will get the same list of dogs, but this time in alphabetical order by name." + message "no changes to the view were made, but the dogs in the view are in a different order!" + end + message "Try: accepting a parameter in your controller, and sorting by that." + message " ```ruby +if params[:sort_by] + @dogs = Dog.all.sort_by{|d| d.send(params[:sort_by]) } + else + @dogs = Dog.all + end +``` +" + explanation do + message "`.send` takes a string and uses that as the method name -- so `d.send('name')` evaluates to `d.name`, and `d.send('age')` evaluates to `d.age`. So you can now sort your dogs by any of their attributes, by passing the name of that attribute as a parameter." + tip "Although you're using new parameters here, you don't need to add them to `params(:permit)` as you did when adding fields to the dogs; this is because these new parameters are being used to affect the order the dogs are displayed in, but have *no effect* on the dogs stored in the database." + end + end + + step 'Filtering dogs' do + message '```ruby +@dogs = @dogs.select{|d| d.age < 5 } +```' + explanation do + message "`select` takes a block, just like `sort_by`. In this block, you check for each dog `d` whether `d` has an `age` less than five; if and only if it does, it will stay in the new `dogs` variable. +" + end +message ' +```ruby +@dogs = @dogs.select{|d| !(d.picture_url.blank?) } +``` +' +explanation do + message "This statement, checking for dogs with pictures, is similar. Notice that you are specifically looking for dogs where the picture is not blank (`!` means not in programming), and that the `.picture_url.blank?` function is the same one you used in your view to avoid showing broken images." +end + end + step do + message ' +```ruby +def index + if params[:sort_by] + @dogs = Dog.all.sort_by{|d| d.send(params[:sort_by])} + elsif params[:babies] + @dogs = Dog.all.select{|d| d.age < 5 } + elsif params[:pictures] + @dogs = Dog.all.select{|d| !(d.picture_url.blank?) } + else + @dogs = Dog.all + end + end +````' + explanation do + message 'Putting this conditional code in your controller means that your users can pass parameters to your application to sort or filter your dogs -- the kind of sorting or filtering will be determined by the parameter.' + end + end +end +next_step 'one_to_many' diff --git a/sites/en/intro-to-rails/voting_on_topics.step b/sites/en/intro-to-rails/voting_on_topics.step deleted file mode 100644 index 6bc428b68..000000000 --- a/sites/en/intro-to-rails/voting_on_topics.step +++ /dev/null @@ -1,28 +0,0 @@ - -goals { - goal "Create a model for votes" - - model_diagram header: 'Votes', fields: %w(id topic_id) - - message "Every topic in suggestotron can be voted on. In order to count votes, we need to record votes. We'll add that table now." -} - -steps { - console <<-SHELL -rails generate model vote topic_id:integer -rake db:migrate - SHELL -} - -explanation { - message <<-MARKDOWN - * Just like before, we're creating a new model named "vote" - * The only thing really different is the integer we added called `topic_id`. - * `topic_id` is the data we need to draw the line between votes and topics. - * We didn't generate a full scaffold this time because we aren't - going to do the full CRUD for votes; they're just going to be - considered part of topics as-is. - MARKDOWN -} - -next_step "hooking_up_votes_and_topics" diff --git a/sites/en/javascript-snake-game/img/helloworld.png b/sites/en/javascript-snake-game/img/helloworld.png deleted file mode 100644 index aaef6f320..000000000 Binary files a/sites/en/javascript-snake-game/img/helloworld.png and /dev/null differ diff --git a/sites/en/javascript-snake-game/javascript-snake-game.step b/sites/en/javascript-snake-game/javascript-snake-game.step deleted file mode 100644 index 7e118c2fe..000000000 --- a/sites/en/javascript-snake-game/javascript-snake-game.step +++ /dev/null @@ -1,56 +0,0 @@ -# Lesson 1 - Building Snake in JavaScript - -markdown <<-MARKDOWN - Today, we're going to recreate the classic game snake in the Javascript - programming language. -MARKDOWN - -canvas id: 'chunk-game', height: 600, width: 800 - -script src: 'js/chunk.js' - -script src: 'js/snake.js' - -markdown <<-MARKDOWN - ### Download the tutorial - - Before you can start the tutorial, you'll need to download the tutorial to your computer - to edit the source code. - - ### Launch your programming environment - - When programming, you'll generally want these tools on hand: - - * Your browser to see the code running (I recommend Chrome) - * A text editor to change the code (I recommend Sublime) - * A javascript console so you can experiment and print out debugging - messages. This is built into your browser. - - Once you have these tools available, we need to open the files we'll be working with: - - * Open game/snake.js in your text editor - * Open game/index.html in your browser - * Open your browser's javascript console - * type `alert("hello world");` in your browser's javascript console and - dismiss the window that pops up - - - - ### Stop and reflect - - * The javascript console is one of the fastest ways to get feedback on - whether the code does what you expect. How else can you get feedback about whether - your code does what you expect? - * Why shouldn't you use Word or Google Docs to edit code? - - ### Helpful Links - - * How to launch dev tools in chrome. - * How to launch dev tools in internet explorer. - * How to launch dev tools in firefox. - * How to launch dev tools in safari. -MARKDOWN - -next_step 'lesson-2' diff --git a/sites/en/javascript-snake-game/js-snake-game-tutorial.zip-manifest b/sites/en/javascript-snake-game/js-snake-game-tutorial.zip-manifest deleted file mode 100644 index 33a706ca8..000000000 --- a/sites/en/javascript-snake-game/js-snake-game-tutorial.zip-manifest +++ /dev/null @@ -1,3 +0,0 @@ -zip_content/index.html -zip_content/snake.js -js/chunk.js diff --git a/sites/en/javascript-snake-game/js/chunk.js b/sites/en/javascript-snake-game/js/chunk.js deleted file mode 100644 index be6278b20..000000000 --- a/sites/en/javascript-snake-game/js/chunk.js +++ /dev/null @@ -1,102 +0,0 @@ -var CHUNK = { - canvasWidth: 800, - canvasHeight: 600, - pixelSize: 40, - KEY_MAPPING: { - 39: "right", - 40: "down", - 37: "left", - 38: "up" - }, - started: true, - attrs: {}, - gameHeight: function() { - return this.attrs.gameHeight || (this.attrs.gameHeight = this.canvasHeight / this.pixelSize); - }, - gameWidth: function() { - return this.attrs.gameWidth || (this.attrs.gameWidth = this.canvasWidth / this.pixelSize); - }, - canvas: function() { - if (CHUNK.context) { return CHUNK.context; } - var canvas = document.getElementById("chunk-game"); - CHUNK.context = canvas.getContext("2d"); - return CHUNK.context; - }, - executeNTimesPerSecond: function(tickCallback, gameSpeed) { - tickCallback(); - CHUNK.processID = setInterval(function() { - tickCallback(); - }, 1000 / gameSpeed); - }, - onArrowKey: function(callback) { - document.addEventListener('keydown', function(e) { - if (CHUNK.KEY_MAPPING[e.which]) { - e.preventDefault(); - callback(CHUNK.KEY_MAPPING[e.which]); - } - }); - }, - endGame: function() { - this.started = false - clearInterval(CHUNK.processID); - }, - draw: function(objects) { - if (this.started) { - CHUNK.clear(); - CHUNK.drawObjects(objects); - } - }, - clear: function() { - CHUNK.canvas().clearRect(0, 0, CHUNK.canvasWidth, CHUNK.canvasHeight); - }, - drawObjects: function(objects) { - var ui = this; - objects.forEach(function(object) { - object.pixels.forEach(function(pixel) { - ui.drawPixel(object.color, pixel); - }); - }); - }, - drawPixel: function(color, pixel) { - CHUNK.canvas().fillStyle = color; - var translatedPixel = CHUNK.translatePixel(pixel); - CHUNK.context.fillRect(translatedPixel.left, translatedPixel.top, CHUNK.pixelSize, CHUNK.pixelSize); - }, - translatePixel: function(pixel) { - return { left: pixel.left * CHUNK.pixelSize, - top: pixel.top * CHUNK.pixelSize } - }, - gameBoundaries: function() { - if (this.attrs.boundaries) { return this.attrs.boundaries; } - this.attrs.boundaries = []; - for (var top = -1; top <= CHUNK.gameHeight(); top++) { - this.attrs.boundaries.push({ top: top, left: -1}); - this.attrs.boundaries.push({ top: top, left: this.gameWidth() + 1}); - } - for (var left = -1; left <= CHUNK.gameWidth(); left++) { - this.attrs.boundaries.push({ top: -1, left: left}); - this.attrs.boundaries.push({ top: this.gameHeight() + 1, left: left }); - } - return this.attrs.boundaries; - }, - detectCollisionBetween: function(objectA, objectB) { - return objectA.some(function(pixelA) { - return objectB.some(function(pixelB) { - return pixelB.top === pixelA.top && pixelB.left === pixelA.left; - }); - }); - }, - randomLocation: function() { - return { - top: Math.floor(Math.random()*CHUNK.gameHeight()), - left: Math.floor(Math.random()*CHUNK.gameWidth()), - } - }, - flashMessage: function(message) { - var canvas = document.getElementById("chunk-game"); - var context = canvas.getContext('2d'); - context.font = '20pt Calibri'; - context.fillStyle = 'yellow'; - context.fillText(message, 275, 100); - } -} diff --git a/sites/en/javascript-snake-game/js/lesson-10.js b/sites/en/javascript-snake-game/js/lesson-10.js deleted file mode 100644 index 654c19803..000000000 --- a/sites/en/javascript-snake-game/js/lesson-10.js +++ /dev/null @@ -1,54 +0,0 @@ -var drawSnake = function(snakeToDraw) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableObjects = [drawableSnake]; - CHUNK.draw(drawableObjects); -} - -var moveSegment = function(segment) { - switch(segment.direction) { - case "down": - return { top: segment.top + 1, left: segment.left }; - case "up": - return { top: segment.top - 1, left: segment.left }; - case "right": - return { top: segment.top, left: segment.left + 1 } - case "left": - return { top: segment.top, left: segment.left - 1 } - default: - return segment; - } -} - -var segmentFurtherForwardThan = function(index, snake) { - if (snake[index - 1] === undefined) { - return snake[index]; - } else { - return snake[index - 1]; - } -} - -var moveSnake = function(snake) { - return snake.map(function(oldSegment, segmentIndex) { - var newSegment = moveSegment(oldSegment); - newSegment.direction = segmentFurtherForwardThan(segmentIndex, snake).direction; - return newSegment; - }); -} - -var advanceGame = function() { - snake = moveSnake(snake); - if (CHUNK.detectCollisionBetween(snake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - drawSnake(snake); -} - -var changeDirection = function(direction) { - snake[0].direction = direction; -} - -var snake = [{ top: 1, left: 0, direction: "down" }, { top: 0, left: 0, direction: "down" }]; - -CHUNK.executeNTimesPerSecond(advanceGame, 1); -CHUNK.onArrowKey(changeDirection); diff --git a/sites/en/javascript-snake-game/js/lesson-11.js b/sites/en/javascript-snake-game/js/lesson-11.js deleted file mode 100644 index 3a6f5efcc..000000000 --- a/sites/en/javascript-snake-game/js/lesson-11.js +++ /dev/null @@ -1,53 +0,0 @@ -var draw = function(snakeToDraw, apple) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableApple = { color: "red", pixels: [apple] }; - var drawableObjects = [drawableSnake, drawableApple]; - CHUNK.draw(drawableObjects); -} - -var moveSegment = function(segment) { - switch(segment.direction) { - case "down": - return { top: segment.top + 1, left: segment.left }; - case "up": - return { top: segment.top - 1, left: segment.left }; - case "right": - return { top: segment.top, left: segment.left + 1 } - case "left": - return { top: segment.top, left: segment.left - 1 } - default: - return segment; - } -} - -var segmentFurtherForwardThan = function(index, snake) { - return snake[index - 1] || snake[index]; -} - -var moveSnake = function(snake) { - return snake.map(function(oldSegment, segmentIndex) { - var newSegment = moveSegment(oldSegment); - newSegment.direction = segmentFurtherForwardThan(segmentIndex, snake).direction; - return newSegment; - }); -} - -var advanceGame = function() { - snake = moveSnake(snake); - if (CHUNK.detectCollisionBetween(snake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - draw(snake, apple); -} - -var changeDirection = function(direction) { - snake[0].direction = direction; -} - -var apple = { top: 8, left: 10 }; - -var snake = [{ top: 1, left: 0, direction: "down" }, { top: 0, left: 0, direction: "down" }]; - -CHUNK.executeNTimesPerSecond(advanceGame, 1); -CHUNK.onArrowKey(changeDirection); diff --git a/sites/en/javascript-snake-game/js/lesson-12.js b/sites/en/javascript-snake-game/js/lesson-12.js deleted file mode 100644 index 49e95dd61..000000000 --- a/sites/en/javascript-snake-game/js/lesson-12.js +++ /dev/null @@ -1,63 +0,0 @@ -var draw = function(snakeToDraw, apple) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableApple = { color: "red", pixels: [apple] }; - var drawableObjects = [drawableSnake, drawableApple]; - CHUNK.draw(drawableObjects); -} - -var moveSegment = function(segment) { - switch(segment.direction) { - case "down": - return { top: segment.top + 1, left: segment.left }; - case "up": - return { top: segment.top - 1, left: segment.left }; - case "right": - return { top: segment.top, left: segment.left + 1 } - case "left": - return { top: segment.top, left: segment.left - 1 } - default: - return segment; - } -} - -var segmentFurtherForwardThan = function(index, snake) { - return snake[index - 1] || snake[index]; -} - -var moveSnake = function(snake) { - return snake.map(function(oldSegment, segmentIndex) { - var newSegment = moveSegment(oldSegment); - newSegment.direction = segmentFurtherForwardThan(segmentIndex, snake).direction; - return newSegment; - }); -} - -var growSnake = function(snake) { - var indexOfLastSegment = snake.length - 1; - var lastSegment = snake[snake.length - 1]; - snake.push({ top: lastSegment.top, left: lastSegment.left }); - return snake; -} - -var advanceGame = function() { - snake = moveSnake(snake); - if (CHUNK.detectCollisionBetween([apple], snake)) { - snake = growSnake(snake); - apple = CHUNK.randomLocation(); - } - if (CHUNK.detectCollisionBetween(snake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - draw(snake, apple); -} - -var changeDirection = function(direction) { - snake[0].direction = direction; -} - -var apple = CHUNK.randomLocation(); -var snake = [{ top: 1, left: 0, direction: "down" }, { top: 0, left: 0, direction: "down" }]; - -CHUNK.executeNTimesPerSecond(advanceGame, 1); -CHUNK.onArrowKey(changeDirection); diff --git a/sites/en/javascript-snake-game/js/lesson-13.js b/sites/en/javascript-snake-game/js/lesson-13.js deleted file mode 100644 index 996a52591..000000000 --- a/sites/en/javascript-snake-game/js/lesson-13.js +++ /dev/null @@ -1,77 +0,0 @@ -var draw = function(snakeToDraw, apple) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableApple = { color: "red", pixels: [apple] }; - var drawableObjects = [drawableSnake, drawableApple]; - CHUNK.draw(drawableObjects); -} - -var moveSegment = function(segment) { - switch(segment.direction) { - case "down": - return { top: segment.top + 1, left: segment.left }; - case "up": - return { top: segment.top - 1, left: segment.left }; - case "right": - return { top: segment.top, left: segment.left + 1 } - case "left": - return { top: segment.top, left: segment.left - 1 } - default: - return segment; - } -} - -var segmentFurtherForwardThan = function(index, snake) { - return snake[index - 1] || snake[index]; -} - -var moveSnake = function(snake) { - return snake.map(function(oldSegment, segmentIndex) { - var newSegment = moveSegment(oldSegment); - newSegment.direction = segmentFurtherForwardThan(segmentIndex, snake).direction; - return newSegment; - }); -} - -var growSnake = function(snake) { - var tipOfTailIndex = snake.length - 1; - var tipOfTail = snake[snake.length - 1]; - snake.push({ top: tipOfTail.top, left: tipOfTail.left }); - return snake; -} - -var ate = function(snake, otherThing) { - var head = snake[0]; - return CHUNK.detectCollisionBetween([head], otherThing); -} - -var advanceGame = function() { - var newSnake = moveSnake(snake); - - if (ate(newSnake, snake)) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! You ate yourself!"); - } - - if (ate(newSnake, [apple])) { - newSnake = growSnake(newSnake); - apple = CHUNK.randomLocation(); - } - - if (ate(newSnake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - - snake = newSnake; - draw(snake, apple); -} - -var changeDirection = function(direction) { - snake[0].direction = direction; -} - -var apple = CHUNK.randomLocation(); -var snake = [{ top: 1, left: 0, direction: "down" }, { top: 0, left: 0, direction: "down" }]; - -CHUNK.executeNTimesPerSecond(advanceGame, 1); -CHUNK.onArrowKey(changeDirection); diff --git a/sites/en/javascript-snake-game/js/lesson-2.js b/sites/en/javascript-snake-game/js/lesson-2.js deleted file mode 100644 index 1840eec22..000000000 --- a/sites/en/javascript-snake-game/js/lesson-2.js +++ /dev/null @@ -1,4 +0,0 @@ -var snake = [{ top: 0, left: 0}]; -var drawableSnake = { color: "green", pixels: snake }; -var drawableObjects = [drawableSnake]; -CHUNK.draw(drawableObjects); diff --git a/sites/en/javascript-snake-game/js/lesson-3.js b/sites/en/javascript-snake-game/js/lesson-3.js deleted file mode 100644 index 1788fb86a..000000000 --- a/sites/en/javascript-snake-game/js/lesson-3.js +++ /dev/null @@ -1,7 +0,0 @@ -var drawSnake = function(snakeToDraw) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableObjects = [drawableSnake]; - CHUNK.draw(drawableObjects); -} -var snake = [{ top: 0, left: 0}]; -drawSnake(snake); diff --git a/sites/en/javascript-snake-game/js/lesson-4.js b/sites/en/javascript-snake-game/js/lesson-4.js deleted file mode 100644 index a60931b6a..000000000 --- a/sites/en/javascript-snake-game/js/lesson-4.js +++ /dev/null @@ -1,15 +0,0 @@ -var drawSnake = function(snakeToDraw) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableObjects = [drawableSnake]; - CHUNK.draw(drawableObjects); -} - -var moveSnake = function(snake) { - var oldSegment = snake[0]; - var newSegment = { top: oldSegment.top + 1, left: oldSegment.left }; - var newSnake = [newSegment]; - return newSnake; -} - -var snake = [{ top: 0, left: 0}]; -drawSnake(snake); diff --git a/sites/en/javascript-snake-game/js/lesson-5.js b/sites/en/javascript-snake-game/js/lesson-5.js deleted file mode 100644 index 0b2c2ba93..000000000 --- a/sites/en/javascript-snake-game/js/lesson-5.js +++ /dev/null @@ -1,21 +0,0 @@ -var drawSnake = function(snakeToDraw) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableObjects = [drawableSnake]; - CHUNK.draw(drawableObjects); -} - - -var moveSnake = function(snake) { - var oldSegment = snake[0]; - var newSegment = { top: oldSegment.top + 1, left: oldSegment.left }; - var newSnake = [newSegment]; - return newSnake; -} - -var advanceGame = function() { - snake = moveSnake(snake); - drawSnake(snake); -} - -var snake = [{ top: 0, left: 0}]; -CHUNK.executeNTimesPerSecond(advanceGame, 1); diff --git a/sites/en/javascript-snake-game/js/lesson-6.js b/sites/en/javascript-snake-game/js/lesson-6.js deleted file mode 100644 index dbc3d9cce..000000000 --- a/sites/en/javascript-snake-game/js/lesson-6.js +++ /dev/null @@ -1,35 +0,0 @@ -var drawSnake = function(snakeToDraw) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableObjects = [drawableSnake]; - CHUNK.draw(drawableObjects); -} - -var moveSegment = function(segment) { - if (segment.direction === "down") { - return { top: segment.top + 1, left: segment.left } - } else if (segment.direction === "up") { - return { top: segment.top - 1, left: segment.left } - } else if (segment.direction === "right") { - return { top: segment.top, left: segment.left + 1 } - } else if (segment.direction === "left") { - return { top: segment.top, left: segment.left - 1 } - } - return segment; -} - -var moveSnake = function(snake) { - var oldSegment = snake[0]; - var newSegment = moveSegment(oldSegment); - newSegment.direction = oldSegment.direction; - var newSnake = [newSegment]; - return newSnake; -} - - -var advanceGame = function() { - snake = moveSnake(snake); - drawSnake(snake); -} - -var snake = [{ top: 0, left: 0, direction: "down" }]; -CHUNK.executeNTimesPerSecond(advanceGame, 1); diff --git a/sites/en/javascript-snake-game/js/lesson-7.js b/sites/en/javascript-snake-game/js/lesson-7.js deleted file mode 100644 index ef1a0e578..000000000 --- a/sites/en/javascript-snake-game/js/lesson-7.js +++ /dev/null @@ -1,41 +0,0 @@ -var drawSnake = function(snakeToDraw) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableObjects = [drawableSnake]; - CHUNK.draw(drawableObjects); -} - -var moveSegment = function(segment) { - switch(segment.direction) { - case "down": - return { top: segment.top + 1, left: segment.left }; - case "up": - return { top: segment.top - 1, left: segment.left }; - case "right": - return { top: segment.top, left: segment.left + 1 } - case "left": - return { top: segment.top, left: segment.left - 1 } - default: - return segment; - } -} - -var moveSnake = function(snake) { - var oldSegment = snake[0]; - var newSegment = moveSegment(oldSegment); - newSegment.direction = oldSegment.direction; - var newSnake = [newSegment]; - return newSnake; -} - -var advanceGame = function() { - snake = moveSnake(snake); - drawSnake(snake); -} - -var changeDirection = function(direction) { - snake[0].direction = direction; -} - -var snake = [{ top: 0, left: 0, direction: "down" }]; -CHUNK.executeNTimesPerSecond(advanceGame, 1); -CHUNK.onArrowKey(changeDirection); diff --git a/sites/en/javascript-snake-game/js/lesson-8.js b/sites/en/javascript-snake-game/js/lesson-8.js deleted file mode 100644 index 581bac95b..000000000 --- a/sites/en/javascript-snake-game/js/lesson-8.js +++ /dev/null @@ -1,46 +0,0 @@ -var drawSnake = function(snakeToDraw) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableObjects = [drawableSnake]; - CHUNK.draw(drawableObjects); -} - -var moveSegment = function(segment) { - switch(segment.direction) { - case "down": - return { top: segment.top + 1, left: segment.left }; - case "up": - return { top: segment.top - 1, left: segment.left }; - case "right": - return { top: segment.top, left: segment.left + 1 } - case "left": - return { top: segment.top, left: segment.left - 1 } - default: - return segment; - } -} - -var moveSnake = function(snake) { - var oldSegment = snake[0]; - var newSegment = moveSegment(oldSegment); - newSegment.direction = oldSegment.direction; - var newSnake = [newSegment]; - return newSnake; -} - -var advanceGame = function() { - snake = moveSnake(snake); - if (CHUNK.detectCollisionBetween(snake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - drawSnake(snake); -} - -var changeDirection = function(direction) { - snake[0].direction = direction; -} - -var snake = [{ top: 0, left: 0, direction: "down" }]; - -CHUNK.executeNTimesPerSecond(advanceGame, 1); -CHUNK.onArrowKey(changeDirection); diff --git a/sites/en/javascript-snake-game/js/lesson-9.js b/sites/en/javascript-snake-game/js/lesson-9.js deleted file mode 100644 index af7cf047a..000000000 --- a/sites/en/javascript-snake-game/js/lesson-9.js +++ /dev/null @@ -1,49 +0,0 @@ -var drawSnake = function(snakeToDraw) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableObjects = [drawableSnake]; - CHUNK.draw(drawableObjects); -} - -var moveSegment = function(segment) { - switch(segment.direction) { - case "down": - return { top: segment.top + 1, left: segment.left }; - case "up": - return { top: segment.top - 1, left: segment.left }; - case "right": - return { top: segment.top, left: segment.left + 1 } - case "left": - return { top: segment.top, left: segment.left - 1 } - default: - return segment; - } -} - -var moveSnake = function(snake) { - var newSnake = []; - snake.forEach(function(oldSegment) { - var newSegment = moveSegment(oldSegment); - newSegment.direction = oldSegment.direction; - newSnake.push(newSegment); - }); - - return newSnake; -} - -var advanceGame = function() { - snake = moveSnake(snake); - if (CHUNK.detectCollisionBetween(snake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - drawSnake(snake); -} - -var changeDirection = function(direction) { - snake[0].direction = direction; -} - -var snake = [{ top: 1, left: 0, direction: "down" }, { top: 0, left: 0, direction: "down" }]; - -CHUNK.executeNTimesPerSecond(advanceGame, 1); -CHUNK.onArrowKey(changeDirection); diff --git a/sites/en/javascript-snake-game/js/snake.js b/sites/en/javascript-snake-game/js/snake.js deleted file mode 100644 index b20d27ee6..000000000 --- a/sites/en/javascript-snake-game/js/snake.js +++ /dev/null @@ -1,81 +0,0 @@ -var draw = function(snakeToDraw, apple) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableApple = { color: "red", pixels: [apple] }; - var drawableObjects = [drawableSnake, drawableApple]; - CHUNK.draw(drawableObjects); -} - -var moveSegment = function(segment) { - switch(segment.direction) { - case "down": - return { top: segment.top + 1, left: segment.left }; - case "up": - return { top: segment.top - 1, left: segment.left }; - case "right": - return { top: segment.top, left: segment.left + 1 } - case "left": - return { top: segment.top, left: segment.left - 1 } - default: - return segment; - } -} - -var segmentFurtherForwardThan = function(index, snake) { - return snake[index - 1] || snake[index]; -} - -var moveSnake = function(snake) { - return snake.map(function(oldSegment, segmentIndex) { - var newSegment = moveSegment(oldSegment); - newSegment.direction = segmentFurtherForwardThan(segmentIndex, snake).direction; - return newSegment; - }); -} - -var growSnake = function(snake) { - var tipOfTailIndex = snake.length - 1; - var tipOfTail = snake[snake.length - 1]; - snake.push({ top: tipOfTail.top, left: tipOfTail.left }); - return snake; -} - - -// The last thing we need to do is check to see if the snake ran into itself. -var ate = function(snake, otherThing) { - var head = snake[0]; - return CHUNK.detectCollisionBetween([head], otherThing); -} - -var advanceGame = function() { - var newSnake = moveSnake(snake); - - if (ate(newSnake, snake)) { - CHUNK.endGame(); - return CHUNK.flashMessage("Woops! You ate yourself!"); - } - // Now we just have to check if the newSnake ate it's previous self to see if - // there was a collision! - - if (ate(newSnake, [apple])) { - newSnake = growSnake(newSnake); - apple = CHUNK.randomLocation(); - } - - if (ate(newSnake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - return CHUNK.flashMessage("Woops! you hit a wall!"); - } - - snake = newSnake; - draw(snake, apple); -} - -var changeDirection = function(direction) { - snake[0].direction = direction; -} - -var apple = CHUNK.randomLocation(); -var snake = [{ top: 1, left: 0, direction: "down" }, { top: 0, left: 0, direction: "down" }]; - -CHUNK.executeNTimesPerSecond(advanceGame, 1); -CHUNK.onArrowKey(changeDirection); diff --git a/sites/en/javascript-snake-game/lesson-10.step b/sites/en/javascript-snake-game/lesson-10.step deleted file mode 100644 index 8c018fd4d..000000000 --- a/sites/en/javascript-snake-game/lesson-10.step +++ /dev/null @@ -1,73 +0,0 @@ -# Lesson 10 - Making the Tail Follow the Head - -markdown <<-MARKDOWN - To make the tail follow the head, we're going to assign the direction of the - segment furher forward in snake to the current segment when it moves. This way - all segments follow the same path! - - Let's define a new function called `segmentFurtherDown` which takes a - segment index and a snake and returns the segment closer to the head. Let's - start with: - - ```js - var segmentFurtherForwardThan = function(index, snake) { - return snake[index - 1] - } - ``` - - While this seems OK, in reality it has a nefarious bug! Open your console and type: - - ```js - segmentFurtherForwardThan(1, snake); - ``` - - This returns a segment object, which looks great! But what happens if we try - a index of 0? - - ```js - segmentFurtherForwardThan(0, snake); - ``` - - Instead of a segment, we get `undefined`! This means we can't get a - direction! Let's use an `if` statement to return the segment at the index if - there isn't a segment further forward. Change `segmentFurtherForwardThan` to: - - - ```js - var segmentFurtherForwardThan = function(index, snake) { - if (snake[index - 1] === undefined) { - return snake[index]; - } else { - return snake[index - 1]; - } - } - ``` - - Now when you run `segmentFurtherForwardThan(0, snake)` it will return the - snakes head instead of undefined. Excellent! Now we get to change moveSnake to - use `segmentFurtherForwardThan` when it assigns the segments direction. Change `moveSnake` to: - - ```js - var moveSnake = function(snake) { - return snake.map(function(oldSegment, segmentIndex) { - var newSegment = moveSegment(oldSegment); - newSegment.direction = segmentFurtherForwardThan(segmentIndex, snake).direction; - return newSegment; - }); - } - ``` - - Great! Now each segment will follow the segment ahead of it! -MARKDOWN - -js_expected_results 'lesson-10' - -markdown <<-MARKDOWN - ### Syntax Breakdown - - `array.map` and `array.forEach` pass 3 arguments to the function it is given: the - first is the element in the collection, the second is its index (or location in the collection) and - the third is the collection itself. -MARKDOWN - -next_step 'lesson-11' diff --git a/sites/en/javascript-snake-game/lesson-11.step b/sites/en/javascript-snake-game/lesson-11.step deleted file mode 100644 index 21d719224..000000000 --- a/sites/en/javascript-snake-game/lesson-11.step +++ /dev/null @@ -1,46 +0,0 @@ -# Lesson 11 - Making an Apple Appear on the Screen - -markdown <<-MARKDOWN - Let's make it so an apple appears on the screen! - - ```js - var draw = function(snakeToDraw, apple) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableApple = { color: "red", pixels: [apple] }; - var drawableObjects = [drawableSnake, drawableApple]; - CHUNK.draw(drawableObjects); - } - ``` - - We renamed the `drawSnake` function and let it take multiple arguments so it - can draw an apple. - - Next, let's make sure we pass the `apple` to the `draw` function, when we call it! - - ```js - var advanceGame = function() { - snake = moveSnake(snake); - if (CHUNK.detectCollisionBetween(snake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - draw(snake, apple); - } - ``` - - Finally, let's create an apple to be drawn! - - ```js - var apple = { top: 8, left: 10 }; - ``` -MARKDOWN - -js_expected_results 'lesson-11' - -markdown <<-MARKDOWN - ### Play Time! - - * Why do you think we put `[]` around the apple in the `draw` function? -MARKDOWN - -next_step 'lesson-12' diff --git a/sites/en/javascript-snake-game/lesson-12.step b/sites/en/javascript-snake-game/lesson-12.step deleted file mode 100644 index dbce3d010..000000000 --- a/sites/en/javascript-snake-game/lesson-12.step +++ /dev/null @@ -1,56 +0,0 @@ -# Lesson 12 - Growing the snake when it eats an apple! - -markdown <<-MARKDOWN - Now that an apple appears on the screen, we can make eating it grow - the snake. - - To do that, we'll create a stationary copy of the snakes last segment. When - the snake moves next the copied segment will stay in place, causing it to - "grow" on the screen. - - ```js - var growSnake = function(snake) { - var indexOfLastSegment = snake.length - 1; - var lastSegment = snake[snake.length - 1]; - snake.push({ top: lastSegment.top, left: lastSegment.left }); - return snake; - } - ``` - - Now that we have a function to grow the snake, let's check for a collision - between the apple and the snake whenever the game advances. Let's change the - `advanceGame` function so it looks like this: - - ```js - var advanceGame = function() { - snake = moveSnake(snake); - if (CHUNK.detectCollisionBetween([apple], snake)) { - snake = growSnake(snake); - apple = CHUNK.randomLocation(); - } - if (CHUNK.detectCollisionBetween(snake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - draw(snake, apple); - } - ``` -MARKDOWN - -js_expected_results 'lesson-12' - -markdown <<-MARKDOWN - ### Syntax Breakdown - - `array.length` tells us how many elements are in a list. Arrays are zero - indexed, so we subtract one to get the index of the last element in the - list. - - ### Play Time! - - * When is the newly added segment given a direction to move in? - * Why do we put the `apple` variable inside of `[]` when we call - `detectCollision` -MARKDOWN - -next_step 'lesson-13' diff --git a/sites/en/javascript-snake-game/lesson-13.step b/sites/en/javascript-snake-game/lesson-13.step deleted file mode 100644 index 1b1a53c9c..000000000 --- a/sites/en/javascript-snake-game/lesson-13.step +++ /dev/null @@ -1,58 +0,0 @@ -# Lesson 13 - Make the snake die when it eats itself! - -markdown <<-MARKDOWN - The last thing we need to do is check to see if the snake ran into itself. - - ```js - var ate = function(snake, otherThing) { - var head = snake[0]; - return CHUNK.detectCollisionBetween([head], otherThing); - } - ``` - - We've created an `ate` function that accepts a snake and the previous version of the snake. We can also think about passing the `ate` function other things, which we'll get into in a bit. In `ate` we also reuse the `detectCollisionBetween` to find out if there's a collision. - - Now we just have to check if the `newSnake` ate it's previous self to see if there was a collision! We do this by calling the `ate` function inside of `advanceGame`. - - ```js - var advanceGame = function() { - var newSnake = moveSnake(snake); - - if (ate(newSnake, snake)) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! You ate yourself!"); - } - - if (ate(newSnake, [apple])) { - newSnake = growSnake(newSnake); - apple = CHUNK.randomLocation(); - } - - if (ate(newSnake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - - snake = newSnake; - draw(snake, apple); - } - ``` - - Notice, we've abstracted out the `ate` function by resuing it. It can now determine if the snake ate itself, an apple or the wall. -MARKDOWN - -js_expected_results 'lesson-13' - -markdown <<-MARKDOWN - ### Congratulations! You've built the snake game! - - If you want your friends and family to be able to play your game, you'll need - to put it online. Lesson 14 includes instructions on putting your game online. - - ### Helpful Links - - 1. Article on Abstraction from Princeton -MARKDOWN - -next_step 'lesson-14' diff --git a/sites/en/javascript-snake-game/lesson-14.step b/sites/en/javascript-snake-game/lesson-14.step deleted file mode 100644 index ee824c591..000000000 --- a/sites/en/javascript-snake-game/lesson-14.step +++ /dev/null @@ -1 +0,0 @@ -insert '../javascript-to-do-list/_deploying_your_site' diff --git a/sites/en/javascript-snake-game/lesson-2.step b/sites/en/javascript-snake-game/lesson-2.step deleted file mode 100644 index 11be4665f..000000000 --- a/sites/en/javascript-snake-game/lesson-2.step +++ /dev/null @@ -1,100 +0,0 @@ -markdown <<-MARKDOWN - To get started, we want to create a `variable` that represents the - snake. Add the following line to the beginning of game/snake.js: - - ```js - var snake = [{ top: 0, left: 0}]; - ``` - -

      Now that we have this amazing snake we want to show it off, right? The - CHUNK game engine makes it easy to draw objects on the screen. Let's tell CHUNK - to `draw` our `snake`!

      - - ```js - var drawableSnake = { color: "green", pixels: snake }; - var drawableObjects = [drawableSnake]; - CHUNK.draw([drawableSnake]); - ``` - - CHUNK's `draw` function expects to be given a collection of objects. This - means we must create an array and place the drawableSnake inside of it. Then we - can pass that array into `CHUNK.draw` - - To see what your code does you'll need to save your `snake.js` file and - refresh the browser window that has your index.html in it. We recommend doing - this early and often! - - Congratulations! You've drawn a (very short!) snake on the screen. -MARKDOWN - -js_expected_results 'lesson-2' - -markdown <<-MARKDOWN - ### Play Time! - - * Add comments underneath each line explaining what it does in plain old - english. - * Change the color of the snake. - * Make the snake longer than just 1 segment! - * Draw something in addition to the snake. Perhaps an apple or a wall? Make - sure it's a different color! - - ### What is CHUNK? - When programming, you'll frequently need to solve problems that have been - solved before. In many cases someone who solved the problem already has - packaged their code into a `library`. - - Good libraries tend to: - - * Help you think about the problem you're solving more clearly - * Be well documented - * Solve a small set of closely related problems - - We'll be using the CHUNK library throughout this tutorial. CHUNK is an - example of a library whose job is to: - - * Draw chunky-pixels on the screen! - * Respond to user input - * Start and end a game - * Check for things running into each other - * Be reasonably approachable for novice developers - - ### Syntax Breakdown - - `var` tells the computer to create a variable (in this case named `snake`) - that we can assign a value to. - - `=` (single equals sign) tells the computer to assign the value on the - right of the `=` to the variable on the left of the `=`. - - `[` and `]` (square brackets) come in pairs. They wrap around one or more - values to make a list (often called an array). - - `{` and `}` (curly braces) also come in pairs. In this case they wrap around - pairs of names and values to create an `object` (sometimes called a - `hashmap`). (Note: There is another use of curly braces which we will see - later.) - - `:` (colon - when creating an object) says to create a variable within the - object. It's name (or key) is on the left side of the `:` and it's value is - on the right. - - `,` (comma - when creating an object or map) is used to separate key/value - pairs on the object. - - `;` (semicolon) says "This line is over. Thanks!" - - `.` (period) is used to get the value stored at a key inside an object. - `drawableSnake.color` says "get me the value of the color key in the - drawableSnake variable." What do you think that value is? - - `(` and `)` (parenthesis) also come in pairs. When they come after a - variable, they are saying "run the code stored in this variable." A variable - that stores code that can be run is called a `function`. Values held within - the parenthesis are given to the `function` for whatever it's purpose may - be. In this case, we want to give a collection of drawable things to - CHUNK's draw function so it can draw them on the screen. -MARKDOWN - -next_step "lesson-3" - diff --git a/sites/en/javascript-snake-game/lesson-3.step b/sites/en/javascript-snake-game/lesson-3.step deleted file mode 100644 index 32fe25444..000000000 --- a/sites/en/javascript-snake-game/lesson-3.step +++ /dev/null @@ -1,76 +0,0 @@ -# Lesson 3 - Drawing a Snake Multiple Times - -markdown <<-MARKDOWN - Now that we have a snake being drawn on the screen, We're going - to want to be able to draw it many times, for instance every time - it moves. - - To do this, we'll define a function which draws the snake - it's given. Add the following line to the beginning of - game/snake.js: - - ```js - var drawSnake = function(snakeToDraw) { - var drawableSnake = { color: "green", pixels: snakeToDraw }; - var drawableObjects = [drawableSnake]; - CHUNK.draw(drawableObjects); - } - ``` - - Functions are a way to group instructions so they're easy for humans to - understand or so the computer can use them over and over without us writing - the code out multiple times. - - Functions exist somewhat independently from the code around them; this means - that if the function needs variables from the rest of the code base they should - be passed in as arguments. The `drawSnake` function takes a single argument, - `snakeToDraw` which it then uses to create the `drawableSnake`. - - Now all we have to do is call drawSnake with a snake and it will be drawn on - the screen! Write the following under the drawSnake function. - - ```js - var snake = [{ top: 0, left: 0}]; - drawSnake(snake); - ``` - - Because Javascript interprets code from top to bottom we can't call - functions until after we've defined them. Make sure you put this code at the - end of the `snake.js` file. -MARKDOWN - -js_expected_results 'lesson-3' - -markdown <<-MARKDOWN - ### Play Time! - - * Open up the console and play around with making the - snake move by calling `drawSnake` with snakes that have - different `top` and `left` values for their segment. - * Try to access `drawableSnake` from outside of the `drawSnake` function. - Check the javascript console. - * Try to access `snake` inside of the `drawSnake` function. Check the - javascript console. - * Why do you suppose you could access one but not the other? Scope is how you - know what variables a function or piece of code has access too. - Understanding scope is hugely important when reading and writing code. - - ### Syntax Breakdown - - `function() { }` says "Hey, between the curly braces is some - code we want to be able to execute." Functions can be stored inside - variables just like words and numbers and objects and lists. - - `(` and `)` in this case are a way to say that this function expects - a value to be given to it when it is called. These values are called - `arguments`, and can be used inside of the function body (the code between - the curly braces). - - ### Helpful Links - - 1. An article explaining functions - 1. Information on Objects -MARKDOWN - -next_step "lesson-4" diff --git a/sites/en/javascript-snake-game/lesson-4.step b/sites/en/javascript-snake-game/lesson-4.step deleted file mode 100644 index df2659f7e..000000000 --- a/sites/en/javascript-snake-game/lesson-4.step +++ /dev/null @@ -1,60 +0,0 @@ -# Lesson 4 - Moving a Single Segment Snake - -markdown <<-MARKDOWN - Now that we have a function to draw the snake, we want to move the snake. - Let's write a function which takes a snake and changes its segment's top and left - values. - - To make our lives easier, let's make some assumptions: - - * The snake is only 1 segment long - * The snake always moves down - - By making these assumptions it keeps the code clear and makes it easy to - take small steps. Add the following code to your snake.js file: - - ```js - var moveSnake = function(snake) { - var oldSegment = snake[0]; - var newSegment = { top: oldSegment.top + 1, left: oldSegment.left }; - var newSnake = [newSegment]; - return newSnake; - } - ``` - - Once we have this `moveSnake` function, we can call it and it will give us a - snake whose segment's location has changed. We can then call `drawSnake` with - that snake and see it move across the screen! - - Type the following lines into your javascript console a few times: - - ``` - snake = moveSnake(snake); - drawSnake(snake); - ``` -MARKDOWN - -js_expected_results 'lesson-4' - -markdown <<-MARKDOWN - ### Play Time! - - * Why does adding 1 to a segment's top value move it down? - * Can you make the snake move right instead of down? - * What happens to the newSnake variable? Can you use it outside of the - moveSnake function body (within the curly braces)? - * Why are we re-assigning snake the results of moveSnake? - - ### Syntax Breakdown - - `return value` - Tells the function to immediately respond with whatever - value it is given. In this case, the newSnake. - - `array[location]` -"Get the value at this location in the array." Arrays in - most programming languages are "zero-indexed" i.e. the first element is at 0, - the second is at 1, and so on. - - `+` adds the values on the left and right together. Surprise, eh? -MARKDOWN - -next_step 'lesson-5' diff --git a/sites/en/javascript-snake-game/lesson-5.step b/sites/en/javascript-snake-game/lesson-5.step deleted file mode 100644 index 9034182b4..000000000 --- a/sites/en/javascript-snake-game/lesson-5.step +++ /dev/null @@ -1,42 +0,0 @@ -# Lesson 5 - Make CHUNK move the snake for us - -markdown <<-MARKDOWN - Hooray! We can both draw and move the snake! Of course, having our users - copy and paste lines of code into their javascript console isn't a wonderful - idea, so we're going to have CHUNK execute the move and draw commands for us. - - We'll start with an `advanceGame` function - - ```js - var advanceGame = function() { - snake = moveSnake(snake); - drawSnake(snake); - } - ``` - - To get this function running we'll use our CHUNK game engine to CALL the `executeNTimesPerSecond` function. It does exactly that, to do this `executeNTimesPerSecond` takes in two arguments. The first arugement advances the game, and the second tells it how many times to move per-second. - - ```js - CHUNK.executeNTimesPerSecond(advanceGame, 1); - ``` - - Bam! Now the snake moves down until it runs off the game screen. - - Because functions are just another kind of value (like numbers, arrays, objects, strings, - etc.) we can pass them as arguments to other functions. - -MARKDOWN - -js_expected_results 'lesson-5' - -markdown <<-MARKDOWN - ### Play Time! - - * How can you increase the speed at which the snake moves? - - ### Helpful Links - - 1. Writing functions with more than one argument -MARKDOWN - -next_step "lesson-6" diff --git a/sites/en/javascript-snake-game/lesson-6.step b/sites/en/javascript-snake-game/lesson-6.step deleted file mode 100644 index c3572f59a..000000000 --- a/sites/en/javascript-snake-game/lesson-6.step +++ /dev/null @@ -1,76 +0,0 @@ -# Lesson 6 - Snake can move in every direction - -markdown <<-MARKDOWN - Now that the snake is moving on it's own, let's make it so it can move in - different directions! - - First, we'll create a function that moves the segment based upon it's - direction (down, up, right, left): - - ```js - var moveSegment = function(segment) { - if (segment.direction === "down") { - return { top: segment.top + 1, left: segment.left } - } else if (segment.direction === "up") { - return { top: segment.top - 1, left: segment.left } - } else if (segment.direction === "right") { - return { top: segment.top, left: segment.left + 1 } - } else if (segment.direction === "left") { - return { top: segment.top, left: segment.left - 1 } - } - return segment; - } - ``` - - `if` statements choose what code to run. Here a series of `if` and `else if`s - to return a new object with coordinates offset from the passed in segment. - - When the passed in segment doesn't have a direction or it doesn't match the - directions in our `if`/`else if` then we return the original segment object. - - Our returned segment doesn't have a direction; which means the snake will - only move once! To keep the snake moving we need to assign every `newSegment` a - direction. - - Let's change our `moveSnake` function to give the `newSegment` the same - direction as the `oldSegment`. This will keep the snake moving in the same - direction. - - ```js - var moveSnake = function(snake) { - var oldSegment = snake[0]; - var newSegment = moveSegment(oldSegment); - newSegment.direction = oldSegment.direction; - var newSnake = [newSegment]; - return newSnake; - } - ``` - - Next add a direction to our initial snakes segments. - - ```js - var snake = [{ top: 0, left: 0, direction: "down" }]; - ``` - - Now our snake knows where to start moving! -MARKDOWN - -js_expected_results 'lesson-6' - -markdown <<-MARKDOWN - ### Play Time! - - * Use a switch statement instead of a series of ifs - * Make sure each direction works! - - ### Syntax Breakdown - - `===` tells the computer to check for EXACT equality. For example: "down" === "down" will return true but "down" === "DOWN" will return false. - - ### Helpful Links - - 1. switch statements - 1. === vs == -MARKDOWN - -next_step "lesson-7" diff --git a/sites/en/javascript-snake-game/lesson-7.step b/sites/en/javascript-snake-game/lesson-7.step deleted file mode 100644 index ebd647ef5..000000000 --- a/sites/en/javascript-snake-game/lesson-7.step +++ /dev/null @@ -1,32 +0,0 @@ -# Lesson 7 - Changing the Snakes Movement Direction - -markdown <<-MARKDOWN - To change the direction of the snake, we need to change the direction of - its first segment. Add the following function to snake.js: - - ```js - var changeDirection = function(direction) { - snake[0].direction = direction; - } - ``` - - Next, we have CHUNK call changeDirection when an arrow key is pressed. - Add the following line at the end of snake.js: - - ```js - CHUNK.onArrowKey(changeDirection); - ``` - - This tells CHUNK to call the `changeDirection` function every time an arrow key - is pressed. - - Just like we pass our snake object into the `drawSnake` function, we can pass - the `changeDirection` function into the `onArrowKey` function. - - In JavaScript, we can pass functions into functions just like we can pass - arrays, strings, integers, and objects into functions -MARKDOWN - -js_expected_results 'lesson-7' - -next_step 'lesson-8' \ No newline at end of file diff --git a/sites/en/javascript-snake-game/lesson-8.step b/sites/en/javascript-snake-game/lesson-8.step deleted file mode 100644 index eb231660f..000000000 --- a/sites/en/javascript-snake-game/lesson-8.step +++ /dev/null @@ -1,39 +0,0 @@ -# Lesson 8 - Ending the Game When A Wall Is Hit - -markdown <<-MARKDOWN - Games aren't much fun if you can't lose them! Let's make it so when you hit - a wall. CHUNK comes with a function to detect collisions between things, so - we'll use that. - - Add an `if` statement to the `advanceGame` function like so: - - ```js - var advanceGame = function() { - snake = moveSnake(snake); - if (CHUNK.detectCollisionBetween(snake, CHUNK.gameBoundaries())) { - CHUNK.endGame(); - CHUNK.flashMessage("Woops! you hit a wall!"); - } - drawSnake(snake); - } - ``` - - Now, when there is a collision between the snake and the border we can have - CHUNK end the game and let the player know the game is over. -MARKDOWN - -js_expected_results 'lesson-8' - -markdown <<-MARKDOWN - ### Syntax Breakdown - - `CHUNK.detectCollisionBetween` takes two collections of coordinates and - returns true if the collections share any pixels - - `CHUNK.endGame` tells chunk to stop calling the advanceGame function, - effectively ending the game. - - `CHUNK.flashMessage` displays text to the user. -MARKDOWN - -next_step 'lesson-9' diff --git a/sites/en/javascript-snake-game/lesson-9.step b/sites/en/javascript-snake-game/lesson-9.step deleted file mode 100644 index 4c0744b63..000000000 --- a/sites/en/javascript-snake-game/lesson-9.step +++ /dev/null @@ -1,66 +0,0 @@ -# Lesson 9 - Moving a Multiple Segment Snake - -markdown <<-MARKDOWN - Now that we can crash into a wall, lets have a snake longer than a single - segment! - - Currently, the `moveSnake` function only moves the first segment in the - snake. Let's make it to move every segment! Change `moveSnake` to the - following: - - ```js - var moveSnake = function(snake) { - var newSnake = []; - snake.forEach(function(oldSegment) { - var newSegment = moveSegment(oldSegment); - newSegment.direction = oldSegment.direction; - newSnake.push(newSegment); - }); - - return newSnake; - } - ``` - - `forEach` introduces `looping`. Looping allows us to do something multiple - times. Looping (for, while, forEach, etc) and conditionals (if, switch)` both - allow you to control the flow of the program. - - Now that we can move many segments across the screen, let's add a second - segment to our snake. Change the line that starts with `var snake = ...` to the - following: - - ```js - var snake = [{ top: 1, left: 0, direction: "down" }, { top: 0, left: 0, direction: "down" }]; - ``` -MARKDOWN - -js_expected_results 'lesson-9' - -markdown <<-MARKDOWN - You'll notice that if you play the game, the second segment always just - moves down. This is OK for now! - - ### Syntax Breakdown - - `array.forEach` allows us to call a function with each item in a collection. - This is a very common kind of loop and is very powerful. - - `array.push` adds the element it is given to the array it is called in. - - ### Play Time! - - * `array.map` - is another kind of loop that makes it easy to build a new collection from an - existing collection. Rewrite the `moveSnake` function to use `array.map` - instead of `array.forEach` - * The - `for` - and - `while` - loops are also quite common. They are more generally useful but harder to use - than the collection based `forEach` and `map` functions. How could you write - moveSnake with either `for` or `while`? -MARKDOWN - -next_step 'lesson-10' - diff --git a/sites/en/javascript-snake-game/zip_content/index.html b/sites/en/javascript-snake-game/zip_content/index.html deleted file mode 100644 index d83e92eac..000000000 --- a/sites/en/javascript-snake-game/zip_content/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/sites/en/javascript-snake-game/zip_content/snake.js b/sites/en/javascript-snake-game/zip_content/snake.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/sites/en/javascript-to-do-list-with-react/adding_an_item.step b/sites/en/javascript-to-do-list-with-react/adding_an_item.step deleted file mode 100644 index 405e8b995..000000000 --- a/sites/en/javascript-to-do-list-with-react/adding_an_item.step +++ /dev/null @@ -1,183 +0,0 @@ -goals do - goal "Allow a user to create a new item." - goal "Understand how to make an AJAX request when prompted by a user's action." -end - -overview do - message <<-MARKDOWN -JavaScript allows us to make our web page dynamic, and responsive to -the actions of our users. In this lesson, we'll allow our users to create -a new item for our list, and ask the server to save it to the database. - -To do so, we're going to use JavaScript's ability to perform a task when a -user has taken an action on the page. JavaScript refers to these actions as -__events__. React makes it easy to listen to these events, and cause the page -to change when nevessary. - -Our code will take the following steps. - -1. When the user loads the page, our CreationForm component will start - listening for when the user submits the form at the top of the page. - -2. When a user submits the form (by pressing enter), we will prevent the page - from refreshing, which is the normal behavior for a form. - -3. The CreationForm component will then tell ListStore to add a new item. - -4. ListStore will make an AJAX request to our server, creating an item with the - description our user just provided. - -5. Once the request succeeds, we will update the items variable with our new item. - -6. Finally, we will tell the components to re-render themselves! - -We've already written the first two steps for you. Let's finish the rest! - MARKDOWN -end - - -steps do - step do - message <<-MARKDOWN -In the browser, try creating a new item. You should see an alert pop up with your item's value. Let's take -a look at the CreationForm component to see how that works. Open up index.html in your browser, and find the -component. It looks like this: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - render: function() { - return ( -
      - -
      - ) - }, - - handleSubmit: function(event) { - event.preventDefault() - var description = this.refs.description.getDOMNode().value - this.refs.description.getDOMNode().value = '' - alert('trying to create an item with description ' + description) - } - JAVASCRIPT - - message <<-MARKDOWN -When the form submits, the handleSubmit function runs! This function is preventing the page from refreshing -(using the preventDefault function) and using React to get the new description the user just wrote. See if you -can follow the code – how does the form know to run the handleSubmit function? - -Now, let's remove the alert, and instead tell the ListStore to add an item. Your code should look like this: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - handleSubmit: function(event) { - event.preventDefault() - var description = this.refs.description.getDOMNode().value - this.refs.description.getDOMNode().value = '' - ListStore.addItem(description) - } - JAVASCRIPT - end - - step do - message <<-MARKDOWN -Now, let's write the logic for the addItem function. We're going to ask the server to save -this item into the database. Open up store.js, and add the following code to the addItem -function. Replace 'YOUR-LIST-NAME-HERE' with your list's name. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - addItem: function(itemDescription) { - var creationRequest = $.ajax({ - type: 'POST', - url: "http://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/items", - data: { description: itemDescription, completed: false } - }) - }, - JAVASCRIPT - - message <<-MARKDOWN -Try creating an item again. After you submit the form, look at the network tab. A -new request should have occurred to http://listalous.herokuapp.com/ ! - MARKDOWN - end - - step do - message <<-MARKDOWN -Finally, we need to tell the components to re-render themselves. After the creationRequest, -add the following code: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - creationRequest.done(function(itemDataFromServer) { - items.push(itemDataFromServer) - notifyComponents() - }) - JAVASCRIPT - - message <<-MARKDOWN -Try creating an item one more time. Once you hit enter, a new item should appear -on the page! If not, flag an instructor down to help you debug the problem. - MARKDOWN - end -end - -explanation do - - message "Here's what the bottom of store.js should now look like:" - - source_code :javascript, <<-JAVASCRIPT - ListStore = { - - getItems: function() { - return items - }, - - loadItems: function() { - var loadRequest = $.ajax({ - type: 'GET', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/" - }) - - loadRequest.done(function(dataFromServer) { - items = dataFromServer.items - notifyComponents() - }) - }, - - addItem: function(itemDescription) { - var creationRequest = $.ajax({ - type: 'POST', - url: "http://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/items", - data: { description: itemDescription, completed: false } - }) - - creationRequest.done(function(itemDataFromServer) { - items.push(itemDataFromServer) - notifyComponents() - }) - }, - toggleCompleteness: function(itemId) {} - } - JAVASCRIPT - - message <<-MARKDOWN - -### The AJAX process - -You've just done something that many JavaScript developers do daily: Use JavaScript -to make a request to a server, and then update the page with the data with which -the server responds. This abstract process is repeated over and over again: - -1. Listen for a user action on the page. -2. Parse out the information the user is submitting. -3. Prevent the default action from occuring, if necessary. -4. Make a request to the server using AJAX. -5. When the request succeeds, parse the data the server sends back. -6. Update the page with the newly received data. - -This process is the basis of most modern web pages! - MARKDOWN -end - -next_step "marking_an_item_as_complete" diff --git a/sites/en/javascript-to-do-list-with-react/building_complex_applications_with_react.step b/sites/en/javascript-to-do-list-with-react/building_complex_applications_with_react.step deleted file mode 100644 index 5f8df950a..000000000 --- a/sites/en/javascript-to-do-list-with-react/building_complex_applications_with_react.step +++ /dev/null @@ -1,179 +0,0 @@ -goals do - goal "Understand how modern web developers organize their code." - goal "Familiarize with Stores, JSX, and other features of a React application." -end - -overview do - message <<-MARKDOWN - When the web was in its infancy, JavaScript was often an afterthought. Web developers - were mostly concerned writing complex servers, and thought of JavaScript as a language to - simply make things move on their user's pages. Consequently, their JavaScript code - was often unorganized, untested, and hard to maintain. - - But as browsers became more advanced, JavaScript was suddenly asked to do much more – web - developers used JavaScript for complex animations, making requests to servers, even doing - complex calculations in the browser! The old approach of writing all your code in one place, - with all the logic jumbled together, quickly became untenable. In response to that, the - JavaScript community has started developing patterns to help themselves organize their code, - making it more readable. Most of these patterns separate code into two buckets: - - * __Views (or Components, or View Controllers)__ are in charge or rendering HTML elements, and - listening for user's actions like clicks and form submissions. - * __Models (or Stores)__ are responsible for the logic of your JavaScript application. - - There are many JavaScript libraries and frameworks that implement this structure, including - [AngularJS](https://angularjs.org/), [Ember.js](http://emberjs.com/), and [Backbone.js](http://backbonejs.org/). - They each have their own strengths and weaknesses. and we wouldn't presume to tell you - which one is "better." As you continue learning, you'll form your own opinions! - - For this tutorial, we'll be using [React](http://facebook.github.io/react/), a rendering library written by Facebook that has - grown in popularity over the last few years. To use React, you write your HTML as a series of __components__ - in a language called __JSX__. Don't worry, JSX looks a lot like HTML! These components handle - the rendering of your HTML elements, as well as listen for user actions. - - You'll be using React to make your view objects, and we'll use a simple JavaScript object as a model. We've - already built a lot of this structure for you! Let's walk through the code together. - MARKDOWN -end - - - - -steps do - step do - message <<-MARKDOWN -Open up store.js in your text editor. There, you should see a ListStore object defined like this: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - ListStore = { - getItems: function() { - return items - }, - loadItems: function() {}, - addItem: function(itemDescription) {}, - toggleCompleteness: function(itemId) {} - } - JAVASCRIPT - - message <<-MARKDOWN -This is where all the logic of our application will be performed! Whenever we need to execute a calcuation, or -make an AJAX request, our program will call a function on the ListStore object. For instance, when we want to load -all items from our server, you would write a line of code like this: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - ListStore.loadItems() - JAVASCRIPT - - message <<-MARKDOWN -In future lessons, we'll be writing the logic to make these functions work! Whenever the store changes – when an item -is added or marked as completed, for example – we'll use the notifyComponents function to update the user's page. - MARKDOWN - end - - step do - - message <<-MARKDOWN -Now that we've looked at the store, let's take a look at our components. Open index.html, and find the Item component. It should -look like this: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - var Item = React.createClass({ - render: function() { - var itemClass = this.props.completed ? 'item completed' : 'item' - return ( -
    1. - {'\\u2714'} -
      {this.props.description}
      - {'\\u2718'} -
    2. - ) - }, - }) - JAVASCRIPT - - message <<-MARKDOWN -This is a React component. It is responsible for rendering the HTML for our list's items! Every React component has -to have a render function, which are written in a language called JSX. It looks a like HTML, except you can write it -alongside your JavaScript code. Here's the HTML this component renders: - MARKDOWN - - source_code :HTML, <<-HTML -
    3. - -
      A gallon of milk.
      - -
    4. - HTML - - message <<-MARKDOWN -Take a look at the other components on the page. What do you think List component does, and how does it know to render -items? How about the CreationForm component? - MARKDOWN - end - - step do - message <<-MARKDOWN -Now you know what a React component looks like, but how does it work? Well, components can have __state__. -Whenever a component's state changes, it re-renders itself to the page! State can change in a handful -of ways. We've already written a function to make List's state change whenever the notifyComponents -function is called. This will be helpful later on! - -Components with state usually also implement a getInitialState function that tells the component what -to render immediately after the page loads. Our List component has one that looks like this: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - getInitialState: function() { - return ( - {items: [ - {description: 'a gallon of milk', completed: true, id: 1}, - {description: 'a stick of butter', completed: false, id: 2} - ]} - ) - }, - JAVASCRIPT - - message <<-MARKDOWN -Does that data look familiar? It's the default items that our list renders! Try changing these values. -Refresh your browser, and see what's changed! - -Before we move on, let's remove the default items altogether. Not everyone wants a gallon of milk! -Your code should look like this: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - getInitialState: function() { - return ( - {items: []} - ) - }, - JAVASCRIPT - end -end -explanation do - - message <<-MARKDOWN - -### Getting Comfortable with React. - -You've just looked at your first React application! There are a lot of moving parts, we know. -Don't worry if you don't understand how everything works just yet – as you keep playing with it, -it will become much clearer. Big picture, our web application has two parts: - -* A ListStore, which is responsible for fetching data from the server using AJAX, and keeps -track of all the items on our list. Whenever a new item has been added or updated, it will notify -all the components that it has changed. - -* A series of components that render our list as HTML. The List component updates whenever -the ListStore changes, and it renders a series of Item components. The CreationForm component -will be responsible for creating new items! - -Next, we'll write our first store function to load items when the user visits the page! - MARKDOWN -end - - -next_step 'loading_items' \ No newline at end of file diff --git a/sites/en/javascript-to-do-list-with-react/creating_a_list.step b/sites/en/javascript-to-do-list-with-react/creating_a_list.step deleted file mode 100644 index f4816dd55..000000000 --- a/sites/en/javascript-to-do-list-with-react/creating_a_list.step +++ /dev/null @@ -1,164 +0,0 @@ -goals do - goal "Understand how the internet is made up of clients and servers." - goal "Write some basic requests using JavaScript, jQuery and your browser's console." - goal "Create a list and your first item." -end - -overview do - - message <<-MARKDOWN - -As you may already know, websites are built using HTML, CSS, and JavaScript. -These are the languages your browser understands, and it uses them to give -structure, style, and interactivity to your website. - -The problem, though, is that browsers don't remember anything. Every time you refresh -a page, your browser reruns all of your CSS, HTML, and JavaScript. A browser, by itself, -doesn't remember who your users are, or any of their information. - -But wait, we need our website to remember things! Specifically, we need our website -to remember all the items on our list, and whether we've completed them. That's where -a __server__ comes in. A server is a catch-all term for a web application that can be -reached over the internet. They are often attached to __databases__ that store information -about their users. If you make an __HTTP request__ with the correct __URL__ (like -http://www.google.com) and __HTTP method__ (like GET or POST), the server will -respond with helpful data. - -Servers are written in dozens of languages, including Java, PHP, and Ruby. -For this exercise, we've already built a server (using Ruby on Rails), and its -available at https://listalous.herokuapp.com/. If you want to learn more about how -to write a server, take a look at our Rails curriculum! - -Browsers, like Chrome and Internet Explorer, are in the business of making requests -to servers, and displaying the data they receive as a web page. Browsers are a -type of __client__, which consume data. There are other types of clients, too. -Your computer can be a client, using the curl command in the terminal. An iPhone -is another type of client, and servers can even communicate with each other. - -Every time you refresh a web page, your browser is making another request to -the server. On modern websites, browsers often make multiple requests to a server, -depending on what the user is doing. For instance, Twitter doesn't load your entire -feed at once – as you scroll down the page, it's making more and more requests! - -To accomplish that feat, websites can use JavaScript to make requests to servers, -updating the page without the user having to refresh. This type of -request is called an __AJAX__ request, which stands for __A__synchronous __J__avaScript -__a__nd __X__ML. It's a technique that is used by most major websites, to provide -a seamless experience to their users. - -In this lesson, we'll be making AJAX requests using our browser's console. - MARKDOWN -end - -steps do - - step do - message <<-MARKDOWN -Copy the following code into your browser's console, replacing 'YOUR-LIST-NAME-HERE' -with your name of choice. Note: it has to be unique! I'd suggest using your github username. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - $.ajax({ - type: 'POST', - url: "https://listalous.herokuapp.com/lists", - data: { name: 'YOUR-LIST-NAME-HERE' } - }) - JAVASCRIPT - - message <<-MARKDOWN -Now click over to your browser's network tab. It should look something like this. - -image of chrome's network tab. - -Find the request to listalous.herokuapp.com. Was it successful? If not, why -do you think it failed? Once you've successfully created a list, move on to the next step. - MARKDOWN - end - - step do - message <<-MARKDOWN -Now that we've created a list, let's create our list's first item. We're -going to use jQuery's AJAX function again to do so. Copy the following -code into your browser's console, replacing 'YOUR-LIST-NAME-HERE' with -your list's name, and 'DESCRIPTION-OF-YOUR-ITEM' with your item's description. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - $.ajax({ - type: 'POST', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/items", - data: { description: 'DESCRIPTION-OF-YOUR-ITEM', completed: false } - }) - JAVASCRIPT - - message <<-MARKDOWN -Check the network tab again. Was your request successful? If it was, take a look at -the server's response. You'll notice that the item has an id attribute now. This is how -the server will uniquely identify your item in the future. - MARKDOWN - end - - step do - message <<-MARKDOWN -Finally, lets fetch our list from the server. Your list application will need to do this -every time someone refreshes the page, so that it can load previously created items. Copy -the following code into your browser's console, replacing 'YOUR-LIST-NAME-HERE' with your -list's name. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - $.ajax({ - type: 'GET', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/" - }) - JAVASCRIPT - - message <<-MARKDOWN -Check the network tab one more time. What data did the server send back? If your -request was successful, it should have returned all the data associated with your list: -your list's name, as well as all of your list's items. This is data will be basis -of your list application! - MARKDOWN - end -end - -explanation do - message <<-MARKDOWN - -That was a lot of copying and pasting! What did it all mean? - -### Adding a Server to the Equation. - -Remember, web pages have short memories. Whenever you refresh the page, all the HTML, -CSS, and JavaScript on that page has to reload and rerun. A common way for a website -to remember information about you (the fact that you have logged in before, your previous -purchases, etc.) is by getting a server involved. A server, attached to a database, can -persist information about your web site as users come and go. - -In this case, we have a server that can be reached over the internet at -https://listalous.herokuapp.com/. It's attached to a database that -stores all lists and items, that can fetched to make hundreds of independent to do lists. - -In step 1, we used jQuery's AJAX function to ask the server to make a -new list in its database. It only did so if the list's name was unique; -otherwise, how could the server tell your list apart from someone else's list? - -In step 2, we asked the server to create an item associated with your -list. The server responded with information regarding this item, including an -id, that we can use to identify that item later (if we want to mark it as complete, -or delete it.) - -In step 3, we asked the server to return all information associated with -our list, including all of the list's items. When we start building our list -application, we will use this data to load all items on our list every time we -refresh the page. - -We did all of this in the browser's console. In the next lesson, we'll learn -how modern web applications integrate AJAX requests into their applications. - - MARKDOWN -end - - -next_step "building_complex_applications_with_react" diff --git a/sites/en/javascript-to-do-list-with-react/deploying_your_site.step b/sites/en/javascript-to-do-list-with-react/deploying_your_site.step deleted file mode 100644 index 433ba891d..000000000 --- a/sites/en/javascript-to-do-list-with-react/deploying_your_site.step +++ /dev/null @@ -1,3 +0,0 @@ -insert '../javascript-to-do-list/_deploying_your_site' - -next_step "next_steps" \ No newline at end of file diff --git a/sites/en/javascript-to-do-list-with-react/developer_tools.step b/sites/en/javascript-to-do-list-with-react/developer_tools.step deleted file mode 100644 index f5c756c90..000000000 --- a/sites/en/javascript-to-do-list-with-react/developer_tools.step +++ /dev/null @@ -1,3 +0,0 @@ -insert '../frontend/_developer_tools' - -next_step 'creating_a_list' \ No newline at end of file diff --git a/sites/en/javascript-to-do-list-with-react/javascript-to-do-list-with-react.step b/sites/en/javascript-to-do-list-with-react/javascript-to-do-list-with-react.step deleted file mode 100644 index 8c2c3fe6b..000000000 --- a/sites/en/javascript-to-do-list-with-react/javascript-to-do-list-with-react.step +++ /dev/null @@ -1,78 +0,0 @@ -message <<-MARKDOWN -### Goal - -By the end of this session, you should understand how to write a JavaScript application -using the [React](http://facebook.github.io/react/) library. You're going to be building a personal to do list application. -You've decided that you'd like to: - -* Add an item to your list -* Mark an item as complete -* Load your list from multiple computers. - -You've sketched up an initial screenshot of what you want it to look like: - -![Browser window with list application running](../javascript-to-do-list/img/finished_app.png) - -### Meta-Goal - -When you have completed today's goal of getting the basic -application online you should understand: - -* How to use JavaScript to interact with a server. -* How to organize your JavaScript code into models and views. -* How to use the React library to render HTML elements. -* How to incremently add features to your application. -* How to get your application online. - -### Schedule - -* 1-ish hours of the basics of clients and servers. -* 1-ish hours on organizing JavaScript using models and views. -* 3-ish hours of adding features to you application, broken up into 1 hour chunks. - -This is just a rough guideline, not a mandate. Some steps you'll go -over and some you'll go under. It'll all work out by the end of the -day. Probably. - -### Requirements - -When programming, you'll generally want these tools on hand: - - * An internet connection. We're going to be communicating with other websites using JavaScript. - * Your browser to see the code running (I recommend Chrome, but any will do!) - * A text editor to change the code (I recommend Sublime) - * A javascript console so you can experiment and print out debugging - messages. This is built into your browser. - -Before you can start the tutorial, you'll need to download the tutorial -to your computer to edit the source code. - -Once you've downloaded it, open index.html with your browser. You should see a mock up of your list. If you do not, get an instructor to help you out. - -### Format - -Each lesson will look like this: - -
      -

      Step Title

      -
      -

      Goal:

      -

      Description of the current step. -

      Red because big goals are scary. -

      -
      -

      Steps:

      -
      steps to take.
      -

      Yellow because we've gotten it done, but we have no clue what's going on. -

      -
      -

      Explanation

      -

      Details of what the steps actually did... spell out the cause and effect. -

      Green because we can tie everything together now. -

      -
      -MARKDOWN - -next_step "developer_tools" - diff --git a/sites/en/javascript-to-do-list-with-react/loading_items.step b/sites/en/javascript-to-do-list-with-react/loading_items.step deleted file mode 100644 index e90a9dfdc..000000000 --- a/sites/en/javascript-to-do-list-with-react/loading_items.step +++ /dev/null @@ -1,131 +0,0 @@ -goals do - goal "Make an AJAX request and update the page based on the server's response." - goal "Load your list's items every time a user visits the page." -end - -overview do - message <<-MARKDOWN - Now that we've learned about AJAX requests and React, let's tie everything together. - Here's what we want to happen. - - 1. Every time a user visits our site, we'll ask ListStore to load all items from the server. - 2. It will use jQuery's AJAX function to make a request to http://listalous.herokuapp.com/ and - get all the data about our list's items. - 3. We will then use our React Components to render all of our items! - MARKDOWN -end - -steps do - step do - message <<-MARKDOWN -First, we need to tell ListStore to call the loadItems function whenever a user visits -the page. Open up index.html, and add this line of code to the bottom of the page, before the end -of the script tag: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - ListStore.loadItems() - JAVASCRIPT - - message "the end of index.html should now look like this:" - - source_code :HTML, <<-HTML - React.render(, document.getElementById('form-container') ) - React.render(, document.getElementById('list-container') ) - ListStore.loadItems() - - - HTML - end - - step do - message <<-MARKDOWN -Now, we have to write the loadItems function! open up Store.js, and add the following code -to the loadItems function. Replace 'YOUR-LIST-NAME-HERE' with the name of the list you created. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - loadItems: function() { - var loadRequest = $.ajax({ - type: 'GET', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/" - }) - }, - - JAVASCRIPT - - message <<-MARKDOWN -Refresh the page, and click over to your browser's network tab. You should see -a new request there, that visits our server at https://listalous.herokuapp.com/. - MARKDOWN - end - - step do - message <<-MARKDOWN -Now that we've made the request, we need to update ListStore whenever the request -succeeds. Add the following lines of code to the bottom of the LoadItems function. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - loadRequest.done(function(dataFromServer) { - items = dataFromServer.items - notifyComponents() - }) - JAVASCRIPT - - message <<-MARKDOWN - Now refresh the page. Once the AJAX request succeeds, your site should now display - all the items you created last lesson! If not, flag an instructor down to help you - debug the problem. - MARKDOWN - end - -end - - -explanation do - message "Store.js should now look like this." - source_code :javascript, <<-JAVASCRIPT - ListStore = { - - getItems: function() { - return items - }, - - loadItems: function() { - var loadRequest = $.ajax({ - type: 'GET', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/" - }) - - loadRequest.done(function(dataFromServer) { - items = dataFromServer.items - notifyComponents() - }) - }, - addItem: function(itemDescription) {}, - toggleCompleteness: function(itemId) {} - - JAVASCRIPT - - message <<-MARKDOWN -Let's walk through what just happened: - - 1. When the user visited the page, we told the ListStore to load items. - 2. The ListStore used jQuery's AJAX function to make a request to our server. - 3. The server responded with all the items associated with our list. - 4. We saved the server's response in the items variable, and notified the components - that it was time to re-render themselves. - 5. The components heard the message, and updated! The List component used ListStore's getItems - function to get all the items data we had stored in the items variable. - -Your web page has made its first successful AJAX request! Now, your page will -load your list's items whenever you visit it. Once we host this page on the internet, -you will be able to see your list on any computer, tablet, or phone! - MARKDOWN -end - - - - -next_step "adding_an_item" diff --git a/sites/en/javascript-to-do-list-with-react/marking_an_item_as_complete.step b/sites/en/javascript-to-do-list-with-react/marking_an_item_as_complete.step deleted file mode 100644 index 75e724300..000000000 --- a/sites/en/javascript-to-do-list-with-react/marking_an_item_as_complete.step +++ /dev/null @@ -1,187 +0,0 @@ -goals do - goal "Allow a user to mark an item as complete or incomplete." - goal "Understand how to listen for user events with React." -end - -overview do - message <<-MARKDOWN -In this lesson, we'll allow our users to mark items as complete and incomplete. As they -do, we will ask the server to update the item's status in its database. This process will look -a lot like the process for adding an item, with some additional complexity. - -First off, We'll have to write the event listener ourselves in the Item component. Don't worry, -we'll walk you through every step! - -Secondly, we need to pass the appropriate information to ListStore, so it can make the correct AJAX request. -To do so, we'll have to use __props__ to fetch the item's id value. - -Let's get started! - MARKDOWN -end - -steps do - step do - message "Let's add a click listener to our Item component's complete button. Find the line of code - that creating ths completion button, and add an onClick attribute to make React listen for your users' - clicks. Your code should look like this:" - - source_code :javascript, <<-JAVASCRIPT - {'\\u2714'} - JAVASCRIPT - - message "Now, let's write the handleComplete function." - - source_code :javascript, <<-JAVASCRIPT - handleComplete: function() { - alert('trying to complete item with an id of ' + this.props.id) - } - JAVASCRIPT - - message <<-MARKDOWN -Refresh the page, and try completing an item. What happens? How does the page know the item's id? - -Your Item component should now look like this: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - var Item = React.createClass({ - render: function() { - var itemClass = this.props.completed ? 'item completed' : 'item' - return ( -
    5. - {'\\u2714'} -
      {this.props.description}
      - {'\\u2718'} -
    6. - ) - }, - - handleComplete: function() { - alert('trying to update item with an id of ' + this.props.id) - } - }) - JAVASCRIPT - end - - step do - message "Now, we're going to tell ListStore to mark this item as complete/incomplete. Remove the alert from last step, and add the following code." - - source_code :javascript, <<-JAVASCRIPT - handleComplete: function() { - ListStore.toggleCompleteness(this.props.id) - } - JAVASCRIPT - end - - step do - message <<-MARKDOWN -Now, let's write the logic for updating an item! Open up store.js, and add the following code to -the toggleCompleteness function. replace 'YOUR-LIST-NAME-HERE' with your list's name. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - var item = findItemById(itemId) - var currentCompletedValue = item.completed - - var updateRequest = $.ajax({ - type: 'PUT', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/items/" + itemId, - data: { completed: !currentCompletedValue } - }) - JAVASCRIPT - - message <<-MARKDOWN -We're using the pre-written findItemById method to fetch the correct item, and then checking -its current completed value. We then tell the server to toggle its completeness from true to false, -or false to true. Refresh the page and try marking an item as complete. Check the network tab to see if -a new request was made! - MARKDOWN - end - - step do - message <<-MARKDOWN -Finally, we'll update the specified item's completeness value in the items array, and -tell the components to re-render themselves. Add this code to the bottom of the toggleCompleteness -function: - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - updateRequest.done(function(itemData) { - item.completed = itemData.completed - notifyComponents() - }) - JAVASCRIPT - - message <<-MARKDOWN -Mark an item as complete, and see it turn gray! If you mark a completed item as incomplete, -it should change colors, too. - MARKDOWN - end -end - - - -explanation do - - message "Here's what store.js should now look like:" - - source_code :javascript, <<-JAVASCRIPT - ListStore = { - - getItems: function() { - return items - }, - - loadItems: function() { - var loadRequest = $.ajax({ - type: 'GET', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/" - }) - - loadRequest.done(function(dataFromServer) { - items = dataFromServer.items - notifyComponents() - }) - }, - - addItem: function(itemDescription) { - var creationRequest = $.ajax({ - type: 'POST', - url: "http://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/items", - data: { description: itemDescription, completed: false } - }) - - creationRequest.done(function(itemDataFromServer) { - items.push(itemDataFromServer) - notifyComponents() - }) - }, - - toggleCompleteness: function(itemId) { - var item = findItemById(itemId) - var currentCompletedValue = item.completed - - var updateRequest = $.ajax({ - type: 'PUT', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/items/" + itemId, - data: { completed: !currentCompletedValue } - }) - - updateRequest.done(function(itemData) { - item.completed = itemData.completed - notifyComponents() - }) - } - } - JAVASCRIPT - - message <<-MARKDOWN -You've now written three ajax requests, making a modern, dynamic web page. Don't worry if you -didn't understand every line of code – JavaScript is complex stuff! - -There are many more features you could add (deleting items, sorting items, etc.) but in our next -lesson, we'll add the most important feature: the ability of users to actually use your site! - MARKDOWN -end - -next_step "deploying_your_site" diff --git a/sites/en/javascript-to-do-list-with-react/next_steps.step b/sites/en/javascript-to-do-list-with-react/next_steps.step deleted file mode 100644 index 2e327e880..000000000 --- a/sites/en/javascript-to-do-list-with-react/next_steps.step +++ /dev/null @@ -1,22 +0,0 @@ -message < - -Find the request to listalous.herokuapp.com. Was it successful? If not, why -do you think it failed? Once you've successfully created a list, move on to the next step. - MARKDOWN - end - - step do - message <<-MARKDOWN -Now that we've created a list, let's create our list's first item. We're -going to use jQuery's AJAX function again to do so. Copy the following -code into your browser's console, replacing 'YOUR-LIST-NAME-HERE' with -your list's name, and 'DESCRIPTION-OF-YOUR-ITEM' with your item's description. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - $.ajax({ - type: 'POST', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/items", - data: { description: 'DESCRIPTION-OF-YOUR-ITEM', completed: false } - }) - JAVASCRIPT - - message <<-MARKDOWN -Check the network tab again. Was your request successful? If it was, take a look at -the server's response. You'll notice that the item has an id attribute now. This is how -the server will uniquely identify your item in the future. - MARKDOWN - end - - step do - message <<-MARKDOWN -Finally, lets fetch our list from the server. Your list application will need to do this -every time someone refreshes the page, so that it can load previously created items. Copy -the following code into your browser's console, replacing 'YOUR-LIST-NAME-HERE' with your -list's name. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - $.ajax({ - type: 'GET', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/" - }) - JAVASCRIPT - - message <<-MARKDOWN -Check the network tab one more time. What data did the server send back? If your -request was successful, it should have returned all the data associated with your list: -your list's name, as well as all of your list's items. This is data will be basis -of your list application! - MARKDOWN - end -end - -explanation do - message <<-MARKDOWN - -That was a lot of copying and pasting! What did it all mean? - -### Adding a Server to the Equation. - -Remember, web pages have short memories. Whenever you refresh the page, all the HTML, -CSS, and JavaScript on that page has to reload and rerun. A common way for a website -to remember information about you (the fact that you have logged in before, your previous -purchases, etc.) is by getting a server involved. A server, attached to a database, can -persist information about your web site as users come and go. - -In this case, we have a server that can be reached over the internet at -https://listalous.herokuapp.com/. It's attached to a database that -stores all lists and items, that can fetched to make hundreds of independent to do lists. - -In step 1, we used jQuery's AJAX function to ask the server to make a -new list in its database. It only did so if the list's name was unique; -otherwise, how could the server tell your list apart from someone else's list? - -In step 2, we asked the server to create an item associated with your -list. The server responded with information regarding this item, including an -id, that we can use to identify that item later (if we want to mark it as complete, -or delete it.) - -In step 3, we asked the server to return all information associated with -our list, including all of the list's items. When we start building our list -application, we will use this data to load all items on our list every time we -refresh the page. - -We did all of this in the browser's console. In the next lesson, we'll integrate -some of this code into our site, so it runs automatically whenever a user -visits your web site. - - MARKDOWN -end - - -next_step "loading_items" diff --git a/sites/en/javascript-to-do-list/deploying_your_site.step b/sites/en/javascript-to-do-list/deploying_your_site.step deleted file mode 100644 index 099c45876..000000000 --- a/sites/en/javascript-to-do-list/deploying_your_site.step +++ /dev/null @@ -1,3 +0,0 @@ -insert '_deploying_your_site' - -next_step "next_steps" \ No newline at end of file diff --git a/sites/en/javascript-to-do-list/developer_tools.step b/sites/en/javascript-to-do-list/developer_tools.step deleted file mode 100644 index fbe7c35a5..000000000 --- a/sites/en/javascript-to-do-list/developer_tools.step +++ /dev/null @@ -1,3 +0,0 @@ -insert '../frontend/_developer_tools' - -next_step 'programming_with_javascript' \ No newline at end of file diff --git a/sites/en/javascript-to-do-list/img/browser_console.png b/sites/en/javascript-to-do-list/img/browser_console.png deleted file mode 100644 index 965ff66c6..000000000 Binary files a/sites/en/javascript-to-do-list/img/browser_console.png and /dev/null differ diff --git a/sites/en/javascript-to-do-list/img/finished_app.png b/sites/en/javascript-to-do-list/img/finished_app.png deleted file mode 100644 index b3269d8b9..000000000 Binary files a/sites/en/javascript-to-do-list/img/finished_app.png and /dev/null differ diff --git a/sites/en/javascript-to-do-list/img/network_tab.png b/sites/en/javascript-to-do-list/img/network_tab.png deleted file mode 100644 index 0bab37307..000000000 Binary files a/sites/en/javascript-to-do-list/img/network_tab.png and /dev/null differ diff --git a/sites/en/javascript-to-do-list/img/text_editor_html.png b/sites/en/javascript-to-do-list/img/text_editor_html.png deleted file mode 100644 index 98072b963..000000000 Binary files a/sites/en/javascript-to-do-list/img/text_editor_html.png and /dev/null differ diff --git a/sites/en/javascript-to-do-list/javascript-to-do-list.step b/sites/en/javascript-to-do-list/javascript-to-do-list.step deleted file mode 100644 index c9dbe4ea7..000000000 --- a/sites/en/javascript-to-do-list/javascript-to-do-list.step +++ /dev/null @@ -1,76 +0,0 @@ -message <<-MARKDOWN -### Goal - -By the end of this session, you should understand how JavaScript is used -in a modern web application. You're going to be building a personal to do list application. -You've decided that you'd like to: - -* Add an item to your list -* Mark an item as complete -* Load your list from multiple computers. - -You've sketched up an initial screenshot of what you want it to look like: - -![Browser window with list application running](img/finished_app.png) - -### Meta-Goal - -When you have completed today's goal of getting the basic -application online you should understand: - -* How JavaScript, CSS, and HTML interact with the browser. -* How to use JavaScript to interact with a server. -* How to incrementally add features to your application. -* How to get your application online. - -### Schedule - -* 2-ish hours of JavaScript and the basics of clients and servers. -* 3-ish hours of adding features to you application, broken up into 1 hour chunks. - -This is just a rough guideline, not a mandate. Some steps you'll go -over and some you'll go under. It'll all work out by the end of the -day. Probably. - -### Requirements - -When programming, you'll generally want these tools on hand: - - * An internet connection. We're going to be communicating with other websites using JavaScript. - * Your browser to see the code running (I recommend Chrome, but any will do!) - * A text editor to change the code (I recommend Sublime) - * A javascript console so you can experiment and print out debugging - messages. This is built into your browser. - -Before you can start the tutorial, you'll need to download the tutorial -to your computer to edit the source code. - -Once you've downloaded it, open index.html with your browser. You should see a mock up of your list. If you do not, get an instructor to help you out. - -### Format - -Each lesson will look like this: - -
      -

      Step Title

      -
      -

      Goal:

      -

      Description of the current step. -

      Red because big goals are scary. -

      -
      -

      Steps:

      -
      steps to take.
      -

      Yellow because we've gotten it done, but we have no clue what's going on. -

      -
      -

      Explanation

      -

      Details of what the steps actually did... spell out the cause and effect. -

      Green because we can tie everything together now. -

      -
      -MARKDOWN - -next_step "the_basics_of_a_website" - diff --git a/sites/en/javascript-to-do-list/loading_items.step b/sites/en/javascript-to-do-list/loading_items.step deleted file mode 100644 index 30a74a596..000000000 --- a/sites/en/javascript-to-do-list/loading_items.step +++ /dev/null @@ -1,105 +0,0 @@ -goals do - goal "Make an AJAX request and update the page based on the server's response." - goal "Load your list's items every time a user visits the page." -end - -overview do - message <<-MARKDOWN - Last lesson, we made AJAX requests in the browser's console to load all of - our list's items. Now, we'll tie that AJAX request to our web site! Here's what will happen. - - 1. Every time a user visits our site, the browser will run the JavaScript in app.js. - 2. It will use jQuery's AJAX method to make a request to http://listalous.herokuapp.com/ and - get all the data about our list's items. - 3. We will then use JavaScript to turn those items into HTML elements, and attach them to our list. - MARKDOWN -end - -steps do - step do - message <<-MARKDOWN -Open app.js in your text editor. Add the following code to the bottom of the file. -Replace 'YOUR-LIST-NAME-HERE' with the name of the list you created last lesson. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - var loadRequest = $.ajax({ - type: 'GET', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/" - }) - JAVASCRIPT - - message <<-MARKDOWN -Refresh the page, and click over to your browser's network tab. You should see -a new request there, that visits our server at https://listalous.herokuapp.com/. - MARKDOWN - end - - step do - message <<-MARKDOWN - Now that we've made the request, we need to update the page whenever the request - succeeds. Add the following lines of code to the bottom of app.js. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - loadRequest.done(function(dataFromServer) { - var itemsData = dataFromServer.items - - itemsData.forEach(function(itemData) { - addItemToPage(itemData) - }) - }) - JAVASCRIPT - - message <<-MARKDOWN - Now refresh the page. Once the AJAX request succeeds, your site should now display - all the items you created last lesson! If not, flag an instructor down to help you - debug the problem. - MARKDOWN - end - -end - - -explanation do - message "App.js should now look like this." - source_code :javascript, <<-JAVASCRIPT - var itemTemplate = $('#templates .item') - var list = $('#list') - - var addItemToPage = function(itemData) { - var item = itemTemplate.clone() - item.attr('data-id',itemData.id) - item.find('.description').text(itemData.description) - if(itemData.completed) { - item.addClass('completed') - } - list.append(item) - } - - var loadRequest = $.ajax({ - type: 'GET', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/" - }) - - loadRequest.done(function(dataFromServer) { - var itemsData = dataFromServer.items - - itemsData.forEach(function(itemData) { - addItemToPage(itemData) - }) - }) - - JAVASCRIPT - - message <<-MARKDOWN -You've web page has made its first successful AJAX request! Now, your page will -load your list's items whenever you visit it. Once we host this page on the internet, -you will be able to see your list on any computer, tablet, or phone! - MARKDOWN -end - - - - -next_step "adding_an_item" diff --git a/sites/en/javascript-to-do-list/marking_an_item_as_complete.step b/sites/en/javascript-to-do-list/marking_an_item_as_complete.step deleted file mode 100644 index b3ed58c86..000000000 --- a/sites/en/javascript-to-do-list/marking_an_item_as_complete.step +++ /dev/null @@ -1,144 +0,0 @@ -goals do - goal "Allow a user to mark an item as complete or incomplete." - goal "Understand how to bind a complex event listener that requires event delegation." - goal "Understand how to parse complex information from the page." - goal "Understand how to make nuanced changes to the page." -end - -overview do - message <<-MARKDOWN -In this lesson, we'll allow our users to mark items as complete and incomplete. As they -do, we will ask the server to update the item's status in its database. This process will look -a lot like the process for adding an item, with some additional complexity. - -First off, the event listener is slightly more complex. Instead of binding a listener to -a single form (like we did in the last lesson), we'll be binding a listener to every check -mark in the list. jQuery's .on function allows you to do this, using __event delegation__. - -Secondly, it will be slightly harder to get the required information from the page when -the user clicks a check mark. We need to know which item they clicked, it's id (so the server -can identify it), and whether it has been completed or not. - -And finally, we need to use jQuery to add and remove classes based on whether the item is completed. -Let's get started! - MARKDOWN -end - - -steps do - step do - message "Add the following code the bottom of app.js." - - source_code :javascript, <<-JAVASCRIPT - $('#list').on('click', '.complete-button', function(event) { - alert('trying to complete an item!') - }) - JAVASCRIPT - - message <<-MARKDOWN -Refresh the page and try completing an item. An alert should pop up! - MARKDOWN - end - - step do - message "Now, we're going to get all the information we need from the page. Remove the alert from last step, and add the following code." - - source_code :javascript, <<-JAVASCRIPT - var item = $(event.target).parent() - var isItemCompleted = item.hasClass('completed') - var itemId = item.attr('data-id') - alert('clicked item ' + itemId + ', which has completed currently set to ' + isItemCompleted) - JAVASCRIPT - - message <<-MARKDOWN -Try marking an item complete again. Does the alert reference the correct item and the correct -completed value? Mark a few other items complete. Does it still work? - MARKDOWN - end - - step do - message <<-MARKDOWN -Now that we have the necessary information, we'll make another request to the server. -This is a url and type we haven't used before! What do you think it does? - -Remove the alert we wrote in the last step, and replace it with the following code. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - var updateRequest = $.ajax({ - type: 'PUT', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/items/" + itemId, - data: { completed: !isItemCompleted } - }) - - JAVASCRIPT - - message <<-MARKDOWN -Refresh the page and try marking an item as complete. Check the network tab to see if -a new request was made! - MARKDOWN - end - - step do - message <<-MARKDOWN -Finally, we'll update the item that has been marked as incomplete or complete. -Instead of creating a new item, we'll simple add or remove the class 'completed' -from the specified item (using jQuery's helpful addClass and removeClass functions). -This will cause the browser to render the item differently, based on the rules -written in styles.css. Add this line of code after the updateRequest. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - updateRequest.done(function(itemData) { - if (itemData.completed) { - item.addClass('completed') - } else { - item.removeClass('completed') - } - }) - JAVASCRIPT - - message <<-MARKDOWN -Mark an item as complete, and see it turn gray! If you mark a completed item as incomplete, -it should change colors, too. - MARKDOWN - end -end - -explanation do - - message "Here's what the bottom of app.js should now look like:" - - source_code :javascript, <<-JAVASCRIPT - $('#list').on('click', '.complete-button', function(event) { - var item = $(event.target).parent() - var isItemCompleted = item.hasClass('completed') - var itemId = item.attr('data-id') - - var updateRequest = $.ajax({ - type: 'PUT', - url: "https://listalous.herokuapp.com/lists/YOUR-LIST-NAME-HERE/items/" + itemId, - data: { completed: !isItemCompleted } - }) - - updateRequest.done(function(itemData) { - if (itemData.completed) { - item.addClass('completed') - } else { - item.removeClass('completed') - } - }) - }) - - JAVASCRIPT - - message <<-MARKDOWN -You've now written three ajax requests, making a modern, dynamic web page. Don't worry if you -didn't understand every line of code – JavaScript is complex stuff! - -There are many more features you could add (deleting items, sorting items, etc.) but in our next -lesson, we'll add the most important feature: the ability of users to actually use your site! - MARKDOWN -end - -next_step "deploying_your_site" diff --git a/sites/en/javascript-to-do-list/next_steps.step b/sites/en/javascript-to-do-list/next_steps.step deleted file mode 100644 index 2e327e880..000000000 --- a/sites/en/javascript-to-do-list/next_steps.step +++ /dev/null @@ -1,22 +0,0 @@ -message < - -Congrats, you just wrote your first lines of JavaScript code! __console.log__ is an important function – -it allows you to print information to the browser's console. It's very helpful in debugging! You can also -use the __alert__ function to make a message pop up in the browser. Try it out! - MARKDOWN - end - - step do - message "Next try some simple math that's built into JavaScript. Type these lines into console:" - - source_code :javascript, <<-JAVASCRIPT - 3 + 3 - 7 * 6 - JAVASCRIPT - end - - step do - message "**Variables** are names with values assigned to them." - - source_code :javascript, <<-JAVASCRIPT - var myVariable = 5 - JAVASCRIPT - - message "This assigns the value `5` to the name `myVariable`." - end - - step do - message "You can also do math with variables:" - source_code :javascript, <<-JAVASCRIPT - myVariable + 2 - myVariable * 3 - JAVASCRIPT - end - - step do - message "Variables can also hold more than one value. This is called an **array**." - - source_code :javascript, 'var fruits = ["kiwi", "strawberry", "plum"]' - - message "Here we're using the variable `fruits` to hold a collection of fruit names." - end - - step do - message "Arrays are a type of __object__ in JavaScript. Objects often include helpful attributes!" - - source_code :javascript, <<-JAVASCRIPT - fruits.length - JAVASCRIPT - - message <<-MARKDOWN -Objects can also have __functions__, which can be helpful for altering objects and learning more about them. -Functions are __invoked__ with parentheses, which causes them to run. - MARKDOWN - - source_code :javascript, <<-JAVASCRIPT - fruits.push("orange") - fruits.slice(1) - JAVASCRIPT - - message <<-MARKDOWN -The __push__ function allows us to add new items to an array. the slice function returns a new array with -with everything to the right of the __index__ we provided. Here, we passed the function the number 1, so -slice returned an array with everything after the first element in the array. (Note that the first element is assigned 0 as its index rather than 1).) - MARKDOWN - end - - step do - message "You can also make your own functions:" - - source_code :javascript, <<-JAVASCRIPT - var pluralize = function(word) { - return word + "s" - } - pluralize("kiwi") - JAVASCRIPT - - message "Functions take **parameters**, which are the variables they work on. In this case, we made a function called pluralize that takes one parameter, a word." - - message "Functions can also return data. In this case, pluralize returns the word with an 's' added to the end of it. In order for a function to return something, you have to use the __return__ keyword." - end - - - step do - message "Arrays have a function called **forEach** which iterates through the list running code on each item. It takes another function as a parameter." - source_code :javascript, <<-JAVASCRIPT - fruits.forEach(function(fruit) { - console.log(fruit) - }) - JAVASCRIPT - message "This takes the first item from the `fruits` array (`\"strawberry\"`), assigns it to the variable `fruit`, and runs the code between curly brackets. Then it does the same thing for each other item in the list. The code above should print a list of the fruits." - end - - step do - message "A **conditional** runs code only when a statement evaluates to true." - - source_code :javascript, <<-JAVASCRIPT - if(myVariable > 1) { - console.log('YAY') - } - JAVASCRIPT - - message "This prints `YAY!` if the value stored in `myVariable` is greater than 1." - - message "Try changing the `>` in the conditional to a `<`." - end -end - - - -next_step "playing_with_jquery" diff --git a/sites/en/javascript-to-do-list/the_basics_of_a_website.step b/sites/en/javascript-to-do-list/the_basics_of_a_website.step deleted file mode 100644 index fba2eba2d..000000000 --- a/sites/en/javascript-to-do-list/the_basics_of_a_website.step +++ /dev/null @@ -1,97 +0,0 @@ -goals do - goal "Understand the purposes of HTML and CSS." - goal "Write some basic code in each language." -end - -overview do - - message <<-MARKDOWN - -## What makes a website? - -Modern websites are built using three languages: __HTML, CSS, and JavaScript__. - - * __HTML__ stands for __H__yper-__t__ext __M__arkup __L__anguage. It provides the structure for your website, using a system of nested __tags__. - - * __CSS__ stands for __C__ascading __S__tyle__s__heets. It's a language for creating rules that can select various elements on the page and change their visual properties. A CSS stylesheet is composed of __rules__ that dictate how your site is presented. - - * __JavaScript__ allows users to interact with your website, making it dynamic and customizable. It's a powerful language that can be used for extraordinarily complex tasks. - -In this lesson, we'll be reviewing HTML and CSS at a high level, and see how they interact. -You'll need to fire up your text editor for these steps. -MARKDOWN -end - -steps do - - step do - message < - -Take a look around. What are the different elements doing? Why are some lines indented deeper -than others? What are those strange series of numbers and ampersands? - -Finally, you should find this line of code in index.html: -MARKDOWN - source_code :html, <<-HTML -

      Your List App

      - HTML - message "and change the text whatever you want your list application to be called. Save your file. Go back to chrome and refresh the page. Your list application should have changed!" - end - - step do - message < - - -
        -
      - HTML - end - - -end - -next_step "developer_tools" \ No newline at end of file diff --git a/sites/en/job-board/add_a_navbar.step b/sites/en/job-board/add_a_navbar.step deleted file mode 100644 index a32c9700a..000000000 --- a/sites/en/job-board/add_a_navbar.step +++ /dev/null @@ -1,115 +0,0 @@ -message <<-MARKDOWN - # What we're going to do - - * Add top-level navigation - * Learn about CSS organization techniques - * Add some really, really ugly CSS to our app - - # Application layout - - We'll start with the application layout, which you can find in the views directory, at `app/views/layouts/application.html.erb`. -MARKDOWN - -discussion_box "What's an application layout?", <<-MARKDOWN - None of the view pages that we've been working with so far have had the necessary structure for a valid HTML page. No `` or `` or JavaScript or CSS tags. This application layout file is where all of that stuff exists! - - * How is this page related to the individual page content? Try comparing the source in the browser to this file, and see where the individual page's code starts showing up. - * If you add something (say, an h1) to this file, where will it show up? -MARKDOWN - -message <<-MARKDOWN - # Add the markup - Copying and pasting a nav bar onto every. single. page. of our application would be the worst. So instead of putting it into our individual pages, we'll add the nav bar HTML to this file! - - Add the following code **above** the line `<%= yield %>` -MARKDOWN - -source_code :erb, - <<-ERB -
      -
      -
        -
      • <%= link_to "Home", jobs_path %>
      • -
      -
      -
      -
        -
      • <%= link_to "Add Job", new_job_path %>
      • -
      -
      -
      -
      - ERB - -message <<-MARKDOWN - Things to note: - - * We use Rails link helpers instead of typing in `Add Job`. The reason is that if the url of a page changes in the future, without the link helpers, we’d have to update every single place we link to that page. The link helpers abstract the actual url for us, so if we change a specific url, we update the address in only one place, in the routes file; and all the places we link to it stay the same. - * The `
      ` tag is HTML5. Aren't we cool!? - - So let's take a look at it. Refresh, and ... isn't that horrifying looking? Let's make it look like a nav, albeit a very ugly one. - - # Add the styles - - Open up the assets directory, and you should have a file here: app/assets/stylesheets/jobs.css.scss. This is a Rails-default created stylesheet, and isn't the best. [Smart CSS people](http://www.stubbornella.org/content/2013/09/12/rails-is-mucking-up-my-css-already/) have taught us that CSS should be organized into [reusable components](https://github.com/stubbornella/oocss/wiki), not organized based on where it is used. - - So let's delete that file and make a new one. - - Actually, we're going to make two new ones. Under `app/assets/stylesheets`, add `global.css.scss`: -MARKDOWN - -source_code :CSS, -<<-CSS - body { - margin: 0; - } - - .content { - margin: 10px auto; - width: 70%; - } - - .clearfix { - clear: both; - } -CSS - -message <<-MARKDOWN - This is where we put styles that affect the whole app. - - Now, under `app/assets/stylesheets`, add `nav.css.scss`: -MARKDOWN - -source_code :CSS, -<<-CSS - header { - background: grey; - padding: 10px; - ul { - margin: 0; - padding: 0; - list-style-type: none; - } - a { - text-decoration: none; - font-weight: bold; - color: white; - } - } - - .left-nav { - float: left; - } - - .right-nav { - float: right; - } -CSS - -message <<-MARKDOWN - Refresh the page, and ... it's still totally horrific. This CSS is not going to win any awards. - - But it's usable, and we can keep working on that later. It turns out sometimes job descriptions have typos, and need to be updated. Let's make that possible! -MARKDOWN - -next_step "update_job_listings" diff --git a/sites/en/job-board/add_a_new_job_form.step b/sites/en/job-board/add_a_new_job_form.step deleted file mode 100644 index cf30583f9..000000000 --- a/sites/en/job-board/add_a_new_job_form.step +++ /dev/null @@ -1,83 +0,0 @@ -message <<-MARKDOWN - # What we're going to do - - * Use Rails form helpers to create the HTML for the form - * Learn to use the Rails server output for great good - * Update the controller so that the form saves submissions to the database - * Learn about the beauty of the params hash - - # Side Note: Web forms are not perfectly straightfoward - - Web forms. They're like, the most basic thing about the internet, other than cat gifs, right? So they should be straightforward, right? WRONG! They are exciting and just complicated enough to bake your noodle a bit. But don't worry, Rails has strong opinions about forms, so we won't have to do _too_ much typing. - - # Setting up the page for the form - - Let's take a look at our handy routes, which can help us figure out what we need to do. We're going to follow the same pattern that we did for the main `/jobs` page. - - First, visit the routing page at , and find the route for `/jobs/new`. - - That's the one we want for our form. Let's visit that page and see what it says: . -MARKDOWN - -error_box "The action 'new' could not be found for JobsController" - -source_code_with_message "This looks familiar! Let's add a method to our jobs controller called `new`:", :ruby, -<<-RUBY - def new - end -RUBY - -message <<-MARKDOWN - Refresh , and we see that familiar "Template is missing" error. So, let's add that template. - - Under app/views/jobs, add a file called new.html.erb. This will be our form. Add some html to the template to keep things moving along: -MARKDOWN - -source_code :html, -<<-HTML -

      Add a job

      -HTML - -message <<-MARKDOWN - Refresh again: - - # Add a form! - - Rails has handy helpers for forms. We'll be using a form helper specifically made for use with a model. -MARKDOWN - -source_code_with_message "In the view file you were just editing (app/views/jobs/new), add the following code:", :erb, -<<-ERB - <%= form_for @job do |f| %> -
      - <%= f.label :title %> - <%= f.text_field :title %> -
      -
      - <%= f.label :description %> - <%= f.text_area :description, size: '60x6' %> -
      -
      - <%= f.submit %> -
      - <% end %> -ERB - -message "Save that file, and reload the page." - -error_box "First argument in form cannot contain nil or be empty" - -message "What do you think that means? What is the first argument? What is it supposed to be? In order for the method `form_for` to do its job, it has to know about the thing that it's building the form for. So we need to give it an object. We do that in the controller." - -source_code_with_message "Open up the jobs_controller, and update the new method:", :ruby, -<<-RUBY - def new - @job = Job.new - end -RUBY - -message "Now we should see our mostly unstyled form!" - -discussion_box "Form HTML", "What HTML did the form helpers produce? Using the web inspector, look through the form code and compare it to the file you've been working on in Sublime." - -next_step "make_the_form_work" diff --git a/sites/en/job-board/add_more_things.step b/sites/en/job-board/add_more_things.step deleted file mode 100644 index 34fb14c95..000000000 --- a/sites/en/job-board/add_more_things.step +++ /dev/null @@ -1,18 +0,0 @@ -message <<-MARKDOWN - - ## Time to add more things! - - The time where we tell you what to type in has finally ended. You should do one or all of the things below! - - Working independently or in pairs is super fun at this point. - - * Add a show page for each listing and move the Edit and Delete links to there. - * Add validations — postings without titles or descriptions shouldn't be allowed, right? - * Add other useful fields to jobs - * Display jobs index in a table; make sortable with data_tables - * Add tags (time for a has_many, folks!!!) - * Make it look better - * Add a user model and auth with Devise - * Test it! Write a controller spec. - -MARKDOWN diff --git a/sites/en/job-board/create_a_rails_app.step b/sites/en/job-board/create_a_rails_app.step deleted file mode 100644 index 2c767755a..000000000 --- a/sites/en/job-board/create_a_rails_app.step +++ /dev/null @@ -1,75 +0,0 @@ -message <<-MARKDOWN - # What we're going to do: - - * Make a new Rails app - * Add a few gems to make life easier - * Start the Rails server and see the default Rails page - * Learn a little about Bundler and dependency management - - # Get Set Up - - First, let's get into a directory for RailsBridge projects (either by finding your existing one & moving there or making a new folder). - - If you don't already have a RailsBridge folder, use the commands `mkdir` and `cd` to create one and move into it: -MARKDOWN - -console_without_message "mkdir railsbridge" -console_without_message "cd railsbridge" - -message <<-MARKDOWN - # Rails New!!! -MARKDOWN - -console "rails new job_board -T --skip-turbolinks" - -message <<-MARKDOWN - The `-T` in that command means that when you make new files using Rails generators, it doesn't automatically create test files using Test::Unit (the default Rails testing framework). - - Watch all the files that are created! Wow! - - # Open the project in Sublime Text -MARKDOWN - -console_with_message "Move into the directory for your new Rails app:", "cd job_board" - -message <<-MARKDOWN - And open the project in Sublime: - - * Open Sublime - * Under Project, choose "Add Folder to Project" - - (You must have at least one window open, so if that option is greyed out, open a window with cmd+n (Mac) or ctl+n (PC)) -MARKDOWN - -discussion_box "Text Editor vs Command Line", "Review the differences between the the command line and your text editor, even if everyone already knows!" - -message "# Fix Up Those Defaults" - -source_code_with_message "We're going to be looking at the Rails server output, which includes a lot of noise by default. Find the file called 'Gemfile' by searching for it, and add the following line:", :ruby, "gem 'quiet_assets'" - -console_with_message "Save the file, and then in the command line, run the following command:", "bundle install" - -discussion_box "What does 'bundle' do?", <<-MARKDOWN - Bundler is the tool the Ruby community uses for dependency management. - - * What's dependency management? - * Why do we need it? - * Why do we even need gems? - * Is there a shorter method to use for `bundle install`? (Hint: yes!) -MARKDOWN - -message "# Look at your empty app" - -tip "Now is a good time to figure out how to have multiple tabs or windows of your terminal or command prompt. Starting and stopping the Rails server all day is tedious, so it's good to have one terminal tab or window for running commands, and a separate one for the server." - -console_with_message "Start the Rails server by running this command in the terminal:", "rails server" - -message <<-MARKDOWN - Now, let's check out our default home page - - In the broswer, visit - - Yup, that's the default Rails home page! -MARKDOWN - -next_step "the_request_cycle" diff --git a/sites/en/job-board/crud_and_resourceful_routing.step b/sites/en/job-board/crud_and_resourceful_routing.step deleted file mode 100644 index 0c4678418..000000000 --- a/sites/en/job-board/crud_and_resourceful_routing.step +++ /dev/null @@ -1,38 +0,0 @@ -message <<-MARKDOWN - # CRUD - Why do we talk about building CRUD apps? What are some examples of CRUD apps that you use? - - Each action that CRUD describes maps to a SQL statement and an HTTP verb: - - Table mapping CRUD operations to SQL and HTTP verbs - - *Source: * - - Compare this to what we see at : - - !["Screenshot of Rails routes page"](img/rails-routes.png) -MARKDOWN - -discussion_box "CRUD", "Talk through the different uses for the HTTP verbs. What is their general purpose, and what are we specifically using them for??" - -message <<-MARKDOWN - To have a useful app, we need to be able to create job postings, see them all and their details, change them, and delete them. The way that Rails wants us to do this is by following RESTful routing conventions, which are perfectly encapsulated by the output of `resources :jobs` in our routes.rb file. - - In Rails we work with seven main verbs, which map to different CRUD actions and controller actions: - - Table mapping CRUD operations to REST verbs - - What does each of these do? Go through each method and review what they do. - - # Resourceful Routing - - You could make your URLs look like anything you wanted, like: `/all_the_jobs` or `/add_a_job` or `show_job`. This would totally work if you set up your controller methods and the route file correctly. - - But we generally avoid this because the RESTful routing is a best practice that Rails makes easy to follow. In RESTful routes, the paths are structured around a specific resource — in our case, jobs. Check out more about [RESTful](http://en.wikipedia.org/wiki/Representational_state_transfer) urls. - - Another example: if we were making a puppy app, I would expect that going to `/puppies` would show me an index of all the puppies, and `/puppies/1` would find the puppy with the ID of one and show me their individual page, and `/puppies/1/edit` would show me the form to update a given puppy. - - For more info on resource-based routing, check out the [Rails Guide on routing](http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default). -MARKDOWN - -next_step "listing_the_jobs" diff --git a/sites/en/job-board/delete_job_listings.step b/sites/en/job-board/delete_job_listings.step deleted file mode 100644 index 9d139e861..000000000 --- a/sites/en/job-board/delete_job_listings.step +++ /dev/null @@ -1,66 +0,0 @@ -message <<-MARKDOWN - # What we're going to do - - * Remove postings - - Once a job is filled, we don't want a listing for it hanging out forever. Let's add a way to delete postings. - - # Postings be gone! - - If we look at our [handy Routes page](http://localhost:3000/rails/info/routes), we see this: -MARKDOWN - -source_code :html, "job_path DELETE /jobs/:id(.:format) jobs#destroy" - -message "So we need to send the DELETE http verb to the server, so we can get to the destory method on the jobs controller (that we will make soon). It turns out rails link_to helpers accept specific verbs as an argument, so we can add this line below the edit posting link that we just added:" - -source_code :erb, "
      <%= link_to 'Delete Posting', job, method: :delete %>
      " - -message "Go to the index, and try to delete something." - -error_box "The action 'destroy' could not be found for JobsController" - -message "This is like my favorite error now! First, let's add the method:" - -source_code :ruby, -<<-RUBY - def destroy - end -RUBY - -message <<-MARKDOWN - This fixes the error. But just like updating, we still need to add the logic that actually deletes the job. - - See if you can figure out the right syntax for finding the job, deleting it, and then redirecting to a useful page. - - **Don't scroll down!!!** -MARKDOWN - -message <<-MARKDOWN - * here - * is - * even - * more - * strategic - * white - * space - * so - * the - * answer - * isn't - * immediately - * visible! - - Okay, here's the answer: -MARKDOWN - -source_code :ruby, -<<-RUBY - @job = Job.find(params[:id]) - @job.destroy - redirect_to jobs_path -RUBY - -message "Try it again, and... kablammo! We're destroying job listings left and right!" - -next_step "add_more_things" diff --git a/sites/en/job-board/img/crud_grid.jpg b/sites/en/job-board/img/crud_grid.jpg deleted file mode 100644 index 408bf0956..000000000 Binary files a/sites/en/job-board/img/crud_grid.jpg and /dev/null differ diff --git a/sites/en/job-board/img/crud_rails_methods.jpg b/sites/en/job-board/img/crud_rails_methods.jpg deleted file mode 100644 index a37308843..000000000 Binary files a/sites/en/job-board/img/crud_rails_methods.jpg and /dev/null differ diff --git a/sites/en/job-board/img/rails-routes.png b/sites/en/job-board/img/rails-routes.png deleted file mode 100644 index 086b0eea4..000000000 Binary files a/sites/en/job-board/img/rails-routes.png and /dev/null differ diff --git a/sites/en/job-board/img/request-cycle.jpg b/sites/en/job-board/img/request-cycle.jpg deleted file mode 100644 index 53ac5ed5b..000000000 Binary files a/sites/en/job-board/img/request-cycle.jpg and /dev/null differ diff --git a/sites/en/job-board/job-board.step b/sites/en/job-board/job-board.step deleted file mode 100644 index 36041a34b..000000000 --- a/sites/en/job-board/job-board.step +++ /dev/null @@ -1,30 +0,0 @@ -message <<-MARKDOWN - We're going to build a job board in Rails using the tried-and-true method of following the errors that we make! - - Rails generators will help us avoid some tedious file creation, but provide a lot less magic than scaffolding (which is what is used in the Suggestotron to create *everything* for a Topic all at once). - - This means we'll a get a little less done today than we did when we built Suggestotron. But we're going to build an app in little pieces, so you can focus on understanding how the pieces fit together. -MARKDOWN - -tip "This is not a self-paced curriculum. You should use the discussion sections on each page to make sure everyone is together!" - -message <<-MARKDOWN - # Notable Things - - As you might have noticed, we're assuming you've already been to a RailsBridge workshop before or have otherwise already explored a Rails app, and are ready for deeper knowledge. - - We're also going to skip deploying to Heroku this time around, but you can definitely use the instructions from the Suggestotron curriculum to deploy your app to the internet! -MARKDOWN - -important "This curriculum is written for Rails 4. Things will get awkward / broken if you're using Rails 3, so if you skipped the Installfest, you need to upgrade to Rails 4 now." - -message <<-MARKDOWN - # Tips for everyone: - - * When adding code, it's awesome for students to walk through the code line by line and say out loud what is happening. (i.e., "The string is being stored in the instance variable" or "The method `snorgle` is being defined"). If you do it every time, you'll get really comfortable with the vocabulary of Rails! - * Error messages are your friend! Read them carefully, and practice understanding what Rails is telling you. Seeing an error and just diving back into your code is a natural reaction, but stop! Then read, think, and talk about what the error means before fixing it. -MARKDOWN - -insert '../intro-to-rails/working_effectively_and_efficiently' - -next_step "create_a_rails_app" diff --git a/sites/en/job-board/listing_the_jobs.step b/sites/en/job-board/listing_the_jobs.step deleted file mode 100644 index 298634793..000000000 --- a/sites/en/job-board/listing_the_jobs.step +++ /dev/null @@ -1,51 +0,0 @@ -message <<-MARKDOWN - # What we're going to do - - * Show the jobs! - * Learn about ERB - - Going back to the jobs index (), we expect to see the new jobs. Let's actually build the job board part of this job board now! - - # Get all the jobs out of the database - - If we're going to show our jobs in view, first we have to get them out of the database and store them in an instance variable. Update the index method to look like this: -MARKDOWN - -source_code :ruby, -<<-RUBY - def index - @jobs = Job.all - end -RUBY - -message <<-MARKDOWN - Before we show the jobs, let's actually look at what that is doing. Go back to your Rails console and run `Job.all`. -MARKDOWN - -discussion_box "Rails Console", <<-MARKDOWN - The Rails console is super fun! It's giving us direct access to our local database. - - * Try running `Job.all.to_sql`. What does that do? - * Try selecting an individual Job record. - * Try updating an that individual record from the console! -MARKDOWN - -message "# Show those jobs!" - -source_code_with_message "Add this to app/views/jobs/index.html.erb:", :ruby, -<<-RUBY - <% @jobs.each do |job| %> -

      <%= job.title %>

      -

      <%= job.description %>

      - <% end %> -RUBY - -discussion_box "ERB", <<-MARKDOWN - What is this doing? Go through this line by line, having one person explain each line. - - Compare the ERB to the HTML that shows up on the page. ("Inspect Element" is your friend!) - - What's the difference between a line with `<% %>` brackets and `<%= %>` brackets? -MARKDOWN - -next_step "add_a_navbar" diff --git a/sites/en/job-board/make_a_jobs_home_page.step b/sites/en/job-board/make_a_jobs_home_page.step deleted file mode 100644 index 832597ded..000000000 --- a/sites/en/job-board/make_a_jobs_home_page.step +++ /dev/null @@ -1,120 +0,0 @@ -message <<-MARKDOWN - # What we're going to do: - - * Play follow-the-error to guide our development - * Add routes, a controller, and a view to make a home page - * Learn how to read the routing info at - - # Getting Started - - That Rails default page is boring. Let's add a page to list the open jobs at RailsBridgeCorp! - - To start, let's visit the page that we want to put our jobs on: . -MARKDOWN - -error_box "No route matches [GET] '/jobs'" - -message <<-MARKDOWN - That's pretty reasonable, since we currently don't have any routes at all right now. - - # Adding Routes - - So it's looking for a route, but can't find one. Let's add one! - - Open up the routes file. It's in the config directory, called `routes.rb`. If you're using Sublime Text 2, you can open it using keyboard shortcuts: - - * Hitting cmd + p (on Mac) or ctl + p (on PC) - * typing in `route` - * hitting enter - - Magic! (Sublime is using fuzzy search, so you can use the entire file path, or just part of the filename to go to files.) -MARKDOWN - -source_code_with_message "We're going to need a resource route, which will create EIGHT different routes for us. Add this to line two:", :ruby, "resources :jobs" - -message <<-MARKDOWN - Now, lets go look at what that made, by using the excellently helpful page available on any Rails 4 app: . -MARKDOWN - -discussion_box "How to read the routes page.", <<-MARKDOWN - In your browser, visit . Go over each of the columns and how to read it. - - * Helper - * HTTP Verb (don't worry about going to in-depth with these yet) - * Path - * Controller#Action - - Why does the Helper column sometimes not have anything? - - Can you find the line that will make `/jobs` a route? -MARKDOWN - -tip "If you are on Rails 3, going to /rails/info will **fail**! Stop right now and upgrade to Rails 4." - -message <<-MARKDOWN - Since adding the line `resources :jobs` made a route matching `/jobs`, let's go visit that page again: -MARKDOWN - -error_box "uninitialized constant JobsController" - -message <<-MARKDOWN - Why does Rails now think it needs a JobsController? - - # Add a controller - - Time for a shortcut!!! Unlike the scaffold that we make in Suggestotron that makes about a million different files, we're just going to use a Rails generator to make the files we need. -MARKDOWN - -console "rails generate controller jobs" - -discussion_box "What did that command do?", <<-MARKDOWN - What files were made by that last command? Are they awesome? - - How will this change what error we see when we go to the jobs page? -MARKDOWN - -message "Now: refresh " - -error_box "The action 'index' could not be found for JobsController" - -message <<-MARKDOWN - What is telling Rails to look in JobsController? - - Let's go back to again and look at what controller and method (AKA action) the route /jobs is pointing to. - - It's looking for a method called index on the jobs controller! Since there isn't a controller method for this route, we'll need to add it. - - Open up your jobs controller (again, try to use keyboard shortcuts: cmd+p on Mac or ctl+p on PC to find the file at app/controllers/jobs_controller.rb). -MARKDOWN - -source_code_with_message "Add the index method to the controller:", :ruby, -<<-RUBY - def index - end -RUBY - -message "And refresh " - -error_box "Missing template jobs/index, application/index with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in: * '/Users/probablyyou/railsbridge/job_board/app/views'" - -message <<-MARKDOWN - What's the important part of the this error? How does Rails decide to look for something called jobs/index? How did it decide to look in the views directory? - - Talk through what Rails is trying, and failing, to do, and how file names and method names are important here. - - # Add a view - - Within app/views/jobs, add a file called index.html.erb. - - Save that file, and refresh - - NO ERROR!?!?! How boring. Let's add some content so we can be more confident that this really a thing. -MARKDOWN - -source_code_with_message "Within index.html.erb, add this (or the name of your fictional megacorp):", :html, "

      RailsBridgeCorp Open Jobs

      " - -message <<-MARKDOWN - DONE! Well, except that we don't have any jobs. And even though we could hand-code a table of job titles here, that would be awfully tedious and we'd probably get sick of adding job postings every time someone came up with a new volunteer position. Let's empower people to add their own postings! -MARKDOWN - -next_step "store_jobs_in_the_database" diff --git a/sites/en/job-board/make_the_form_work.step b/sites/en/job-board/make_the_form_work.step deleted file mode 100644 index 850dedfc0..000000000 --- a/sites/en/job-board/make_the_form_work.step +++ /dev/null @@ -1,132 +0,0 @@ -message <<-MARKDOWN - # What we're going to do - - * Make the form actually work - * Learn how to read server output - * Review happy debugging techniques - - # Partytime: Use the form to Create Objects -MARKDOWN - -message "Now, try to submit your form." - -error_box "The action 'create' could not be found for JobsController" - -message <<-MARKDOWN - So, let's add it: - - (Don't forget to navigate to the jobs controller by using the search shortcut, cmd+p or ctl+p) -MARKDOWN - -source_code :ruby, -<<-RUBY - def create - end -RUBY - -message "Reload the page!" - -error_box "Missing template jobs/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in: * '/Users/lillie/railsbridge/job_board/app/views'" - -<<-MARKDOWN - Familiar error, right? We don't have a template called create.html.erb. - - BUT!!! This time we're not going to make one. - - We actually want to go somewhere useful, right? Let's go back to the main jobs page (where we will eventually be listing our jobs). We need to tell the create method where to go, instead of letting it decide based on method name. -MARKDOWN - -source_code :ruby, -<<-RUBY - def create - render :index - end -RUBY - -message <<-MARKDOWN - Okay, now go to again, and submit a new job. - - Hopefully it went to the right place! But did it do anything? - - Sadly, no. We just took our form contents and dropped them on the ground. -MARKDOWN - -discussion_box "Logging & Server Output", -<<-MARKDOWN - Arrange your screens so that you can see your server logs (in the terminal window) at the same time as your browser. Now, refresh the form page, and look at what happens in the server. You should see output like `Started GET "/jobs/new"`. - - As a group or in pairs, go over the output of the server, talking through the various pieces of information you see. -MARKDOWN - -message <<-MARKDOWN - # Saving form data! - - Head back to , and get your Rails console and your browser next to eachother again. Submit the form again, this time looking for the section that looks something like: -MARKDOWN - -source_code :http, -<<-JSON - Parameters: { - "utf8"=>"✓", - "authenticity_token"=>"f48rtxanK9/MHu7TPvd6QzygGnrwv0P2/bxLllozw5U=", - "job"=>{ - "title"=>"Meta-organizer", - "description"=>"We need an somene to organize the organizers." - }, - "commit"=>"Create Job" - } -JSON - -message <<-MARKDOWN - This is the precious data that our form is sending, and right now we're just throwing it away. Let's not do that! Since we're using Rails 4 and all its great conventions, we're going to use Strong Parameters to limit what kind of data our form can submit to our app. -MARKDOWN - -source_code_with_message "Add this code to your jobs controller. (Notice that we're expanding the create method. Don't just copy and paste and end up with two create methods, folks.)", :ruby, -<<-RUBY - def create - Job.create(job_params) - redirect_to jobs_path - end - - private - - def job_params - params.require(:job).permit(:title, :description) - end -RUBY - -message <<-MARKDOWN - Walk through this code line by line with the class! (But don't get too hung up on how strong params works — suffice it to say that it limits the parameters that we'll allow in to the ones listed here.) -MARKDOWN - -console_with_message "Rails console time! Open up another tab or window in your terminal and type this:", "rails c" - -console_with_message "After that's loaded, let's see how many jobs we've saved to the database:", "Job.count" - -message <<-MARKDOWN - Now, submit a new job using the form. What's the count now? - - If the count is going up, yay!!! You got it! If not, time to debug! - - # Tips for Effective Debugging - - * Take a deep breath. Most of your time programming will be looking for bugs. - * Read the error message out loud. Even if you already think you know what it means. - * Check every assumption you can think of. You think that something is getting stored in a variable? WHO KNOWS? - * A good way to check your assumptions is to print out anything you can to the Rails server log. Add puts statements to your code! - * For example: If the jobs count isn't changing when we make jobs, make the jobs controller look like this. Now, it will print to the console the line "In the create method!!!!" and whatever is being returned from `Job.create(job_params)` -MARKDOWN - -source_code :ruby, -<<-RUBY - def create - p "In the create method!!!!!!" - job = Job.create(job_params) - p job - redirect_to jobs_path - end -RUBY - -message "* Think about how you would explain the problem to someone else, or, actually explain the problem to another student or a TA!" - -next_step "crud_and_resourceful_routing" diff --git a/sites/en/job-board/store_jobs_in_the_database.step b/sites/en/job-board/store_jobs_in_the_database.step deleted file mode 100644 index 671423044..000000000 --- a/sites/en/job-board/store_jobs_in_the_database.step +++ /dev/null @@ -1,85 +0,0 @@ -message <<-MARKDOWN - # What we're going to do: - - * Review what a database is - * Create a table in the database for jobs - * Learn what a migration file is -MARKDOWN - -discussion_box "Databases & SQL", -<<-MARKDOWN - Review how relational databases are structured, how we communicate with them (hint: SQL!). -MARKDOWN - -message <<-MARKDOWN - # Make a jobs model & migration - - In order to make it possible for users to create jobs, we need: - - * A place to store the jobs (a table in the database) - * Rails to know what a job is (a model) - - We're going to use another Rails generator; this time to make our migration and model! -MARKDOWN - -console "rails g model job" - -message <<-MARKDOWN - (The g stands for *generate*, which has many more letters than is necessary to type.) - - That generated two files: a migration and models/job.rb. - - # Make that migration file useful - - Open up the migration file that you just made (cmd+p / ctl+p, type 'create jobs', and hit enter) and you'll see the following: -MARKDOWN - -source_code :ruby, <<-RUBY - class CreateJobs < ActiveRecord::Migration - def change - create_table :jobs do |t| - - t.timestamps - end - end - end -RUBY - -message <<-MARKDOWN - Running this code will make a table in our database called jobs. Right now it just has the timestamps (`created_at` and `updated_at`). What else should a job have? Let's start with a title and description. - - Add the the title and description so it looks like this: -MARKDOWN - -source_code :ruby, <<-RUBY - create_table :jobs do |t| - t.text :title - t.text :description - t.timestamps - end -RUBY - -message "Now we need to execute this file, so that the database schema gets updated." - -console "rake db:migrate" - -message <<-MARKDOWN - This uses a utility called rake to run a task called `db:migrate`, which in turn looks through all of your migration files and runs any that haven't already been run at some point in the past. -MARKDOWN - -discussion_box "Why do we use migrations?", -<<-MARKDOWN - Talk about the pros and cons of using migrations to update the database, instead of just updating the schema directly. Also, discuss what the database schema is! - - (Pro-tip: *never* update the schema directly.) -MARKDOWN - -message <<-MARKDOWN - # Check out the model - - The migration we just ran updated the database, but that doesn't mean that we can talk to the database using Ruby yet. Look at the file `app/models/job.rb`. The `Job` class inherits from ActiveRecord::Base, so that we can talk to the database with Ruby instead of SQL! - - Okay, so we've got some place to store our jobs. But how can we make any? THROUGH THE MAGIC OF FORMS!!! -MARKDOWN - -next_step "add_a_new_job_form" diff --git a/sites/en/job-board/the_request_cycle.step b/sites/en/job-board/the_request_cycle.step deleted file mode 100644 index ce3281348..000000000 --- a/sites/en/job-board/the_request_cycle.step +++ /dev/null @@ -1,9 +0,0 @@ -message "" - -discussion_box "What is this diagram?", <<-MARKDOWN - Talk through this diagram of the request cycle! - - If there's room, act out a request being made as a tiny play, in which a small object is the request and the students are the various pieces of code that the request travels through. -MARKDOWN - -next_step "make_a_jobs_home_page" diff --git a/sites/en/job-board/update_job_listings.step b/sites/en/job-board/update_job_listings.step deleted file mode 100644 index a219a031c..000000000 --- a/sites/en/job-board/update_job_listings.step +++ /dev/null @@ -1,171 +0,0 @@ -message <<-MARKDOWN - # What we're going to do - - * Create a form for editing job listings - * Learn about partials - * Revel in the joy of Rails form helpers - - # Add the edit page -MARKDOWN - -source_code_with_message "Say we want to edit the first job posting. If we look at , we see this line:", :html, "edit_job_path GET /jobs/:id/edit(.:format) jobs#edit" - -message "So, it looks like if we want to edit the job description, we should visit this URL: ." - -source_code_with_message "We've seen this before, right? Let's add the controller action:", -<<-RUBY - def edit - end -RUBY - -source_code_with_message "Refresh, template is missing. Alright, let's add that edit view, under app/views/jobs/edit.html.erb", :erb, -<<-ERB -

      Edit Posting

      -ERB - -message <<-MARKDOWN - Okay, so that's awesome. Now we just have to add a form for editing. I wonder if it is any different from the create form? I guess we could copy and paste the other form? - - We could copy and paste from the other form, but we try to avoid that because duplicated code is hard to maintain. For example, if I want to add placeholder text for the inputs in the form, when the code is duplicated, I’ll need to update the code in each place the form was copied. (In large apps it’s easy to miss a place that would need to be updated.) The solution is to reuse rather than duplicate the code, and the way to reuse code in views is by using partials. -MARKDOWN - -discussion_box "Don't Repeat Yourself", -<<-MARKDOWN - * What are some reasons to DRY up our code? - * What are some strategies for DRYing up code throughout a Rails app? -MARKDOWN - -message <<-MARKDOWN - # Create a Partial - - Rails form helpers are designed beautifully for CRUD interfaces. So we're not gonna have to write very much code to make this form work for editing AND creating job postings. - - But first, a refactor: we're going to move the create form into a partial. - - (Refactoring is improving code while maintaining the behavior it produces.) - - Make a new file under jobs like so: `app/views/jobs/_form.html.erb`, and move the following code OUT of `app/views/jobs/new.html.erb` and into the `_form.html.erb` file: -MARKDOWN - -source_code :erb, -<<-ERB - <%= form_for @job do |f| %> -
      - <%= f.label :title %> - <%= f.text_field :title %> -
      -
      - <%= f.label :description %> - <%= f.text_area :description, size: '60x6' %> -
      -
      - <%= f.submit %> -
      - <% end %> -ERB - -source_code_with_message "Now, in `app/views/jobs/new.html.erb`, add the following line:", :erb, -<<-ERB - <%= render "form" %> -ERB - -message <<-MARKDOWN - Add a job posting, just to make sure that the form is working as expected. - - # Use the power of partials -MARKDOWN - -source_code_with_message "Now that we have a form partial, we can reuse it! In `app/views/jobs/edit.html.erb`, we can add the same line under the header:", :erb, -<<-ERB -<%= render "form" %> -ERB - -message "Refresh the page." - -error_box "First argument in form cannot contain nil or be empty" -source_code_with_message "It looks like we don't have a job ... because we haven't gotten our job out of the database! Let's go to the jobs_controller and fix that. In jobs_controller.rb, add the following", :ruby, -<<-RUBY - def edit - @job = Job.find(params[:id]) - end -RUBY - -discussion_box "Params", "What is `Job.find(params[:id])` doing? What is `params` again?" - -message <<-MARKDOWN - # Actually Update The Job - - So now the form works. Let's try to update that job posting. Change something about the job posting, and submit the form. -MARKDOWN - -error_box "The action 'update' could not be found for JobsController" - -source_code_with_message "So it looks like the form is finding the right route, but the method is missing from the controller. Let's add the update method to the file jobs_controller.rb", :ruby, -<<-RUBY - def update - end -RUBY - -source_code_with_message "Try it again, and ... template missing error! Similarly to create, we don't have a template to render for update. So let's just send them back to the jobs listing.", :ruby, -<<-RUBY - def update - redirect_to jobs_path - end -RUBY - -message <<-MARKDOWN - Try again, and ... no errors! But we're still not seeing our changes. -MARKDOWN - -discussion_box "What is this controller method missing?", <<-MARKDOWN - Who knows what we're missing? - - Take a look at the `create` method on the jobs controller and compare what we're doing in each. - - See if you can figure it out as a class. - - (Spoilers below, so don't keep scrolling!) -MARKDOWN - -message <<-MARKDOWN - * here - * is - * some - * strategic - * white - * space - * so - * the - * answer - * isn't - * immediately - * visible! -MARKDOWN - -source_code_with_message "Here's what the update method should actually look like:", :ruby, -<<-RUBY - def update - @job = Job.find(params[:id]) - @job.update_attributes(job_params) - redirect_to jobs_path - end -RUBY - -message <<-MARKDOWN - We needed to save our changes to the database so they can actually persist! If you didn't have the discussion before and work out the answer, go through this method line-by-line explaining precisely what the code is doing. - - ### Add a Link - - Our users probably aren't going to know they can hit `/jobs/:id/edit` to visit the edit form, so let's add a link to it on the jobs index so we end up with this (we're just adding the line with the `
      ` header in it ... don't copy and paste the whole thing!): -MARKDOWN - -source_code :erb, -<<-ERB - <% @jobs.each do |job| %> -

      <%= job.title %>

      -

      <%= job.description %>

      -
      <%= link_to "Edit Posting", edit_job_path(job)%>
      - <% end %> -ERB - -next_step "delete_job_listings" diff --git a/sites/en/learn-to-code/argv.md b/sites/en/learn-to-code/argv.md deleted file mode 100644 index 5d0411103..000000000 --- a/sites/en/learn-to-code/argv.md +++ /dev/null @@ -1,54 +0,0 @@ - - -# ARGV - -There is a magic array named `ARGV`. - -It contains the *command line arguments* to the program. - -If the user types: - - ruby hello.rb Alice Bob - -then ARGV contains: - - ["Alice", "Bob"] - -# Why ARGV? - -ARGV is a historical name. It means "Argument Vector" and has been around since the early 1970s. - -# Command-Line Hello - -Change `hello.rb` to contain: - - puts "Hello, " + ARGV[0] - -and run it a few times, e.g. - - ruby hello.rb Alice - -# LAB: Hello, Everyone! - -Change `hello.rb` to say hello to *every one* of its command line arguments. - -For instance: - - ruby hello.rb Alice Bob Charlie - Hello, Alice! - Hello, Bob! - Hello, Charlie! - -# LAB: Add - -Write a program named `add.rb` that adds all of its command line arguments together. - -e.g. - - ruby add.rb 1 2 3 - 6 - -Do you remember how to convert a string to an integer? - - - diff --git a/sites/en/learn-to-code/arrays.md b/sites/en/learn-to-code/arrays.md deleted file mode 100644 index 5dbc0eefc..000000000 --- a/sites/en/learn-to-code/arrays.md +++ /dev/null @@ -1,126 +0,0 @@ - - -# Arrays - -* An ARRAY is a CONTAINER - * an object that contains other objects -* It's a list of objects - -# What makes an array an array - -* You can put any objects inside it -* In any order -* They stay in order -* Duplicates are fine - -# Creating an array - - ["apple", "banana", "cherry"] - -# Array Indexes - -* Every slot in the array has a serial number -* You can retrieve any item in an array by its INDEX -* An index is a number from 0 to infinity - * actually to the size of the array - -# Array Indexes Exercise - -Try this in IRB: - - fruits = ["apple", "banana", "cherry"] - fruits[1] - -Did you get the result you expected? - -Why or why not? - -# Start At Zero - -When counting, - -humans start at one, - -but **computers start at zero**. - -So the first item in an array is number zero, not number one. - -# The End - -Try this: - - fruits[99] - -Did you get the result you expected? - -Why or why not? - -# Array Methods - - fruits.last - fruits.first - fruits.reverse - fruits.shuffle - -# Turning an array into a string - - fruits.join - fruits.join(" and ") - -Note that `to_s` doesn't work right on arrays: - - fruits.to_s - puts fruits.to_s - -# Looping through an array - - fruits.each do |fruit| - puts fruit - end - -* `each` is like `while` for arrays -* `fruits.each do` means "for each item inside this array, do this" -* `|fruit|` means "put the current item into a variable named `fruit`" -* `puts fruit` means "print out the value of this variable" -* `end` means "we're done with the loop now" :-) - -# Lab: reverse fruit - -Given this array: - - fruits = ["apple", "banana", "cherry"] - -write a program that prints: - - yrrehc - ananab - elppa - -# Setting items in an array - -The `[]` operator works for assignment as well. - - fruits[0] = "Apricot" - fruits[1] = "Blueberry" - - puts fruits.first - -# Checking an array - -The `include?` method checks if an object is inside an array or not. - - fruits.include? "apple" - true - - fruits.include? "pizza" - false - -# LAB: enemies list refactoring - -I'd like you to **refactor** your old `hello.rb` program to use the `include?` method to check if someone is your enemy. - -# TODO: more array labs - - - - diff --git a/sites/en/learn-to-code/computers.md b/sites/en/learn-to-code/computers.md deleted file mode 100644 index b8f90cb4a..000000000 --- a/sites/en/learn-to-code/computers.md +++ /dev/null @@ -1,106 +0,0 @@ - - -# What is a computer? - -* A smart box - * desktop - * laptop - * cell phone - * smart phone - -# The Universal Machine - -* A computer can do anything - * (at least on the inside) -* This can be intimidating! -* But the basic rules are simple - -# The Terminal - -* the *TERMINAL* is a window into which you can talk directly to your computer -![Shall we play a game?](img/wargames-terminal.jpg) - -# In The Beginning Was The Command Line - -* the *TERMINAL* is a window into which you can talk directly to your computer -* aka *console* or *command line* or *command prompt* or *shell* or *prompt* - * contrast *CLI* (Command Line Interface) to *GUI* (Graphical User Interface) - -* ["In The Beginning Was The Command Line"](http://www.cryptonomicon.com/beginning.html) is an essay by Neil Stephenson describing the history of computers in an enjoyable and clever way - -# irb - the Interactive Ruby Browser - -## Exercise: Calculator - -* open a terminal -* type `irb` -* press the `return` key (also called `enter`) -* see the `>` prompt -* type `1 + 1` -* press the `return` key again -* see the `2` -* yay, a $1000 calculator! - -* Bonus: what other math can you do? - -* From now on, whenever you see text in the `code font`, try typing it into irb and see what happens! - -# Computer Anatomy: Hardware - -* CPU ("the brain") -* Memory -* Input/Output - * keyboard, mouse, touch screen, monitor - -# Computer Anatomy: Software - -* Operating System -* Libraries -* Applications -* Languages - -Every piece of software on your computer is a PROGRAM. - -# A Program Is Like A Recipe - -* a recipe is a collection of *ingredients* and *instructions* - -![Grandma's Cookie Recipe](img/cookie-recipe.gif) - -* a program is a collection of *data* and *code* - -When you are writing code, you are not baking cookies, you are writing a recipe for how to make cookies. - -(recipe from http://www.popcornpottery.com/rec.html) - -# Languages - -* every program is written in a LANGUAGE - * like Java or Python or C or Fortran - * even HTML and CSS and SQL are languages - * every computer language has a silly name -* different languages are useful in different areas, but there is a lot of overlap -* today we will learn the RUBY programming language - -# Ruby - -* Ruby was invented in the 1990s by a very nice Japanese man named Yukihiro Matsumoto (nicknamed Matz) -* The motto of Ruby is MINASWAN: - -> Matz is nice, and so we are nice. - -# Ruby is fun - -* Ruby was [designed to be fun](http://blog.crowdint.com/2013/06/11/matz-keynote-at-ruby-kaigi-2013.html) to write code in, while also being powerful and well-rounded. -* *Ruby is poetry* - * especially compared to other languages - -# Errors Are Awesome - -* Don't be afraid of errors -* Your computer is trying to help you fix your program - * It's just *really* bad at communicating -* It's not all gibberish -* Try to read it -- really try! -- and pull out the pearls from the pig slop - - diff --git a/sites/en/learn-to-code/extra.md b/sites/en/learn-to-code/extra.md deleted file mode 100644 index 0b38313a0..000000000 --- a/sites/en/learn-to-code/extra.md +++ /dev/null @@ -1,17 +0,0 @@ - - -# Extra Fun Ruby Stuff - -We've gone over the basics, but Ruby has lots of other language features. Here's a quick overview, with links to more info about them. - -[Iterators](http://codelikethis.com/lessons/ruby_blocks/iterators) are special loops that act on all the items in a collection. - -[Blocks](http://codelikethis.com/lessons/ruby_blocks) are like a cross between functions and methods. They allow Ruby to express many powerful algorithms in a compact writing style. - -[Symbols](http://codelikethis.com/lessons/ruby_basics/symbols) are like strings that start with a colon, and they're used all over the place. - -[Chaining](http://codelikethis.com/lessons/ruby_basics/chaining) is a compact way to express a chain of events. Properly executed, chaining turns Ruby from prose into poetry. - -[Methods](http://codelikethis.com/lessons/ruby_objects/objects#behavior) and [Classes](http://codelikethis.com/lessons/ruby_objects/classes) are the heart of [Object-Oriented Programming](https://en.wikipedia.org/wiki/Object-oriented_programming). They - -## ...and [lots more](http://codelikethis.com/lessons)... diff --git a/sites/en/learn-to-code/functions.md b/sites/en/learn-to-code/functions.md deleted file mode 100644 index 198a2a503..000000000 --- a/sites/en/learn-to-code/functions.md +++ /dev/null @@ -1,58 +0,0 @@ - - -# Functions - -* just like a VARIABLE is a name for a chunk of data -* a FUNCTION is a name for a chunk of code -* if you have some code you want to run again and again - * or just run once, but keep it organized - -# For example - -Here's a silly function: - - def add x, y - x + y - end - -* `def` means "define a function" -* `add` is the *name* of the function -* `x, y` are the *parameters* of the function -* `x + y` is the *body* of the function - * also the *return value* - -Lab: write a `multiply` method and use it to multiply 123 * 456 - -# Rant!!! - - def rant s - s.upcase.gsub(" ", "") + "!!!" - end - - puts rant "i like pizza" - -Lab: use "rant" to rant about something really important!!! - -# Capitalize Just The First Character - - def initial_cap s - s[0] + s[1,s.length] - end - - puts initial_cap("smith") - puts initial_cap("deniro") - -Lab: capitalize a few things - -# Titleize - - def titleize string - string.split(' ').map(&:capitalize).join(' ') - end - -* The funny `&:` means "send this message" -* `map(&:capitalize)` means "send the message `capitalize` to every item in the array" - -# LAB: titleize your favorite movies - - diff --git a/sites/en/learn-to-code/hashes.md b/sites/en/learn-to-code/hashes.md deleted file mode 100644 index 14c753f44..000000000 --- a/sites/en/learn-to-code/hashes.md +++ /dev/null @@ -1,14 +0,0 @@ - - -# Hashes - -* `Hash` is a built-in type - * aka Map, Dictionary, Associative Array -* Like an array where the index can be *anything*, not just a number - -# TODO: - -* examples -* labs - - diff --git a/sites/en/learn-to-code/img/cookie-recipe.gif b/sites/en/learn-to-code/img/cookie-recipe.gif deleted file mode 100644 index 1a593848c..000000000 Binary files a/sites/en/learn-to-code/img/cookie-recipe.gif and /dev/null differ diff --git a/sites/en/learn-to-code/img/dot.jpg b/sites/en/learn-to-code/img/dot.jpg deleted file mode 100644 index e756c29fb..000000000 Binary files a/sites/en/learn-to-code/img/dot.jpg and /dev/null differ diff --git a/sites/en/learn-to-code/img/fruit-banana-snack-banana.svg b/sites/en/learn-to-code/img/fruit-banana-snack-banana.svg deleted file mode 100644 index 061d03e1f..000000000 --- a/sites/en/learn-to-code/img/fruit-banana-snack-banana.svg +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - "banana" - - - - fruit - - - - "BANANA" - - - - snack - - diff --git a/sites/en/learn-to-code/img/one-infinite-loop.jpg b/sites/en/learn-to-code/img/one-infinite-loop.jpg deleted file mode 100644 index e635a0614..000000000 Binary files a/sites/en/learn-to-code/img/one-infinite-loop.jpg and /dev/null differ diff --git a/sites/en/learn-to-code/img/snack-apple.svg b/sites/en/learn-to-code/img/snack-apple.svg deleted file mode 100644 index b64c4eaf9..000000000 --- a/sites/en/learn-to-code/img/snack-apple.svg +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - "Apple" - - - - snack - snack - - - diff --git a/sites/en/learn-to-code/img/snack-fruit.svg b/sites/en/learn-to-code/img/snack-fruit.svg deleted file mode 100644 index 788f7d147..000000000 --- a/sites/en/learn-to-code/img/snack-fruit.svg +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - "Apple" - - - - snack - snack - - - fruit - - - - diff --git a/sites/en/learn-to-code/img/spoon.jpg b/sites/en/learn-to-code/img/spoon.jpg deleted file mode 100644 index a75005414..000000000 Binary files a/sites/en/learn-to-code/img/spoon.jpg and /dev/null differ diff --git a/sites/en/learn-to-code/img/truthiness.png b/sites/en/learn-to-code/img/truthiness.png deleted file mode 100644 index ffabdecae..000000000 Binary files a/sites/en/learn-to-code/img/truthiness.png and /dev/null differ diff --git a/sites/en/learn-to-code/img/warehouse.jpg b/sites/en/learn-to-code/img/warehouse.jpg deleted file mode 100644 index b11e1f5f3..000000000 Binary files a/sites/en/learn-to-code/img/warehouse.jpg and /dev/null differ diff --git a/sites/en/learn-to-code/img/wargames-terminal.jpg b/sites/en/learn-to-code/img/wargames-terminal.jpg deleted file mode 100644 index f82f86510..000000000 Binary files a/sites/en/learn-to-code/img/wargames-terminal.jpg and /dev/null differ diff --git a/sites/en/learn-to-code/input_and_output.md b/sites/en/learn-to-code/input_and_output.md deleted file mode 100644 index 27e8c85bd..000000000 --- a/sites/en/learn-to-code/input_and_output.md +++ /dev/null @@ -1,114 +0,0 @@ - - -# Input and Output - -* Computers have many senses -- keyboard, mouse, network card, digital camera, etc. Collectively, these are called INPUT. - -* Computers can also express themselves in many ways -- text, graphics, sound, network, printers, etc. Collectively, these are called OUTPUT. - -* Input and Output together are called **I/O**. - -# Terminal I/O - -* In Ruby, - * `puts` means "print a line to the terminal" - * `gets` means "read a line from the terminal" - -* `gets` reads all the characters from the keyboard and puts them into a new string, until you press RETURN - -# LAB: Hello, friend! - -1. Open `hello.rb` in your text editor -2. Change it to contain the following code: - - puts "What is your name?" - name = gets - puts "Hello, " + name + "!" - -3. Save the file and switch back to the terminal -4. Run the program using `ruby hello.rb` -5. Type in your name and press the RETURN (or ENTER) key - -What happens? Is this what you expected? - -# Yikes! - -* Uh-oh! We've got trouble... what is that exclamation point doing way down there? - -* The first thing to do is DON'T PANIC! -* You are *totally* going to figure this out. -* And even if you don't, you haven't actually broken anything. -* In fact, it's really hard to break a computer, so just stay calm. - -# Breathe - -* In through the nose... -* Out through the mouth... -* In through the nose... -* Ahhhhhhhh. - -# Let's fix this - -* Have you figured out what the problem is? -* If not, I'll tell you on the next slide. -* Take a second and try to figure it out first. I'll wait. - -# The newline character - -* Here's a fun fact: -* In addition to letters, numbers, and punctuation, computers also store other keys inside strings -* Among these CONTROL CHARACTERS is the one that represents the RETURN KEY -* This character's name is NEWLINE -* Every time you use `gets`, Ruby reads *all* the characters, *including the newline*! - -# Strip it - -* Fortunately, there's an easy fix -* If you send the message `strip` to a string, it will remove all SPACES and NEWLINES from both ends - -# LAB: fixing Hello, Friend - -* Change the program to look like this: - - puts "What is your name?" - name = gets.strip - puts "Hello, " + name + "!" - -* Run it and make sure it works OK - -# LAB: Capitalization - -* What happens if you type your name in all lowercase? -* Make the program capitalize your name for you even if you forget. - -# LAB: Crazy Name - -* Now go crazy and make it do all sorts of silly things to your name! - -# LAB: Full Name - -* Write a program named `name.rb` that asks two things: - 1. Your first name - 2. Your last name -* Then it says hello to the user by her *full name*. -* Run the program by typing `ruby name.rb` on the command line. - -# CONGRATULATIONS! - -> You just wrote a program! - -You are now officially a coder. HIGH FIVE! - -# Lab: Name Length - -* Change `name.rb` so it also prints the number of characters in the user's name. -* For instance: - - What is your first name? - Alex - What is your last name? - Chaffee - Hello, Alex Chaffee! - Your name is 11 characters long. - - diff --git a/sites/en/learn-to-code/learn-to-code.md b/sites/en/learn-to-code/learn-to-code.md deleted file mode 100644 index 5f079016a..000000000 --- a/sites/en/learn-to-code/learn-to-code.md +++ /dev/null @@ -1,79 +0,0 @@ - - -# Learn To Code - -You may have never programmed before. Now you will. - -# What is coding? - -* coding = programming - -* ...thoughts? - -# What is coding NOT? - -* coding is not mathematical - * some logic - * mostly just long todo lists -* coding is not lonely - * most coding happens in a team - * pair programming is awesome - - - -# What is coding? - -* coding is fun! -* coding is frustrating! -* coding is creative! -* coding is communication - * between you and a computer - * between you and other coders - -# What will we learn today? - -In this class, you will utilize Ruby to learn: - -* The command line and why we use it -* Learn about Strings, Arrays, Variables, Objects, Loops, Files -* Object concepts like Methods - -* How to run your Ruby code interactively (irb) or from a file -* Make a very simple website run on your own computer - -Follow along at http://docs.railsbridge.org/learn-to-code - -# Go at your own pace - -* we will **definitely not** get through all the materials today - -# What if I know some of that already? - -* Pair up and fill in each other's gaps -* Promote yourself to TA - -## And if you and your pair finish early... - -* Let us know! -* Start working on Ruby For Programmers lessons - * http://testfirst.org - * http://codelikethis.com/lessons -* Build a Rails website - * http://docs.railsbridge.org/ - -# Technical requirements - -* WIFI - * Ask for SSID and password -* a live Ruby installation - * e.g. http://railsinstaller.org -- click on the *BIG GREEN BUTTON* - * Ruby version 2.1 preferred, but 1.9 is fine too - * run `ruby -v` to check -* a text editor - * e.g. Sublime Text 2 - * http://www.sublimetext.com/2 - -* If you do not have both of these things, RAISE YOUR HAND - * visit http://installfest.railsbridge.org for more instructions - - diff --git a/sites/en/learn-to-code/logic.md b/sites/en/learn-to-code/logic.md deleted file mode 100644 index 16769744e..000000000 --- a/sites/en/learn-to-code/logic.md +++ /dev/null @@ -1,111 +0,0 @@ - - -# Truthiness - -Computers have a very strict idea of when things are *true* and *false*. - -![Truthiness](img/truthiness.png) - -(Unlike Stephen Colbert...) - -# True or False? - -Try the following in irb: - -* `1 < 2` -* `2 + 2 < 4` -* `2 + 2 <= 4` -* `2.even?` -* `4.odd?` -* `"apple".empty?` -* `"".empty?` - -# Conditions - -The magic word `if` is called a CONDITIONAL. - - if age < 18 then - puts "Sorry, adults only." - end - -# One-Line Condition - -Ruby has a compact way of putting an entire `if` expression on one line: - - puts "Sorry, adults only." if age < 18 - -Note that: - -* the action comes *first* in a one-line condition -* this sounds kind of natural - * "Go to bed if you're sleepy." - -# if... then... else... end - -The magic word `else` allows BRANCHING. - - if age >= 18 then - puts "allowed" - else - puts "denied" - end - -Like a fork in the road, the program chooses one path or the other. - -(In Ruby, `then` is optional, so we usually leave it off, but if it makes your code clearer, go ahead and use it.) - -# 2 + 2 = 4 - -Sadly, this expression: - - 2 + 2 = 4 - -causes a `SyntaxError`. You need to do - - 2 + 2 == 4 - -instead. Why? - -# The Tragedy of the Equal Sign - -* a single equal sign means ASSIGNMENT - * `name = "Alice"` -- "assign the variable 'name' to the value 'Alice'" -* two equal signs means COMPARISON - * `name == "Alice"` -- "does the variable 'name' contain the string 'Alice'?" - -> This is confusing, and you should feel confused. - -* (it's all FORTRAN's fault) - -# LAB: Good Friend, Bad Friend - -* Your `hello.rb` program should currently look something like this: - - puts "What is your name?" - name = gets.strip - puts "Hello, " + name + "!" - -* Now change `hello.rb` so that it doesn't always say hello! - * If the user's name is "Darth" then say "Go away!" - -# Conjunction Junction - -* You can make more complicated logical expressions using conjunctions like `and`, `or`, `not`: - * `X and Y` means "are both X and Y true?" - * `X or Y` means "is either X or Y (or both) true?" - * `not X` means "is X false?" (think about it) - -* For example: - - if age >= 18 or parent.gave_permission? then - puts "allowed" - else - puts "denied" - end - -# LAB: Enemies List - -* Change `hello.rb` so that it says "Go away!" if the user's name is any one of a number of evil names -* For instance, Voldemort, Satan, Lex Luthor... - - diff --git a/sites/en/learn-to-code/loops.md b/sites/en/learn-to-code/loops.md deleted file mode 100644 index 194c8b707..000000000 --- a/sites/en/learn-to-code/loops.md +++ /dev/null @@ -1,232 +0,0 @@ - - -# Loops - -Computers are like robots. They are good at doing things over and over and over and over again. - -A LOOP is when we ask a program to do something many times. - -# loop - -If you want something to keep going forever, use a special loop called `loop`. - - loop do - puts "Hello" - end - -To stop it, hold down the CONTROL key and press the C key. - -**Note well!** The lines between `do` and `end` are INDENTED. Indentation is very important to you and other humans. It lets our eyes follow the patterns and helps us quickly see what parts of the program go with each other. - -# One Infinite Loop - -![One Infinite Loop](img/one-infinite-loop.jpg) - -*Fun Fact:* The address of Apple HQ is - - 1 Infinite Loop - Cupertino, CA 95014 - -*Image from the Wikimedia Commons, licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license. Attribution: Joe Ravi* - -# LAB: Infinite Hello - -Let's change `hello.rb` so that it keeps saying hello over and over again. - - loop do - puts "What is your name?" - name = gets.strip - puts "Hello, " + name + "!" - end - -# LAB: Infinite Food - -Write a program called `food.rb` that - -1. asks the user for a food -- say, "pizza" -2. prints "Yum, I love pizza!" -3. asks again, and prints again, forever and ever - -Remember, CONTROL-C means "Stop everything!!!" - -# Who wants to loop forever? - -Next, we will change your `food.rb` program so that if the user types "return" -- meaning the string is empty -- then the program exits. - -Please try this yourself! But it's kind of tricky, so on the next slide I'll show you one solution. - -# Exiting a Loop with break - -The magic word `break` stops a loop immediately. - - loop do - puts "What is your name?" - name = gets.strip - break if name.empty? - puts "Hello, " + name + "!" - end - -The magic word `break` means "stop the current loop". It's less dangerous -- but still kind of weird, since it's not always clear which loop you mean. - -# LAB: Exiting a Loop - -Change your `food.rb` program so that if the user types "return" -- meaning the string is empty -- then the program exits. - -# LAB: Good Food, Bad Food - -* Change `food.rb` so that it doesn't love every food. -* If it's a food you like (let's say, pizza), make it print "Yum! I love pizza." -* If it's a food you like (let's say, cabbage), make it print "Yuck! I hate cabbage." - -# times - -Another loop in Ruby is called `times`, and it's a message you can send to a number. - -Try this in IRB: - - 3.times do - puts "Hip! Hip! Hooray!" - end - -Let's unpack this: - -* `3.times do` means what it sounds like: "do this three times" -* `end` means this is the end of what I want you to do -* and of course, `puts` means "show this on the terminal" - -# Counting in a loop - -Remember this poem? - - 1 potato - 2 potato - 3 potato - 4 - 5 potato - 6 potato - 7 potato - More - -We're going to examine a few different ways to code this. - -# `times` with a counter - -Try this: - - 4.times do |count| - puts count.to_s + " potato" - end - -`|count|` means - -> "the `count` variable points to the current value of the counter" - -# `times` output - - 0 potato - 1 potato - 2 potato - 3 potato - 4 - -Whoops! What's wrong? - -# `times` with a counter -- fixed - - 4.times do |count| - puts (count+1).to_s + " potato" - end - -# `loop` with a counter - - count = 1 - loop do - puts count.to_s + " potato" - count = count + 1 - end - -Whoops! Hit Control-C and join me on the next slide... - -# `loop` with a counter -- fixed - - count = 1 - loop do - puts count.to_s + " potato" - count = count + 1 - break if count > 4 - end - -# `while` - -The magic word `while` combines `loop` and `break`. - - count = 1 - while count <= 4 - puts count.to_s + " potato" - count = count + 1 - end - -* The `while` statement keeps checking the expression - - * if it's `true` then it loops back - * if it's `false` then it stops looping and goes on to the rest of the program - -This is fairly complicated, so let's stop here and make sure to understand everything that's happening in this little program. - -# `while` breakdown (pt.1) - - count = 1 - -creates a *variable* named `count` and sets its value to `1`. - - while count <= 4 - -starts a loop and immediately compares `count` to `4`. - -`1` is less than `4`, so the expression is `true`, so we continue with the loop. - -# `while` breakdown (pt.2) - - puts count.to_s + " potato" - -prints the current value of count (and the word "potato"). - - count = count + 1 - -*increments* the `count` variable... it was `1`, so now it's `2` - - end - -goes *back to the `while` line* and checks again - -# `while` breakdown (pt.2) - - while count <= 4 - -compares `count` to `4`. - -`2` is less than `4`, so the expression is `true`, so we continue with the loop. - -Eventually, `count` becomes `5`, and the `while` expression is `false`, and so we stop looping and go on. - -# LAB: One Potato - -Write a program called `potato.rb` that prints the entire potato poem, accurately. - -# Lab: Adder - -Write a program named `adder.rb` that keeps a *running total*. - -For example: - - ruby adder.rb - 1 - Total: 1 - 2 - Total: 3 - 4 - Total: 7 - -5 - Total: 2 - - diff --git a/sites/en/learn-to-code/methods.md b/sites/en/learn-to-code/methods.md deleted file mode 100644 index 0034323bf..000000000 --- a/sites/en/learn-to-code/methods.md +++ /dev/null @@ -1,7 +0,0 @@ -# Methods vs. Functions - -* a FUNCTION is a named chunk of code with PARAMETERS and a RETURN VALUE -* a METHOD is a function that is *attached* to a specific object - * it has privileged access to that object's data -* in Ruby everything's an object, so the terms are mostly interchangeable - diff --git a/sites/en/learn-to-code/next_steps.md b/sites/en/learn-to-code/next_steps.md deleted file mode 100644 index dae282ded..000000000 --- a/sites/en/learn-to-code/next_steps.md +++ /dev/null @@ -1,19 +0,0 @@ -# Next Steps - -* [Try Ruby](http://tryruby.org/) at -* Sign up for Code School at - * Code School's "Ruby Bits" class -* Alex's online courses at [Code Like This](http://codelikethis.com) and [TestFirst.org](http://testfirst.org) -* Chris Pine's book "[Learn to Program](http://www.amazon.com/gp/product/1934356360/ref=as_li_ss_il?ie=UTF8&camp=1789&creative=390957&creativeASIN=1934356360&linkCode=as2&tag=alexchaffeeco-20)" book -* Attend or host a [RailsBridge Workshop](http://railsbridge.org) - -* _why's guide to Ruby (http://mislav.uniqpath.com/poignant-guide/) - -* -* - -# Thanks - -* to all the TAs -* to all the students! - diff --git a/sites/en/learn-to-code/nil.md b/sites/en/learn-to-code/nil.md deleted file mode 100644 index d256fa794..000000000 --- a/sites/en/learn-to-code/nil.md +++ /dev/null @@ -1,40 +0,0 @@ - - -# Nil - -*nil* is a magic object - -# There Is No Spoon - -![](img/spoon.jpg) - -*nil* is the object that means "there is no object" - -# Experiment - - fruit = "apple" - fruit = nil - fruit.reverse - -*Read the error!* - -# Errors are good - -They tell you - -* you made a mistake -* what that mistake was -* (sometimes) how to fix it - -Interpret this error: - - fruit.reverse - NoMethodError: undefined method `reverse' for nil:NilClass - -# Fail Fast, Fail Often - -* Ruby has a "fail fast" philosophy -* Is this a good idea? -* Why or why not? - - diff --git a/sites/en/learn-to-code/numbers.md b/sites/en/learn-to-code/numbers.md deleted file mode 100644 index 9018485af..000000000 --- a/sites/en/learn-to-code/numbers.md +++ /dev/null @@ -1,156 +0,0 @@ - - -# Numbers - -The following operations work on numbers: - - * + -- addition - * - -- subtraction - * * -- multiplication - * / -- division - * % -- modulus - * ** -- exponentiation - -# LAB: Playing With Numbers - -Answer the following questions using irb: - -* How many seconds are in an hour? -* How many minutes are in a week? -* How many seconds old are you? -* How many years old is someone who is 1 billion seconds old? - -# Order of operations - -Q: What is 1 plus 2 times 3? - -# Order of operations - -Q: What is 1 plus 2 times 3? - -A: *It depends!* - - * `(1 + 2) * 3` is 9 - * `1 + (2 * 3)` is 7 - -# Parentheses Are Free - -When in doubt, use parentheses! - -# Strings vs. Numbers - -Hmmm.... - - 1 + 2 - "1" + "2" - "1 + 2" - -# Strings plus Numbers - -Hmmm again... - - "1" + 2 - -Uh-oh! - - TypeError: can't convert Fixnum into String - -The problem is that Strings and Numbers are different TYPES, aka different CLASSES. - -Don't panic! The solution is easy. - -# Type Conversion - -Numbers know a message that converts them into strings. `to_s` means "to string". - - "1" + 2.to_s - -Likewise, strings know a message that converts them into numbers. - - 1 + "2".to_i - -`to_i` means "to integer". - -Try this in irb! - -# Advanced Number Theory (optional) - -# WTFixnum? - -The error said `can't convert Fixnum into String`. - -Q: What is a Fixnum? - -A: It's one type of number. - -# Math is hard - -There are many types of numbers! - -Each is useful in different situations. - -Without getting into too much detail, the two main number types in Ruby are: - -* `Fixnum` - for *integers* like 12 or -1023 -* `Float` - for *decimals* like 3.14 - -(Other number types include Complex, Rational, and Bignum.) - -# Number to Number - -You can convert from one type of number to another by sending a message: - -* `to_i` turns a Float into a Fixnum -* `to_f` turns a Fixnum into a Float - -Try this: - - 3.to_f - 3.14.to_i - -# String to Number - -`to_f` and `to_i` also work on Strings: - - "3.14".to_f - "3.14".to_i - -and `to_s` works on numbers: - - 3.14.to_s - -# Arithmetic - -Try this in irb: - - 1 + 2 - 3 - 4 - 5 * 6 - 7 / 8 - -Whoa! What just happened? - -# Integer Arithmetic - -7 and 8 are *Integers* - -so the result is an Integer - -7/8 is somewhere between 0 and 1 - -but there is no integer between 0 and 1 - -so the computer has to *round down* to 0 - -# Floating Point Arithmetic - - 7.0/8.0 - -7.0 and 8.0 are *Floats* - -so the result is a Float - -and `0.875` can fit in a float - -# Okay, that's enough math! - diff --git a/sites/en/learn-to-code/objects.md b/sites/en/learn-to-code/objects.md deleted file mode 100644 index 2075079cf..000000000 --- a/sites/en/learn-to-code/objects.md +++ /dev/null @@ -1,81 +0,0 @@ - - -# Objects - -An OBJECT is a location in computer memory where you can store DATA (aka VALUES). - -There are many kinds of objects, including String, Number, Array, Hash, Time, ... - -(The different kinds of objects are called CLASSES or TYPES. Some day soon you will create your own classes but for now, we will use the built-in ones.) - -# Numbers - -A NUMBER is what it sounds like. - - 10 - -12 - 3.14 - -# Strings - -A STRING is an object that's a collection of characters, like a word or a sentence. - - "apple" - "banana" - "Cherry Pie" - -# Messages and Operators - -An object responds to MESSAGES. You send it messages using OPERATORS. - -The most powerful operator is DOT. - -On screen she looks like this... - - . - -# Dot up close - -...but here's what she looks like up close: - -![picture of Dot the Operator](img/dot.jpg) - -# Dot's job - -Dot can send any message she likes, by name, to any object. - - "apple".upcase - -The `upcase` message turns `"apple"` into `"APPLE"`. - -# Other Operators - -There are other operators, like PLUS (`+`) and TIMES (`*`), but they only send one message each. - -And remember, Dot is more powerful than any other operator! - - 2 + 7 - -is the same as - - 2.+ 7 - -Both send the message `+` to the object `2`. - -# Return Values - -Every time an object receives a message, it returns a response. - -The response is also called the VALUE or the RETURN VALUE. - -You can think of it as the answer to a question. - - 2 + 2 # Question: What is 2 + 2? - 4 # Answer: 4 - - "apple".upcase - # Q: What is the upcase of the string "apple"? - - "APPLE" - # A: the string "APPLE" - diff --git a/sites/en/learn-to-code/sinatra.md b/sites/en/learn-to-code/sinatra.md deleted file mode 100644 index d7c672bdb..000000000 --- a/sites/en/learn-to-code/sinatra.md +++ /dev/null @@ -1,67 +0,0 @@ - - -# Sinatra - -Sinatra is a Web Application Framework. It includes a Web Server and lets you write code to show when people request web pages. - -# Hi, Sinatra - -1. install Sinatra by running `gem install sinatra` on the command line - -2. create a file called `hi.rb` containing this: - - require 'sinatra' - - get '/hi' do - "Hi!" - end - -3. run `ruby hi.rb` - -Now open a Web Browser (like Firefox or Chrome or Safari or Internet Explorer) and enter the following URL into the address bar: - - http://localhost:4567/hi - -# Congratulations - -You just wrote a web server. - -No, really. - -# Hello, Whoever - -Change `hi.rb` to look like this: - - require 'sinatra' - - get '/hi/:who' do - "Hi " + params[:who] + "!" - end - -Now visit the following URL: - - http://localhost:4567/hi/alice - -# LAB: Yeller - -Make a route in your Sinatra application so that when someone requests this: - - /yell/ahoy - -they see this: - - AHOY!!! - -and when someone requests this: - - /yell/dinnertime - -they see this: - - DINNERTIME!!! - -# Detour: Deploying to Heroku - -* Railsbridge pages describing account setup & deploy steps - - diff --git a/sites/en/learn-to-code/strings.md b/sites/en/learn-to-code/strings.md deleted file mode 100644 index 3da28ac4e..000000000 --- a/sites/en/learn-to-code/strings.md +++ /dev/null @@ -1,45 +0,0 @@ - - -# String Messages - -A string understands lots of messages. Here are a few: - - "banana".upcase - "Cherry".downcase - "titanic".capitalize - "elderberry".reverse - "fig".length - "Fig Newton".swapcase - "".empty? - "syzygy".length - -Try all of these out in irb! - -# String Operators - -A string knows DOT, but also understands several other operators: - - "blue" + "berry" - "yum" * 10 - "elderberry"[8] - -`+` `*` and `[]` are pronounced PLUS, TIMES, and SUB - -Try these out in irb! - -# Combining Messages and Operators - -You can combine messages and operators at will. - - "fig".upcase.reverse - "grape".reverse * 10 + "!!!" - -Definitely try these out in irb! It's pretty fun. - -# LAB: Playing With Strings - -* What is the reverse of "stressed"? -* How many characters long is your name? -* What does your name look like, repeated 1000 times? -* What is the tenth character of "Matz is nice"? (Trick question!) - diff --git a/sites/en/learn-to-code/the_command_line.md b/sites/en/learn-to-code/the_command_line.md deleted file mode 100644 index c007e8d0b..000000000 --- a/sites/en/learn-to-code/the_command_line.md +++ /dev/null @@ -1,106 +0,0 @@ - - -# The Command Line - -* the TERMINAL is a window into which you can talk directly to your computer - * aka *console* or *command line* or *command prompt* -* very low level, based entirely on text and typing, not graphics and mousing -* when you type into the terminal, you are always issuing COMMANDS - * which is why it's called the Command Line - -# Opening the Terminal - -* to open your terminal: - * Mac OS: launch the "Terminal" application - * Windows with Railsinstaller: launch "Command Prompt with Ruby and Rails" -* **Important:** make your terminal *as tall as possible* - -# Directories - -* a DIRECTORY is a location on your hard disk - * also called a FOLDER -* directories can contain FILES -* directories can also contain other directories (called SUBDIRECTORIES) - -# The Current Directory - -* inside the Terminal, you are *always* inside a directory -* it is very important not to get lost! You must try to remember which directory you are in. -* If you forget, you can use a special command called `pwd` - -# Home Directory - -* when you open the Terminal you are in your HOME DIRECTORY -* usually you don't want to store files directly in here - -# Listing Directory Contents - -* when you type `ls` ("list") it shows the contents of the current directory - -# Making a directory - -* when you type `mkdir` ("make dir") it creates a new SUBDIRECTORY inside the current directory - - mkdir code - -# Changing directories - -* `cd` ("change dir") moves you into a different directory -* For example, `cd code` would move you into a directory named `code` -* If you ever get lost, type `cd` all on its own and press the return key. This will send you back to your home directory. - -# Basic Command Line Glossary - -* `pwd` ("print working dir") -- shows the name of the current directory -* `ls` ("list") -- shows the contents of the current directory -* `mkdir` ("make dir") -- creates a new SUBDIRECTORY inside the current directory -* `cd` ("change dir") -- move into a different directory -* `touch whatever.txt` -- creates an empty file named `whatever.txt` inside the current directory - -# LAB: make a subdirectory and then enter it - -1. open Terminal -2. make a new subdirectory using `mkdir code` -3. change into that directory using `cd code` -4. list its contents using `ls` (and note that it's empty) - -# Files - -* a file is a place on disk for storing stuff -* "stuff" here could be anything at all - * documents, pictures, sounds, applications... -* every file lives inside a directory - -# Text Editor - -* a text editor is a program that edits a text file -* a text editor is *like* a word processor -* but a text editor is **not** a word processor -* You probably have *Sublime Text* - * others include *TextMate*, *Notepad++* - * but **NOT** *TextEdit* or *Notepad* or *Microsoft Word* - -# Source File - -* source code is the essence of a program -* source files are text files that contain source code -* to RUN a program you type `ruby` and then the name of the source file - -* The Recipe Metaphor - * source file = recipe - * running = cooking - -# LAB: Hello, World - -1. Make sure you are in your `code` subdirectory using `pwd` -2. Create a file named `hello.rb` using `touch hello.rb` -3. Open `hello.rb` in your favorite text editor -4. Inside this file, put the following source code: - - puts "Hello, World!" - -5. Save the file -6. Go back to the terminal -7. Run this file using `ruby hello.rb` - -What happens? Is this what you expected? diff --git a/sites/en/learn-to-code/todo-learntocode.md b/sites/en/learn-to-code/todo-learntocode.md deleted file mode 100644 index 3a7bbb821..000000000 --- a/sites/en/learn-to-code/todo-learntocode.md +++ /dev/null @@ -1,18 +0,0 @@ -# todo: - -* diagram: memory (variables+objects) -* diagram: message passing - -* interpolation? -* more on arrays -* hashes -* more labs (for students who "get it" before the rest of the room and don't want to sit around bored (or help others)) -* functions -* more array labs -* methods -* classes -* File I/O -* testing -* symbols -* rand - diff --git a/sites/en/learn-to-code/variables.md b/sites/en/learn-to-code/variables.md deleted file mode 100644 index df7801947..000000000 --- a/sites/en/learn-to-code/variables.md +++ /dev/null @@ -1,114 +0,0 @@ - - -# Variables - -A VARIABLE is a NAME for an object. You give an object a name using the ASSIGNMENT operator (it looks like an equal sign). - - color = "blue" - fruit = "berry" - -Anywhere you can use an object, you can use a variable instead. - - color + fruit - fruit.upcase - -# The Warehouse Metaphor - -![Warehouse from Raiders of the Lost Ark](img/warehouse.jpg) - -Think of memory as a giant warehouse. - -# The Warehouse Metaphor Explained - -If memory is a giant warehouse... - -...and *objects* are **boxes** in that warehouse - -...then a *value* is the **contents** of a box - -...and a *variable* is a **label** you stick on the outside of the box - -# Variables are documentation - -Which is clearer, this: - - 60 * 60 * 24 - -or this: - - seconds_per_minute = 60 - minutes_per_hour = 60 - hours_per_day = 24 - seconds_per_day = seconds_per_minute * minutes_per_day * hours_per_day - -? - -# Lab: Play In IRB - -Let's spend a few minutes just playing around in IRB. Some things to try: - -* write a poem -* YELL THE POEM -* calculate 2 + 2 and more complicated things -* assign your best friend to a variable -* reverse your best friend's name -* get a new best friend and reverse her too - -# The Pointer Metaphor - - snack = "Apple" - -![snack-apple](img/snack-apple.svg) - -Think of a variable as **pointing** to an object. - -# Changing Variables - -You can assign and reassign variables at will. - - color = "blue" - fruit = "berry" - color + fruit - - color = "black" - color + fruit - -Changing a variable (using ASSIGNMENT) just changes the name of an object. It does *not* change the data inside the object. - -# Many pointers can point to the same thing - - fruit = "Apple" - snack = fruit - -![snack-fruit](img/snack-fruit.svg) - -After this both `snack` and `fruit`... - - * are *pointing* to the same *object* - * have the same *value* - -# Return values are new - -most messages return *new* values - - fruit = "banana" - snack = fruit.upcase - -![fruit-banana-snack-banana](img/fruit-banana-snack-banana.svg) - -`"banana"` and `"BANANA"` are two *different objects* in memory - -# Changing Values - -Most messages do not change the data inside the object. - - color.upcase - color - -But some messages do change the data! - - color.upcase! - color - -This can be dangerous so sometimes those messages end with a BANG (exclamation point). - diff --git a/sites/en/ruby/arrays.step b/sites/en/ruby/arrays.step deleted file mode 100644 index e7da6fde3..000000000 --- a/sites/en/ruby/arrays.step +++ /dev/null @@ -1,102 +0,0 @@ -goals do - goal "Make some arrays and do stuff with them" - goal "Retrieve data from arrays" -end - -step do - irb < 5 -15 >= 5 -10 == 12 - IRB -end - - -step do - message 'Notice we use a double equals sign to check if things are equal. It\'s a common mistake to use a single equals sign.' - irb <<-IRB -a = 'apple' -b = 'banana' -a == b -puts a + b -a = b -puts a + b -IRB - message "Surprise!" -end - -step do - message "For 'not equals', try these:" - irb <<-IRB -a = 'apple' -b = 'banana' -a != b -IRB - message "The exclamation point means **the opposite of**" - irb <<-IRB -!true -!false -!(a == b) -IRB - message "In `!(a == b)`, Ruby first evaluated `a == b`, then gave the opposite." - message "It also means **not true** . In conditionals, we'll see things like - - - if not sunny - puts \"Bring an umbrella!\" - -We can also say - - if sunny == false - puts \"Bring an umbrella!\" -but \"if not sunny\" is a little more natural sounding. It's also a little safer -- that double equals is easy to mistype as a single equals." -end - -step do - message "We can check more than one condition with `and` and `or` . `&&` and `||` (two pipes) is another notation for `and` and `or`." - message "We do something like this when we Google for 'microsoft and cambridge and not seattle'" -irb <<-IRB -# First let's define variables: -yes = true -no = false -# Now experiment. Boolean rule 1: AND means everything must be true. -# true and true are true -yes and yes -yes && yes -# true and false fail the test - AND means everything must be true -yes and no -no and yes -no and no -# Boolean rule 2: OR says at least one must be true. -yes or no -yes || no -yes or yes -IRB -end - - -step do - message 'By convention, methods in Ruby that return booleans end with a question mark.' - irb <<-IRB -'sandwich'.end_with?('h') -'sandwich'.end_with?('z') -[1,2,3].include?(2) -[1,2,3].include?(9) -'is my string'.empty? -''.empty? -'is this nil'.nil? -nil.nil? - IRB -end - - -explanation do - message "In code we ask a lot of questions. Boolean logic gives us tools to express the questions. " -end - -further_reading do - message "Some languages offer wiggle room about what evaluates to true or false. Ruby has very little. See [What's Truthy and Falsey in Ruby?](https://gist.github.com/jfarmer/2647362)" - message "[What's Truthy and Falsey in Ruby?](https://gist.github.com/jfarmer/2647362) has a more detailed walkthrough of booleans." - message "Ruby documentation for [true](http://www.ruby-doc.org/core-2.1.0/TrueClass.html) and [false]](http://www.ruby-doc.org/core-2.1.0/TrueClass.html)" -end - -next_step "conditionals" diff --git a/sites/en/ruby/classes.step b/sites/en/ruby/classes.step deleted file mode 100644 index 96d7b1e53..000000000 --- a/sites/en/ruby/classes.step +++ /dev/null @@ -1,43 +0,0 @@ -goals do - goal "Define a new object" - goal "Create an instance of your object" - goal "Call methods on your object" -end - -step do - message 'Create a new file called circle.rb' - type_in_file 'circle.rb', <<-'CONTENTS' -class Circle - def initialize(radius) - @radius = radius - end - - def area - Math::PI * (@radius ** 2) - end - - def perimeter - 2 * Math::PI * @radius - end -end - -print "What is the radius of your circle? > " -radius = gets.to_i - -a_circle = Circle.new(radius) -puts "Your circle has an area of #{a_circle.area}" -puts "Your circle has a perimeter of #{a_circle.perimeter}" - CONTENTS - console 'ruby circle.rb' - message 'When prompted, type in a radius for your circle.' -end - -explanation do - message "Functions by themselves aren't always enough to keep your program organized. **Object-oriented programming** was developed to keep related data (attributes) and functions that work on that data (methods) together." - message "In Ruby, a new object is defined with the **class** keyword, followed by the name of your object (typically CamelCased). You finish the object definition later on with an **end**." - message "Most objects define a special method, **initialize**, that saves the initial data your object is created with (here, a radius) and performs any other required set-up." - message "You create an **instance** of your object with the **new** method. Arguments passed in to **new** are sent to your **initialize** method." - message "Data is stored on your object using **instance variables** that start with an `@` sign. Instance variables behave like normal variables, but are only visible from inside a specific instance of your object. If you want the data to be externally accessible, you have to write more methods." -end - -next_step 'how_to_write_a_program' \ No newline at end of file diff --git a/sites/en/ruby/command_line.step b/sites/en/ruby/command_line.step deleted file mode 100755 index 63be32941..000000000 --- a/sites/en/ruby/command_line.step +++ /dev/null @@ -1,162 +0,0 @@ -message "

      The command line is a text-based way to interact with your computer.

      - -

      In Windows and OS X we use graphical user interfaces (GUIs). GUIs let you operate your computer with pictures -and a mouse. We start programs by clicking an icon, look through files and folders in Finder or File Explorer, -or pick a command from a dropdown menu.

      - -

      In the command line, we type commands to run programs and navigate through files and folders. We will need this to run - Ruby progams from files. This lesson covers the commands we need for the workshop.

      " - -message "It\'s helpful to keep Finder (OS X), File Explorer (Windows), or -Nautilus (Ubuntu) open during this topic. We\'ll make files and move between -directories. A graphical file browser will help you see the results more -clearly." - -goals do - goal "Learn about the command line" - goal "Make a new directory" - goal "Browse some directories on your computer" - goal "Learn the commands `pwd`, `mkdir`, `ls`, `cd` and `man`" -end - -step do - message 'Open up a command line application on your computer.' - message "**On Macs:** In Finder, start Applications > Utilities > Terminal, or find the Terminal application through Spotlight (click the magnifying glass in the top right of the screen and start typing 'Terminal')" - message '**On Windows:** open up **Git Shell** from your desktop or All Programs menu. Do not use Power Shell! It doesn\'t support the ssh command that we need.' - message '**On Linux:** press Ctrl + Alt + T or Find Terminal under the Accessories category of your applications menu.' - - message 'We will call this "the console" or "the command line", no matter what program you\'re using. ' - message 'Consoles will either start in your home directory, the way OS X and Windows open up in your Desktop, or in the directory you ended in during your last console session. We\'ll talk more about the home directory in a few steps.' - -end - -step do - message 'The first word you type in the terminal is always the name of a program. - Many programs are included in OS X and Windows, like `ls` and `pwd`. Others - are programs you installed, like `ruby`, `irb`, or `vagrant`.' - console 'ls' - message 'Hit **RETURN** or **ENTER** to run the command.' - message '`ls` stands for **list**, and lists the contents of the current directory.' - message 'You are in your home directory. You may see directories like - \'Documents\' or \'Desktop\'. If you start up Finder, File Explorer, or - Nautilus, you\'ll see the same files and folders listed.' -end - -step do - console "pwd" - message '`pwd` means "print working directory". It shows you what **directory** you\'re currently in. Directories are also often called **folders**.' - message '`pwd` can tell you where you are if you get lost somewhere in your computer.' - message 'What directory are you in right now?' -end - -step do - console 'cd workspace' - message '`cd` means **c**hange **d**irectory. You use `cd` when you want to move from the current directory into some other directory.' - console 'pwd' - message "Notice how it changed? The working directory ends in '/workspace'." -end - -step do - console 'mkdir railsbridge_ruby' - message '`mkdir` means **m**ake **d**irectory. You use `mkdir` when you want to create a new directory.' - console 'ls' - message 'Now the directory "railsbridge_ruby" shows up in the list.' - message 'The command line is just one way of manipulating the files on your computer. Try to find the new directory you created in Finder or Windows Explorer.' - message 'If you get an error saying the directory already exists, maybe someone did these steps on your computer before. Don\'t fret.' -end - -step do - message "Let\'s go back to your home directory." - console 'cd ~' - message "`~` is the tilde key. On US keyboards, it's on the top left, next the - 1 key, and you have to press `SHIFT` along with it. - - On the command line, the tilde means your **home directory**, a directory owned by the account currently logged in to the computer. - Your home directory might be something like `/home/sparklepants` (Linux) or `/Users/saucyfrank` (Mac). - -What\'s your home directory?" - console 'pwd' - message "Remember that you can always get back to your home with `cd ~`." -end - -step do - message 'The dash is a special shortcut that brings you back to your last - location, like an "undo" for `cd`.' - console 'cd -' - message 'What command shows you your current directory?' - console 'pwd' - message 'You should be back in "railsbridge\_ruby\another\_directory".' - -end - - -step do - message "There are two tricks to save you some typing. The first one is command history." - message "Press the `up arrow` key." - result 'pwd' - message "Press `ENTER` to run the command." - message "Keep pressing the arrow key to replay commands. The `up arrow` moves backward through history, and the `down arrow` moves forward." -end - -step do - message "The `TAB` key will autocomplete a command." - console <<-LINES -cd ~ -ls -cd rai - LINES - message '... and hit `TAB`.' - result 'cd railsbridge_ruby' - message <<-LINES -Autocomplete will be as smart as it can. If you started with `cd`, it will list directories. - If it could be a command, it will suggest commands. When there are multiple matches, it will show you the options. - LINES - console 'p' - message '... and hit `TAB`. What happens? Hit `TAB` a second time.' - result 'Display all 203 possibilities? (y or n)' - message 'When autocomplete is stumped, it\'ll wait for another hint. It will ask when there are too many possibilities.' - console 'y' - message 'There are quite a few commands that begin with `p`! Autocomplete can remind you when you don\'t know what all the choices are.' - -end - -challenge do - message "Using the command line and your editor, create a new directory that contains a set of text files. These text files will be lists of the various things you want to learn." - - message "For example, you might want to learn various things about ruby and HTML. You could create a `ruby.txt` file and a `html.txt` file in the same directory. In each file, enter in a few questions you have about those topics." -end - -explanation do - message "The command line is an essential tool for computer programmers. While daunting at first, it offers great flexibility in moving around your computer and manipulating files." - message "There are many, many, many more commands available on the command line than what we've seen here, but these are enough to get you going." - message 'Command summary:' - - table class: 'bordered' do - tr do - td 'pwd' - td 'print working directory' - td 'print the full path to your current directory' - end - tr do - td 'ls' - td 'list directory' - td 'display the contents of the current directory' - end - tr do - td 'cd [directory]' - td 'change directory' - td 'make this directory the current directory' - end - tr do - td 'man [cmd]' - td 'manual' - td "show the manual for this command. press 'q' to quit." - end - end -end - -tip do - message "If your workshop is using a Virtual Machine (ask a TA!) now is the time to take a detour to [Using Virtual Machines](using_virtual_machines)" -end - -next_step 'irb' \ No newline at end of file diff --git a/sites/en/ruby/conditionals.step b/sites/en/ruby/conditionals.step deleted file mode 100644 index 892de6454..000000000 --- a/sites/en/ruby/conditionals.step +++ /dev/null @@ -1,100 +0,0 @@ -goals do - goal 'Use `gets` to get input from the user of your program.' - goal 'Use a conditional statement to execute a branch of code only some of the time.' - goal 'if/elsif/else, while, unless' -end - - -step do - message "In this section, we'll modify the file we've created in previous steps which we called `conditionals_test.rb`. Verify that it has only the following contents." - - type_in_file 'conditionals_test.rb', <<-'CONTENTS' -print "How many apples do you have? > " -apple_count = gets.to_i -puts "You have #{apple_count} apples." - CONTENTS -end - -step do - message 'Continuing on from the end of conditionals_test.rb...' - type_in_file 'conditionals_test.rb', <<-'CONTENTS' -print "How many apples do you have? > " -apple_count = gets.to_i - -if apple_count > 5 - puts "Lots of apples!" -else - puts 'Not many apples...' -end - CONTENTS - console 'ruby conditionals_test.rb' - message 'Sometimes, we want our programs to make decisions for us. We call this concept **flow control** and it is found in most object oriented programming languages. The `if ... else ... end` construct is a way of selectively executing code based on values that exist in the program.' - message 'Try running the program with different values for `apple_count` to see each side of the conditional get executed. Notice how if you enter an apple count less than or equal to 5, `Not many apples...` is outputted. If you enter an apple count greater than 5, then `Lots of apples!` is outputted. The results of the expression `apple_count > 5` returns true or false, and with the use of the `if` statement, your program can start to make decisions as to what parts of the program to execute.' -end - - -step do - message 'What goes after the `if` is any expression that returns a **boolean**, (the values `true` or `false`). ' -end - - -step do - message "A **while** loop continues repeating until a certain statement is false. Here, the program continually asks us for numbers until we say the string 'stop'." - - message 'Create a new file called while_loop.rb' - type_in_file 'while_loop.rb', <<-'CONTENTS' -total = 0 -user_input = nil -while user_input != 'stop' - print 'Enter a number to add to the total. > ' - user_input = gets.chomp - total = total + user_input.to_i -end -puts "Your final total was #{total}!" - CONTENTS - console 'ruby while_loop.rb' - - message "It's easy for a while loop to get out of control! If your loop body doesn't do anything to make the **while** condition false, your loop will run forever. Programmers call this an **infinite loop**. If you get into an infinite loop, you can terminate the program by typing **ctrl+c**" -end - -challenge do - message "Let's extend the program you created in the numbers and arithmetic assignment to perform more mathematical operations." - - message "Using what you've learned about flow control, allow the user to select whether they would like two numbers to be added, subtracted, multiplied, or divided." - - message 'Here is a sample of how the program might run. The `>` has been used below to indicate that the user should input the value proceeding it.' - - source_code <<-'CONTENTS' -What is the first number? -> 2 -What is the second number? -> 4 -Would you like to add (1), subtract (2), multiply (3), or divide (4) these numbers? -> 3 -The product is 8 -CONTENTS - - message "As an optional challenge, can you modify this program to continuously ask for numbers?" - - message "Here is a sample of how the program might run." - - source_code <<-'CONTENTS' -What number do you want to include? -> 2 -What number do you want to include? -> 4 -What number do you want to include? -> 6 -What number do you want to include? -> DONE -Would you like to add (1), subtract (2), multiply (3), or divide (4) these numbers? -> 3 -The product is 48 -CONTENTS -end - -explanation do - message "Without some kind of conditional, your program would do the same thing every time. Conditionals let you choose to do different things depending on what data you have in hand." -end - -next_step 'nil' diff --git a/sites/en/ruby/datatypes.step b/sites/en/ruby/datatypes.step deleted file mode 100644 index fb7cf9277..000000000 --- a/sites/en/ruby/datatypes.step +++ /dev/null @@ -1,98 +0,0 @@ -goals do - goal "Know the basic data types" - goal "Know why it matters" - message "Variables are easygoing about the objects they hold. You can assign a word, then assign a number, then a list of words." - message "But sometimes it matters what type of data we assign a variable. The fancy word for \"type of data\" is **class**." - message "Ruby has several built-in classes. In a later section, we'll explore how to make your own classes." -end - -step do - message "How can you find out what class something is?" - irb '"Letters and words".class' - result "String" - message "\"class\" is a **method**, a behavior you can ask an object to perform. " - message "To call a method on an object, type the object or variable name, then - a period, and finally the method name. " - message "Here's a preview of the datatypes we'll cover:" - irb <<-TRYME -'a'.class -5.class -3.14.class -true.class -:symbol.class -[ 1, 2, 3].class -{name: "value"}.class -nil.class -Class.class -TRYME -end - -step do - message "Different classes come with different methods. Browse the String - class' methods. (Ruby will put a ':' before the method name.)" - irb '"five".methods' - message "There are a lot of them. Can you predict what some of them do?" - message "Numbers have different methods." - irb "5.methods" - message "Notice that number methods include arithmetic operators." - message "Knowing what class an object is tells us what methods we can call." -end - -step do - message "Some datatypes are incompatible. For example, Ruby knows how to - concatenate two objects of the same class." - irb <<-TRYME -5 + 5 -"5" + "5" -TRYME - message "Ruby can guess how to convert some classes into a similar class." - irb "5 + 5.0" - message "... but it's totally confused by different objects." - irb <<-TRYME -5 + "5" -"5" + 5 -TRYME -end - -step do - message "When you have incompatible data types, you can use an object's - *conversion methods* to get a translated version of the object." - message "Conversion methods can be spotted by their name; they begin with - `to_`, e.g. `to_s` converts to a string, `to_i` to an integer, and `to_f` to - a float (decimal)." - irb <<-TRYME -5.to_s -5.to_s.class -5.to_f -5.to_f.class -5.67.to_i -"5".to_i -"5".to_i.class -TRYME - message "There isn't always a sensible conversion from one class to another." - irb <<-TRYME -"I am not a number".to_i -"five".to_i -TRYME - message "Conversion methods are used most often in calculations and in printing." - irb <<-TRYME -5 + "5".to_i -"5 plus" + 5.to_s -TRYME - message "It's common to include a `to_s` method when you make your own classes so it prints nicely." - message "To explore further, try converting the examples in step 1 to - different classes. To more easily see what conversion methods an object has, - call `methods.sort` on it." - irb "5.methods.sort" -end - -explanation do - message "Sometimes it's necessary to think about what type of data you're working with." - message "Use the `class` method to find out what class an object is." - message "Use the `methods` method to find out what methods an object has." - message "Use conversion methods to get a transformed version of an object." - message "A `TypeError` message is a hint to look more carefully at an object's class." - message "Let's look at the basic datatypes in more detail." -end - -next_step "strings" diff --git a/sites/en/ruby/functions.step b/sites/en/ruby/functions.step deleted file mode 100644 index 3a59daeac..000000000 --- a/sites/en/ruby/functions.step +++ /dev/null @@ -1,69 +0,0 @@ - -message "A function is a step in a process. Think back to the last recipe you cooked. There were steps like 'mix', 'measure', and 'bake'." - -goals do - goal "Create a function" - goal "Call a function" -end - - -step do - message 'In your text editor, create a new file called area.rb' - type_in_file 'area.rb', <<-'CONTENTS' -def calculate_circle_area(radius) - Math::PI * (radius ** 2) -end - -print "What is the radius of your circle? > " -radius = gets.to_i - -puts "Your circle has an area of #{calculate_circle_area(radius)}" - CONTENTS - message "Save your work. " -end - -step do - message "Run the file." - console 'ruby area.rb' - message 'When prompted, type in a radius for your circle and hit return.' -end - -step do - message "We can write functions in IRB too." - - irb <<-CONTENTS - - def backwards( phrase ) - phrase.reverse - end -CONTENTS - - - message <<-CONTENTS -A function begins with `def`. It's followed by the name of the function, and then a list of what you plan to send in. - -Inside the function is the code that does the work. The function ends with a statement that evaluates to a function. What does it mean to evaluate a statement? When we type `puts "Two plus two is \#{2 + 2}", Ruby evaluates the statement inside the curly brackets. 2 + 2 evaluates to 4, and 3 < 9 evaluates to true. "Hello".reverse evaluates to "olleH". The function hands the value back by saying it. - -After you typed 'end' and hit return, irb typed `nil`. This is fine. Ruby always reports what it got when it ran your command, and functions result in `nil`. -CONTENTS - message "... and then **call** our function:" - - message "To call a function, first say the name of the function, then send in the values the function needs to do its job." - - irb "backwards 'Hello' " -end - - -step do - message "We can store the result in a variable." - irb "mirror = backwards 'Hello'" -end - - -explanation do - message "As your programs get more and more complicated, you'll want to group code into **functions** that can be called over and over again." - message "Pedantic Programmers might want to tell you that Ruby doesn't technically have **functions**, and everything in Ruby is really a **method**. It is appropriate to slap these people." -end - - -next_step 'classes' diff --git a/sites/en/ruby/hashes.step b/sites/en/ruby/hashes.step deleted file mode 100644 index f02c3b9c9..000000000 --- a/sites/en/ruby/hashes.step +++ /dev/null @@ -1,50 +0,0 @@ -goals do - goal "Make some hashes and get data back out of them" - goal "Understand why we might use a Hash" - goal "Understand the differences between Arrays and Hashes" -end - -step do - irb <<-IRB -states = {"CA" => "California", "DE" => "Delaware"} - IRB - message "Arrays are ideal when we want to store an ordered list of items. We can access elements in an array by their position, but sometimes the position doesn't really help us much. We may want to access items in the list based on a name, or **key**. A hash stores pairs of items, associating **keys** with **values**." - message 'The `{` character is typically called a \'curly brace\', and the `=>` is called a \'rocket\' or \'hashrocket\'' - irb <<-IRB -states.keys -states.values - IRB - message 'You can ask a hash for an array of just its keys or its values.' - irb <<-IRB -states['CA'] -states['DE'] - IRB - message 'With arrays, we accessed elements by their **index**, a number. With a hash, we access elements by their **key**.' -end - -step do - irb <<-IRB - bike_1 = {'make' => 'Trek', 'color' => 'Silver'} - bike_2 = {'make' => 'Cannondale', 'color' => 'Blue'} - bikes = [bike_1, bike_2] -IRB - message "Hashes are often used to store the properties of some object. Here, each hash stores the properties of a bike." - message "The *keys* are often the name of a property (here *make*, *color*) while tha *values* are the value of the property for a given object (here, *Trek*, *silver*)." - message "Consider how you might have had to store this data if you didn't have hash. What else might you want to store in a hash?" - irb <<-IRB - bikes[0]['make'] - bikes[1]['color'] -IRB - message 'When objects are nested deeply in arrays and hashes, you can access elements one after the other like this.' - message "For example, on the first line here, we are getting the first *bike* in the *bikes* array (`bikes[0]`) and then getting its *make* (`bikes[0]['make']`)" -end - -explanation do - message "Hashes are a fundamental way to group large amounts of related data. In other languages, hashes are called **dictionaries**, **maps**, or **associative arrays**." -end - -further_reading do - a "Ruby's documentation for Hash", href: 'http://www.ruby-doc.org/core-1.9.3/Hash.html' -end - -next_step 'loops' diff --git a/sites/en/ruby/how_to_write_a_program.step b/sites/en/ruby/how_to_write_a_program.step deleted file mode 100644 index ad6910dce..000000000 --- a/sites/en/ruby/how_to_write_a_program.step +++ /dev/null @@ -1,240 +0,0 @@ -goals do - goal "Break down problem statements into code" - goal "Design and arrange our code to serve a purpose" -end - - -explanation do - message "Every time we write a program, we translate abstract thoughts in our minds into workable, actual code. It helps to think out those thoughts and put them in a clear, plain, problem statement." - message "if we think out all the functionality of our program, we can write a description that we can *refactor* into a program, piece by piece, until it does what we want it to do." - message "Here, we're going to break down a problem statement into workable goals that we can then translate into our first program." -end - -step do - message "Today, we're going to write a Dice rolling simulator. It's a simple app, with three goals: **Simulate the rolling of a die**, **Roll a die with any number of sides**, and **Roll any number of dice.**" - - message "Lets start by making a file named **'roller.rb'**" -end -step do - message "lets start with the first goal, **Simulate the rolling of a die.**" - message "Ruby comes with the 'rand' method, which can give you a random number. It takes an integer as an argument, and will give you a random number." - - message "Note: rand is 0-indexed, like an array. Open up irb and type:" - - irb 'rand 2' - - message "Now, repeat that a few more times. You'll notice the numbers you get in response are either a 0 or a 1, never a 2. This is what 0-indexing means: the first number is always zero." - - message "The problem is, dice don't start at zero, they start at one. So we can just add one to the rand method to make it more dice-like." - - message "Open up 'roller.rb' and write this method into the file." - type_in_file 'roller.rb', <<-'CONTENTS' - def roll - rand(6) + 1 - end - puts roll - CONTENTS - - message "Run that file a few times, and you'll see that we have successfully simulated rolling a die." -end -step do - message 'Now on to the second goal, **Roll a die with any number of sides**.' - message 'We can take our existing roll method and add to it with a simple argument.' - - type_in_file 'roller.rb', <<-'CONTENTS' - def roll(sides) - rand(sides) + 1 - end - - puts roll(6) - CONTENTS - - message 'Now, our program can roll any number of die, so long as we pass in the number of sides to the roll method.' -end - -step do - message "We've got one more goal to knock down: **Roll any number of dice**." - message 'We can pass in another argument, but we still have to consider how to show this information to the user. For now, lets add the numbers together.' - message "We're going to need to increase the method somewhat. Make the changes to the method that you see below." - type_in_file 'roller.rb', <<-'CONTENTS' - def roll(sides, number=1) - roll_array = [] - number.times do - roll_value = rand(sides) + 1 - roll_array << roll_value - end - total = 0 - roll_array.each do |roll| - new_total = total + roll - total = new_total - end - total - end - - puts "We're rolling a six sided die!" - puts roll(6) - - puts "Now we're rolling two 20 sided die!" - puts roll(20, 2) - CONTENTS - - message "A lot is happening in this function, now! Here's a walkthrough of the changes we made: " - message "* We added an argument, 'number'. It has a default argument of '1', so that way if we don't pass it anything, it just uses the default. " - message "* We create an empty array to hold the dice we're about to roll, called 'roll_array'." - message "* We call the 'times' method on the number. This is like the 'each' method, which allows us to run the code inside of it as many times as the number. So, if it is 1, it will do it once. If it is 2, it will do it twice, and so on." - message "* every time we loop over this code, we make the roll (using the sides argument value) and then insert the result into the roll_array." - message "We assign 0 to the variable 'totals'. This is what we're going to use to hold the value of the combined rolls." - message "* We loop through each item in the roll_array, and add it to the 'totals' variable. The totals variable is saved outside of the loop, so you will effectively add each of the members together." - message "* We add the totals variable at the end so that the method knows what to return." - - message "And so, we have a program that works they way we want it to work... but how useful is it?" -end - -step do - message "The problem with our program currently is that it is too clunky. Whenever you write code, think about how you want it to be used - either by you, a user, or even another programmer that might want to adapt your work further down the line. We should strive to write code that is readable, and mainainable." - - message "Right now, our program is one big method, and that is not very good for readability or maintability. Lets organize this a little more thoughtfully, and make a class that contains this behavior." - - type_in_file 'roller.rb', <<-'CONTENTS' - class Die - - def initialize(sides) - @sides = sides - end - - def roll(number=1) - roll_array = [] - number.times do - roll_value = rand(@sides) + 1 - roll_array << roll_value - end - total = 0 - roll_array.each do |roll| - new_total = total + roll - total = new_total - end - total - end - end - - puts "We're rolling a six sided die!" - puts Die.new(6).roll - - puts "Now we're rolling two 20 sided die!" - puts Die.new(20).roll(2) - CONTENTS - - message "Now, we can instantiate a Die object (passing in the number of sides as an argument) and then roll as a method called in it. This makes things a little easier to organize and break up this big method into smaller bits." - - message "Think for a moment about how we could break up that big method into smaller ones. What parts can we seperate now that we have the stability of a class?" -end -step do - message "One option for breaking it up would be to seperate out the method of rolling a single die. Right now, 'rand(sides) + 1' doesn't necessarily make sense in context. If someone was reading this code, it might not be obvious that it is actually generating a number for a rolled die. lets break that up into its own method:" - - type_in_file 'roller.rb', <<-'CONTENTS' - def generate_die_roll - rand(@sides) + 1 - end - end - CONTENTS - message "And now, our entire class looks like this:" - - type_in_file 'roller.rb', <<-'CONTENTS' - class Die - def initialize(sides) - @sides = sides - end - - def generate_die_roll - rand(@sides) + 1 - end - - def roll(number=1) - roll_array = [] - number.times do - roll_array << generate_die_roll - end - total = 0 - roll_array.each do |roll| - new_total = total + roll - total = new_total - end - total - end - end - - puts "We're rolling a six sided die!" - puts Die.new(6).roll - - puts "Now we're rolling two 20 sided die twice!" - puts Die.new(20).roll(2) - CONTENTS - - message "It is a small change, but now that line makes a little more sense when reviewing it. Making changes like this can be a big help to others, but an even bigger help to yourself. Programming is hard, so be sure to be kind to your memory while you do it!" -end - -step do - message "We're almost done. Why don't we make things easy for our soon-to-be users? We can imagine that there are certain dice that are popular in many games. Why not define some ready-made dice that people can use moving forward?" - - message "We're going to instantiate some dice in our class, and assign them to something called a 'Constant'. Constants are like variables, except they are unchanging - once they are assigned, they are assigned to that value - forever! They can't ever be changed. Note: You may have noticed that class names start with an uppercase - that is because class names are, in fact, constants!" - - message "We're going to assign some of these dice to constants to make it easier to use later." - - type_in_file 'roller.rb', <<-'CONTENTS' - SIX_SIDED_DIE = Die.new(6) - EIGHT_SIDED_DIE = Die.new(8) - TEN_SIDED_DIE = Die.new(10) - TWENTY_SIDED_DIE = Die.new(20) - CONTENTS - - message "So now, our file looks like this:" - type_in_file 'roller.rb', <<-'CONTENTS' - class Die - def initialize(sides) - @sides = sides - end - - def generate_die_roll - rand(@sides) + 1 - end - - def roll(number=1) - roll_array = [] - number.times do - roll_array << generate_die_roll - end - total = 0 - roll_array.each do |roll| - new_total = total + roll - total = new_total - end - total - end - end - - SIX_SIDED_DIE = Die.new(6) - EIGHT_SIDED_DIE = Die.new(8) - TEN_SIDED_DIE = Die.new(10) - TWENTY_SIDED_DIE = Die.new(20) - - puts "We're rolling a six sided die!" - puts SIX_SIDED_DIE.roll - - puts "Now we're rolling two 20 sided die twice!" - puts TWENTY_SIDED_DIE.roll(2) - CONTENTS - - message 'And now you have a program that works, is readable, and easy to use. Congratulations!' - - message 'Lets have some fun. launch irb and type the following:' - irb "require './roller.rb'" - - message "This loads the file into irb, which lets us play with it. Try using the dice. Roll a few! Use the constants to roll dice that you have already defined, or create some new dice and test the bounds of the system." -end - -explanation do - message "Consider the differences in the code between steps 4 and step 8. Coding is like being an architect, in that what you create is, at once, creative and load-bearing. The code at the end of step 4 worked perfectly, but it was hard to read, and a little bit of a pain to change. Imagine if we wanted to keep log of how the die rolled, or add other aspects or descriptions to the roll." - - message "The final version of the code gives us room to breathe, is easy to read and easy to modify. Consider what other changes might be made to make it even simpler - when it comes to writing code, it's generally better to split big methods into lots of smaller ones." -end - diff --git a/sites/en/ruby/input_and_output.step b/sites/en/ruby/input_and_output.step deleted file mode 100644 index 5cd3d62c1..000000000 --- a/sites/en/ruby/input_and_output.step +++ /dev/null @@ -1,67 +0,0 @@ -goals do -goal "Print to the screen with puts" -goal "Read user input with gets" -end - -message '' - -step do - irb <<-IRB -puts 'Hello World' - IRB - message '`puts` (**put** **s**tring) is a way of printing information to the user of your program.' - message 'Take some time to contemplate the output of `puts` in irb:' - result <<-RESULT -irb :006 > puts 'Hello World' -Hello World - => nil -irb :007 > - RESULT - message 'The method `puts` always has the **return value** of `nil`, which is what we see after the `=>` in the output. Printing \'Hello World\' to the screen is just a side-effect.' -end - - -step do - message "`print` is like `puts` but doesn't make a new line after printing." - - message 'Create a new file called input\_and\_output.rb' - type_in_file 'input_and_output.rb', <<-'CONTENTS' -print "All" -print " " -print "in" -print " " -print "a" -print " " -print "row" -CONTENTS - message "Save the file and exit out of irb." - console 'ruby input_and_output.rb' -end - - -step do - message 'Create a new file called conditionals_test.rb' - type_in_file 'conditionals_test.rb', <<-'CONTENTS' -print "How many apples do you have? > " -apple_count = gets.to_i -puts "You have #{apple_count} apples." - CONTENTS - message "Save the file and exit out of irb." - console 'ruby conditionals_test.rb' - message 'When prompted, type in a number of apples and press enter.' - message "`print` is like `puts` but doesn't make a new line after printing." - message "`gets`, or **get** **s**tring, pauses your program and waits for the user to type something and hit the enter key. It then returns the value back to your program and continues execution. Since the user could have typed anything ('banana', '19.2', '<` has been used below to indicate that the user should input the value proceeding it.' - - source_code <<-'CONTENTS' -What do you want to say? -> sally sells seashells -You said: sally sells seashells -CONTENTS -end -next_step "numbers_and_arithmetic" diff --git a/sites/en/ruby/irb.step b/sites/en/ruby/irb.step deleted file mode 100755 index c565a3864..000000000 --- a/sites/en/ruby/irb.step +++ /dev/null @@ -1,84 +0,0 @@ -goals do - goal "Understand how and when to use irb" - goal "Understand how to start and stop irb" - goal "Understand the difference between irb and the command line" - goal "Execute some simple Ruby statements" -end - -step do - message "irb is the **i**nteractive **r**u**b**y interpreter. It's a program - that runs Ruby code as you type it in." - message "Start irb." - console "irb" - result "irb: line 001 >" - message "The prompt changed. This is irb's way of reminding you that it's - running, and telling you it's ready." - message "Hit **Enter** a few times." - result "irb: line 002 > -irb: line 003 > -irb: line 004 >" - -end - -step do - message "irb will run until you quit." - irb "exit" - message "You're back at the command line. Notice that the prompt no longer says irb." - message "`exit` is the guaranteed way to get out of irb. Depending on your - operating system, Control-C or Control-D on an empty line may also work." - message "Practice going in and out of irb a couple of times. How can you tell - when you're in irb? How can you tell when you're back at the command line?" -end - - -step do - message "irb is its own program with its own commands. Although we start it - from the command line, the commands to change directories and so on don't - work in irb." - message "Restart irb." - console "irb" - irb "pwd" - result <<-YIKES - NameError: undefined local variable or method `pwd' for main:Object - from (irb):1 - from /usr/bin/irb:12:in `
      ' - YIKES - message "This ferocious error message is irb saying \"Huh? What??\" because - only irb understands Ruby." -end - -step do - message "In irb, you can experiment with short pieces of code to figure out what they do." - irb <<-IRB -5 + 9 -109 / 17 -2 ** 8 -5 > 6 - IRB - message "What happened after each line? What do you think these statements do?" -end - -step do - message "Lets take a closer look at the output of irb:" - irb "1 + 2" - result <<-MESSAGE -1.9.3p125 :015 > 1 + 2 - => 3 -1.9.3p125 :016 > - MESSAGE - message "Here, `=> 3` is the **return value** of the **statement** `1 + 2`, - the result of running your code." - message "Every statement in Ruby has a **return value**: irb shows you that - value after you type a complete statement and press ENTER." -end - - -explanation do - message "irb is a place to experiment and find out how certain language - features work. It's not a good place to write long programs. It doesn't let - you save your work, and it's not a very friendly text editor." - message "When you write a full-fledged program, you'll save it into a text - file on your computer. We'll see this in a later step." -end - -next_step "running_programs_from_a_file" diff --git a/sites/en/ruby/loops.step b/sites/en/ruby/loops.step deleted file mode 100644 index 4d8c8ee02..000000000 --- a/sites/en/ruby/loops.step +++ /dev/null @@ -1,88 +0,0 @@ - message 'Loops are a way of doing something multiple times. In this loop, we printed each fruit to the screen in order.' - -goals do - goal "Use loops to do operations for every element in an array." - goal "Use `puts` to print strings to the screen." - goal 'Learn the two different syntaxes for creating blocks in Ruby.' -end - -step do -message "What do you predict this will do?" -irb "3.times { puts 'Hip, hip, hooray!'}" -message "The `times` method will do something as many times as you tell it." -message "The chunk of code between the brackets is called a `block`. It will get run each time." -end - -step do -message "We often want to do something to each item in a collection." -irb <<-CONTENTS -beatles = [ "John", "Paul", "George", "Ringo"] -beatles.each { |beatle| puts "Hi, my name is \#{beatle}"} -CONTENTS - -message 'The straight up-and-down `|` is called the **\'pipe character\'**. On a US keyboard, it\'s typically the shifted version of the `\` (backslash) key.' -message "The variable between the pipes is a **block variable**. It's a way to refer to each item in the collection." - message '`each` takes the first element in the array and sends it to the block, which temporarily stores it in the **block variable** and then runs the code after the pipes. It then goes back and does this again for each of the remaining items in the array.' - irb <<-'IRB' -ducks = ['Huey', 'Dewey', 'Louie'] -ducks.each { |duck| puts "#{duck} quacks!" } -ducks.each { |zombie| puts "#{zombie} quacks!" } - IRB - message 'It doesn\'t matter what you call your block variable: the previous two statements are exactly equivalent to Ruby. But you should try to name your variables something useful so the code makes sense to you later!' -end - -step do -irb "('a'..'z').each { |letter| puts letter }" -message "In ruby, we have a special construct called a **range**. A range gives us a shortcut in defining a list of objects that fall within starting and ending point. In the example above, we're defining a range of all the lowercase characters between and including 'a' and 'z'. When used with an `each` statement, a range will loop through each value within that starting point and ending point." - -irb "('a'...'z').each { |letter| puts letter }" - -message "How is this line different from the previous example? The three dots tells us to **omit** the ending point." -end - -step do - message "There's a second way to make a block in Ruby. Instead of { }, we surround the code with **`do`** and **`end`**." - irb <<-'IRB' - -total = 99 -colors = ['red', 'blue', 'green'] -colors.each do |color| - puts "#{total} colors of paint on the wall..." - puts "Take #{color} down, pass it around..." - total = total - 1 - puts "#{total} colors of paint on the wall!" -end - IRB - message " The `do ... end` syntax is typically used when a block needs to span multiple lines, while the `{ ... }` syntax is for a single line block." -end - -challenge do - message "Let's write a program that greets everyone in your group. Use an array to store everyone's name." - - message 'Here is a sample of how the program might run.' - - source_code <<-'CONTENTS' -Oh, hello, Sally Samsonite! -Oh, hello, Johnny Jameson! -Oh, hello, Beth Benitsky! -Oh, hello, Corinne Camelia! -CONTENTS - - message 'Your program should be written in a way that group members can be removed and added to your array without requiring a change to the rest of your program. Use what you now know about loops so that only one `puts` statement is in your program.' - - message "Let's write a program that adds up a set of numbers in an array. The numbers you can use as a test case are 4, 6, 5, 5, 10" - - message 'Here is a sample of how the program might run.' - - source_code <<-'CONTENTS' -The sum of all of the numbers is 30. -CONTENTS - - message "Your program should be written in a way that doesn't require massive changes when the array of numbers is modified." -end - -explanation do - message "As you build complex programs, you'll want to do something to many pieces of data without typing it all out. Loops help solve this problem." -end - -next_step "summary:_basics" diff --git a/sites/en/ruby/nil.step b/sites/en/ruby/nil.step deleted file mode 100644 index 4ed3b85c7..000000000 --- a/sites/en/ruby/nil.step +++ /dev/null @@ -1,97 +0,0 @@ -message <<-CONTENT -nil is a special Ruby data type that means "nothing". It's equivalent to null or None in other programming languages. - - -CONTENT - -goals do -goal "Know what nil is for" -end - -step do -message <<-CONTENT -How do you set a variable to empty? - -Some of the values we could use can be legitimate values, like: - -`temperature = 0` - -`today_is_friday = false` - -`empty_phrase = ""` - -Nil to the rescue. Nil means 'nothing'. It's used to show that a variable hasn't been assigned anything yet, or that a function didn't return a value. - - -CONTENT - -irb <<-IRB -# Where is the letter "a" in apple? -"apple".index("a") - -# Where is the letter "z"? -"apple".index("z") -IRB -end - -step do - message "You may have noticed this already:" - irb 'puts "What does puts evalute to?"' - message "Ruby returns what an expression evaluated to. `puts` puts a string on the screen, but always evaluates to nil." - -end - - - -step do - message "Here's an error message you will see often." -irb <<-IRB - word = "hello" - word.upcase - word = nil - word.upcase -IRB - result "NoMethodError: undefined method 'downcase' for nil:NilClass" - message "What happened?" - irb "word.class" - message "`word` was set to nil. Let's look at the alphabetized list of methods the Nil class has." - irb "word.method.sort" - message "The error message told us Nil doesn't have a method called upcase." - -end - -step do - message "How can we avoid these errors? There are a few ways to tell if something is nil." - -irb <<-IRB -word = "something" -word.nil? -word = nil -word.nil? -# Remember, two equals signs asks if something is equal -word == nil? -IRB - - message "What's going on here?" - source_code <<-CONTENT - name = nil - if name.nil? - puts "The name hasn't been set yet." - else - puts "Your name is \#{name}" - end -CONTENT -end - - -explanation do - -end - -further_reading do - message "[Nil Class documentation](http://www.ruby-doc.org/core-2.1.0/NilClass.html)" -end - - -next_step 'symbols' - diff --git a/sites/en/ruby/numbers_and_arithmetic.step b/sites/en/ruby/numbers_and_arithmetic.step deleted file mode 100644 index b52de8fb2..000000000 --- a/sites/en/ruby/numbers_and_arithmetic.step +++ /dev/null @@ -1,85 +0,0 @@ -goals do - goal "Understand the difference between an integer and a float" - goal "Perform basic arithmetic operations" -end - -step do - message "In programming, we like to distinguish between different kinds of - numbers. Here, we'll talk about integers (whole numbers) and floats - (decimals)." - irb <<-TRYME -1.class -1.0.class -TRYME - message "You'll notice that `1.class` and `1.0.class` are actually 2 different - kinds of objects." - message "With that in mind, let's see how that plays into performing - arithmetic opertions." -end - -step do - irb <<-TRYME -1 + 2 -1.0 + 2.0 -1 + 2.0 -TRYME - message "Here, you'll notice that performing an operation on 2 integers will - produce an integer and operating on 2 floats will produce a float, but mixing - an integer with a float would actually produce a float." -end - -step do - irb <<-TRYME - -2 - 1 -2.0 - 1.0 -2.0 - 1 -TRYME - message "Just like addition, we can perform subtraction on integers and floats interchangeably." -end - -step do - irb <<-TRYME - -2 * 3 -2.0 * 3 -2.0 * 3.0 -TRYME - message "Likewise, we can perform multiplication on floats and integers." -end - -step do - irb <<-TRYME - -4 / 2 -8 / 2 -6 / 4 -6 / 4.0 -TRYME - message "Division can be performed similarly. Notice the difference in the results of the last two lines. When dividing two integers, ruby will perform mathematical truncation, where the expected result 1.5 becomes 1" -end - -step do - irb <<-TRYME - -4 / 0 -TRYME - message "Uh oh! Notice how we did not get a result here. The ruby interpreter raised an error. These errors tell the programmer that they tried to do something that the interpreter does not like or cannot use. Each error has a classification and a message. In this case, we get a `ZeroDivisionError` with the message: divided by 0" -end - -challenge do - message "Write a calculator that performs addition. Your program should prompt the user to enter two numbers and output the sum." - - message 'Here is a sample of how the program might run. The `>` has been used below to indicate that the user should input the value proceeding it.' - - source_code <<-'CONTENTS' -What is the first number? -> 2 -What is the second number? -> 4 -The sum is 6 -CONTENTS - -end - -next_step "booleans" diff --git a/sites/en/ruby/overview:_building_blocks.step b/sites/en/ruby/overview:_building_blocks.step deleted file mode 100644 index 416a6fc0c..000000000 --- a/sites/en/ruby/overview:_building_blocks.step +++ /dev/null @@ -1,11 +0,0 @@ - -goals do -goal "Learn about different kinds of data: what they\'re called, what you can do with them" -goal "Store data in a variable so you can use it later" -goal "Make decisions with conditionals" -goal "Hold collections of data in arrays and hashes" -goal "Loop over a collection" -end - - -next_step 'variables' \ No newline at end of file diff --git a/sites/en/ruby/overview:_organizing.step b/sites/en/ruby/overview:_organizing.step deleted file mode 100644 index a1114872b..000000000 --- a/sites/en/ruby/overview:_organizing.step +++ /dev/null @@ -1,7 +0,0 @@ -message "When your program gets longer than one screenful, it gets hard to keep track of. Most interesting problems have hundreds of lines of code. Let's look at tools that make it more manageable." -goals do - goal "Use functions to break up code into tasks" - goal "Use classes to group variables and functions that naturally go together" -end - -next_step 'functions' \ No newline at end of file diff --git a/sites/en/ruby/ruby.step b/sites/en/ruby/ruby.step deleted file mode 100755 index f3ed0ef52..000000000 --- a/sites/en/ruby/ruby.step +++ /dev/null @@ -1,76 +0,0 @@ -message <<-MARKDOWN -### Goal - -To teach you Ruby we are going to explain the basic building blocks used in the Ruby language and allow you reinforce what you've learned through challenges. - -When you have completed this curriculum you should understand: - -* The command line and why we use it -* How to run your Ruby code interactively (irb) or from a file -* Simple types like numbers, strings, and booleans -* Data structures like arrays and hashes -* Object concepts like Classes - -### Requirements - -We're going to be working with: - -* Ruby -* A command line program -* A text editor of your choice - -Everything should be set up the night before during our -Installfest. Please -ensure you have everything working _before_ you show up for the workshop. - -You can verify that you have everything working by trying this out in your terminal: - -
      -$ irb
      ->> 1 + 2
      -=> 3
      -$
      -
      -
      - -If you can do that, you are probably good to go. - -### Format - -Each lesson will look like this: - -
      -

      Step Title

      -
      -

      Goal:

      -

      Description of the current step. -

      Red because big goals are scary. -

      -
      -

      Steps:

      -
      steps to take.
      -
      -
      -def code_to_write
      -  1 + 1
      -end
      -
      -

      Yellow because we've gotten it done, but we have no clue what's going on. -

      -
      -

      Challenges

      - -

      A list of activities to try to reinforce the concepts learned in the lesson

      - -

      Orange because it stimulates the brain by increasing its oxygen supply.

      -
      -
      -

      Explanation

      -

      Details of what the steps actually did... spell out the cause and effect. -

      Green because we can tie everything together now. -

      -
      -MARKDOWN - -next_step "what_is_ruby" - diff --git a/sites/en/ruby/running_programs_from_a_file.step b/sites/en/ruby/running_programs_from_a_file.step deleted file mode 100644 index 2410536ec..000000000 --- a/sites/en/ruby/running_programs_from_a_file.step +++ /dev/null @@ -1,92 +0,0 @@ -message <<-INTRO -irb isn't a good tool for writing long programs. Code is entered one line at a -time. You can't save your work, and you can't share it when you're done. - -Instead, we write code in a file and run it from the command line. - -For writing code, we use a program called a text editor. - -A text editor is a word processor that saves in plain text format. This is -unlike Word, which saves files in a special format that only Word can read. - -We may have recommended a particular text editor during the Installfest, such as -SublimeText. You can use any editor you like so long as it saves plain text. - -It'll helpful to keep your text editor running, since you'll be coming back to -it often. -INTRO - -goals do - goal "Use a text editor." - goal "Write and save a Ruby program into a file" - goal "Start and connect to the RailsBridge virtual machine, if you are using it for the workshop" - goal "Run Ruby code saved in a file" -end - -step do - message "Start your text editor." - message "In your text editor, create a new file called **my_program.rb**" - type_in_file "my_program.rb", <<-CONTENTS -puts 'This code is in a file!' -some_variable = 19 -puts "I stored a variable with the value #\{some_variable\}!" -CONTENTS -end - -step do - message <<-INFO -Save the file. - -If you're using the RailsBridge virtual machine, *save the file -in the same folder you created the virtual machine.* That folder is shared -between your laptop and the vm, like Google Drive. - -Did you notice we added `.rb` at the end of the name? It's standard practice to -name Ruby files this way, to help people and tools recognize the file contains -Ruby code. - -When you saved the file, your text editor may have added colors to the code. It -recognizes the file contains Ruby, and will mark up different kinds of words -with different colors. This is called "syntax highlighting", which makes it -easier to read code. -INFO -end - -step do - message "Let's look at the file." - message "Open your terminal, connect to the - VM, and `cd` to your workspace directory" - console "ls" - result "my_program.rb" - console "more my_program.rb" - result <<-CONTENTS -puts 'This code is in a file!' -some_variable = 19 -puts "I stored a variable with the value #\{some_variable\}!" -CONTENTS - message "**my_program.rb** was saved in plain text - you see exactlty what you - typed. If this were a Word document, you would see a screenful of weird - characters and formatting, and you would get errors when you ran it." -end - - -step do - message "Now run the code. Stay in your workspace directory." - console "ruby my_program.rb" - result <<-CONTENTS -This code is in a file! -I stored a variable with the value 19! -CONTENTS - message "If you didn't see this message, troubleshoot with a TA. We will do - this for the rest of the tutorial, so it's important to ensure everything - works." -end - - -explanation do - message "Congratulations! You've run your first Ruby program!" - message "Ruby programs are written in files and run from the command line. As - your program becomes larger and larger, it may span many files!" -end - -next_step "summary:_tools" diff --git a/sites/en/ruby/strings.step b/sites/en/ruby/strings.step deleted file mode 100644 index 205bffe5a..000000000 --- a/sites/en/ruby/strings.step +++ /dev/null @@ -1,97 +0,0 @@ -goals do - goal "Understand when to use strings" - goal "Learn how to combine strings" - goal "Learn about string interpolation" -end - -step do - irb <Recall that you can see what methods - are available for an object by calling `.methods` on it." - irb "'some string'.methods" -end - -explanation do - message "Strings are a key way to present information in your programs. Since a human will probably be reading the output of your program eventually, and humans speak words rather than numbers, you will often want to use strings." - message 'A not at all complete summary of methods on String:' - table class: 'bordered' do - tr do - td 'length' - td 'how long is this string (characters)' - end - tr do - td 'reverse' - td 'return same string, reversed' - end - tr do - td 'upcase' - td 'return same string, IN UPPER CASE' - end - tr do - td 'delete([another string])' - td 'delete all characters in the second string from the first' - end - tr do - td 'methods' - td 'get the names of all methods you can perform on string' - end - end -end - -further_reading do - a "Ruby's documentation for String", href: 'http://www.ruby-doc.org/core-1.9.3/String.html' -end - -next_step 'input_and_output' diff --git a/sites/en/ruby/summary:_basics.step b/sites/en/ruby/summary:_basics.step deleted file mode 100644 index e564bee4d..000000000 --- a/sites/en/ruby/summary:_basics.step +++ /dev/null @@ -1,18 +0,0 @@ -message "We\'ve seen built in data types, input and output, making decisions with conditionals as well as some looping. We've also identified two interesting data structures: the **array** and the **hash**." - -message "Challenge yourself to create programs for the following situations." - -message <<-CONTENT -
        -
      • Write a program that verifies whether someone can vote based on their supplied age.
      • -
      • Write a program that plays back the message a user supplied.
      • -
      • Write a program that adds up five user-supplied numbers.
      • -
      • Make a hash for the people at your table, where the key is their name and the value is their favorite color.
      • -
      • Make an array of the months in the year.
      • -
      -CONTENT - - -message "When programs get big, they get disorganized and hard to read. Next we'll look at how to keep things tidy with functions and classes." -next_step "overview:_organizing" - diff --git a/sites/en/ruby/summary:_tools.step b/sites/en/ruby/summary:_tools.step deleted file mode 100644 index 554a0a1b3..000000000 --- a/sites/en/ruby/summary:_tools.step +++ /dev/null @@ -1,17 +0,0 @@ - -message <<-SUMMARY -We\'ve explored the basic tools for writing and running Ruby programs. -
        -
      • How do you open the console on your laptop? -
      • How do you find out what directory you\'re in on the command line? How can you move to a different directory? -
      • How do you start the RailsBridge VM and connect to it? -
      • Where should you save files when you're using the RailsBridge VM? Can you show it in Finder or File Explorer? -
      • How do you run a Ruby program? -
      • How can you experiment with Ruby interactively? -
      • -
      -Let's dive into the ABCs of Ruby. - -SUMMARY - -next_step 'overview:_building_blocks' \ No newline at end of file diff --git a/sites/en/ruby/symbols.step b/sites/en/ruby/symbols.step deleted file mode 100644 index 427572d38..000000000 --- a/sites/en/ruby/symbols.step +++ /dev/null @@ -1,103 +0,0 @@ - -message " -Symbols are, if not unique to Ruby, at least not found in most other languages. - -Symbols help Ruby use memory more efficiently. Every time you store a value in an object, Ruby sets aside a little piece of memory to hold it. If enough memory is tied up, we'll see an effect on performance. Perhaps you've seen your laptop run more and more slowly when lots of programs are open, or seen it speed up when you add more RAM. - -Symbols let Ruby variables point to the same object in several places instead of allocating a new copy. As a metaphor, think of how a rental car company lets several drivers use the same car instead of buying their own. - -Efficient memory use isn't a concern in simple programs, but it's considered good form . At this stage, focus on recognizing and declaring symbols. You'll see symbols regularly as you look at code. -" - - -goals do - goal "Know a symbol when you see it" - goal "Learn how to declare a symbol" - goal "Notice when symbols are used" -end - - - -step do - message "Symbols start with a colon. Let's look at one." - irb <<-CONTENTS - :north - :north.class - :north.methods - CONTENTS -end - - -step do - message "Here are more examples:" - irb <<-CONTENTS - :TUESDAY - :"symbols can have spaces if in quotes but it's a lot to type" - :'single quotes work too' -CONTENTS - message "Experiment with naming symbols. Do they use the same rules as variables?" -end - - -step do - message "Symbols are constants, like letters and numbers, so they can't be assigned a value." - irb <<-CONTENTS - :north = :south - CONTENTS - - message "Symbols print their names when they're converted to strings." - irb <<-CONTENTS - :Saturday.to_s - puts "Today is \#{:Saturday}" - CONTENTS - - message "Symbols are used in a similar way to enums or named constants in other languages - for unchanging ideas that you want to refer to the same way, no matter where you are in a program. Unlike enums and named constants, you never initialize them with a value." -end - -step do - message <<-CONTENTS -How do we know it's the same object? Ruby assigns an object_id number when it creates an object, like a serial number. These are the same object. - CONTENTS - irb <<-CONTENTS -:friday.object_id -:friday.object_id - CONTENTS - message "Now create two variables with the value 'Friday' and check their object_id. " - message "Ruby allocated a fresh chunk of memory each time, even though the strings says the same thing." - - message <<-CONTENTS -Ruby automatically treats strings, numbers, and some values as symbols. - -In irb, check the object ids of a word, your lucky number, true and false, and nil. Check the same value twice to prove it's the same object. ( Tip: to save typing, use the up-arrow key to scroll back through your last irb commands.) - CONTENTS -end - - -step do - message "Calendars are a good example of when to use symbols. The days and months repeat. In a one year calendar making 52 new Mondays takes some memory, but not too much. What if you wanted to make a ten year calendar, or one with no limits? This is a good place for symbols. - - days = [:Monday, :Tuesday, :Wednesday, :Thursday, :Friday, - :Saturday, :Sunday] - - months = [:January, :February, :March, :April, :May, :June, - :July, :August, :September, :October, :November, :December] - - today = :Friday - month = :May - -" -end - - -explanation do - message "Symbols are memory-efficient labels we re-use to keep track of all kinds of things in Ruby. You'll see them again soon in Hashes." - message "When you see a symbol, think about why the programmer chose to use one. Is the idea important here, or the contents?" -end - -further_reading do - message "[The Difference Between Ruby Symbols and Strings ](http://www.robertsosinski.com/2009/01/11/the-difference-between-ruby-symbols-and-strings/)" - message "[The Ruby_Newbie Guide to Symbols](http://www.troubleshooters.com/codecorn/ruby/symbols.htm)" - message "[The Ruby documentation says](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/): *If you\’re in doubt whether to use a Symbol or a String, consider what\’s more important: the identity of an object (i.e. a Hash key), or the contents.*" -end - -next_step 'working_with_collections' \ No newline at end of file diff --git a/sites/en/ruby/using_virtual_machines.step b/sites/en/ruby/using_virtual_machines.step deleted file mode 100644 index ee788e453..000000000 --- a/sites/en/ruby/using_virtual_machines.step +++ /dev/null @@ -1,114 +0,0 @@ -message <<-INTRO -Some workshops ask OS X and Windows users to use a virtual machine. To -run Ruby, you need to start and connect to the virtual machine. -INTRO - -tip do - message "If students aren't using a virtual machine at your workshop, head back to the curriculum." -end - -goals do - goal "Define virtual machine, Vagrant, and VirtualBox" - goal "Find your workspace directory" - goal "Start and halt Vagrant" - goal "Connect to and exit Vagrant" -end - -message <<-CONTENTS -Most laptops don't come with Ruby installed. Getting 75+ people ready at a -workshop is a big logistical challenge. - -To get going quickly and to have things work the same for everyone, we're using -a virtual machine. Using a virtual machine adds some extra steps, which we'll -practice here. -CONTENTS - - -step do - message "First, let's define \"virtual machine.\"" - message "A virtual machine - **VM** for short - is a snapshot of all the - software on a computer. The snapshot is called an image. You downloaded and - saved the image file in the pre-workshop steps." - message "We've made an image of a Linux machine with Ruby and other tools - installed." - end - -step do - message <<-CONTENTS -By itself, a VM image is just a file like any other. It needs something to -run it. - -We're using VirtualBox. If a VM image is a fish, VirtualBox is the aquarium -it lives in. - -It knows how to translate the features of this Linux image into -something Windows or OSX understands, and display it on your monitor. It -knows how to translate your keyboard and mouse input to something the Linux -machine can use. - -If you're familiar with PC Anywhere, Remote Desktop, Parallels, or -VMware Fusion, VirtualBox is a bit like that. Essentially, you're accessing -another computer through your own computer. -CONTENTS -end - - -step do - message <<-CONTENTS -Vagrant is a tool for running a virtual machine. It will start and stop the -VM, and let you connect to it so you can use it. - -During the Installfest you made a folder called "workspace" and ran some vagrant -commands to set up the RailsBridge image. - -It created a configuration file named Vagrantfile. Vagrant needs the config -file in order to run the machine. -CONTENTS -end - -step do - message <<-CONTENTS -To run Ruby on our image, we have to start the VM and then connect to it. The -VM only needs to be started once. It will keep running until you halt it or -reboot your machine. -CONTENTS - console "vagrant up" - result <<-CONTENTS -Bringing machine 'default' up with 'virtualbox' provider... -[default] Clearing any previously set forwarded ports... -[default] Clearing any previously set network interfaces... -[default] Preparing network interfaces based on configuration... -[default] Forwarding ports... -[default] -- 22 => 2222 (adapter 1) -[default] -- 3000 => 3000 (adapter 1) -[default] Booting VM... -[default] Waiting for machine to boot. This may take a few minutes... -[default] Machine booted and ready! -[default] The guest additions on this VM do not match the installed version of -VirtualBox! In most cases this is fine, but in rare cases it can -prevent things such as shared folders from working properly. If you see -shared folder errors, please make sure the guest additions within the -virtual machine match the version of VirtualBox you have installed on -your host and reload your VM. - -Guest Additions Version: 4.2.0 -VirtualBox Version: 4.3 -[default] Mounting shared folders... -[default] -- /vagrant -[default] VM already provisioned. Run `vagrant provision` or use `--provision` to force it -CONTENTS - message "What happens if it's already running?" - console "vagrant up" - result <<-CONTENTS -Bringing machine 'default' up with 'virtualbox' provider... -[default] VirtualBox VM is already running. -CONTENTS -end - -further_reading do - message <<-CONTENTS -"What's virtualization? Why get that nerdy?" Lifehacker explains it all in [The -Beginner's Guide to Creating VMs with -VirtualBox](http://lifehacker.com/5204434/the-beginners-guide-to-creating-virtual-machines-with-virtualbox) -CONTENTS -end diff --git a/sites/en/ruby/variables.step b/sites/en/ruby/variables.step deleted file mode 100755 index 8f59e2b9b..000000000 --- a/sites/en/ruby/variables.step +++ /dev/null @@ -1,104 +0,0 @@ -message "A variable is a way to name a piece of data so we can do things with -it. It can hold all kinds of things - words, numbers, the result of a function, -and even a function itself." - -goals do - goal "Understand what a variable is for" - goal "Store data in variables" - goal "Replace data in an existing variable" -end - -step do - message "Start up irb." - console "irb" -end - -step do - irb "my_variable = 5" - message "This creates a new variable called `my_variable` and stores the value 5 in it." - message "Let's confirm that. To see what value a variable holds, type its name." - irb "my_variable" - result "5" - - irb "another_variable = \"hi\"" - - message "This creates another variable and stores the value \"hi\" in it." - -end - -step do - irb "my_variable = 10" - message "`my_variable` has a new value." - irb "my_variable" - result "10" -end - -step do - irb <<-IRB -apples = 5 -bananas = 10 + 5 -fruits = 2 + apples + bananas -bananas = fruits - apples - IRB - message "Variables are assigned a value using a single equals sign (=)." - message "The right side of the equals sign is evaluated, and the result is - assigned to the variable named on the left side of the equals." - end - -step do - message "You've created a lot of variables. Let's see the list." - irb "local_variables" - result "[:bananas, :fruits, :apples, :another_variable, :my_variable]" - message "Here Ruby gives you a list of variables you've defined in irb so - far. This might be useful for when you want to see what variable names are - already in use." - end -step do - message <<-CONTENT - The opposite of a variable is `constant` - a value that doesn't change. - Numbers, strings, nil, true, and false are constants. - Check out what happens if you assign a value to a constant." - CONTENT - irb <<-IRB - true = false - 1 = 1 - "a" = 1 - IRB - message "(Notice in the last example we put the a in quotation marks to make it a string.)" -end - -step do - message "There are some rules about what you can name a variable." - message <<-VARIABLE_NAMES -Try making variables with the following kinds of names names in irb: - -* all letters (like 'folders') - -* all numbers (like '2000') - -* an underscore (like 'first_name') - -* a dash (like 'last-name') - -* a number anywhere (like 'y2k') - -* a number at the start (like '101dalmations') - -* a number at the end (like 'starwars2') - -Which worked? Which didn't? - VARIABLE_NAMES -end - -step do - message "Variables can hold the result of a function." - irb 'shouting = "hey, you!".upcase' -end - -explanation do - message "Variables allow you to store data so you can refer to it by name - later. The data you store in variables will persist as long as your program - keeps running and vanish when it stops." - end - -next_step "datatypes" diff --git a/sites/en/ruby/what_is_ruby.step b/sites/en/ruby/what_is_ruby.step deleted file mode 100755 index 8d18fef92..000000000 --- a/sites/en/ruby/what_is_ruby.step +++ /dev/null @@ -1,23 +0,0 @@ -goals do - goal "Discuss what a programming language is" - goal "Discuss some of the characteristics of the Ruby language" -end - -explanation do - message <<-CONTENTS - Every application on your computer was written by somebody, from the operating system to your web browser. Every program was written in some kind of programming language. - - Programming languages come in all shapes and sizes. Some are optimized for the speed at which the computer will execute them, and some are optimized for the speed at which a human can program in them. - - Ruby was invented in the mid-1990s by Yukihiro Matsumoto -- Matz for short. Matz\' goals were to make programming faster and easier. \'Ruby is designed to make programmers happy.\' - - Ruby\'s popularity soared with the invention of the **Ruby on Rails** web framework, but Ruby is useful for many more things than just websites. - CONTENTS -end - -further_reading do - message '[Wikipedia\'s article on Ruby](https://en.wikipedia.org/wiki/Ruby_\(programming_language\))' - message 'If you know another programming language, see [Ruby From Other Languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages) for a comparison' -end - -next_step "command_line" diff --git a/sites/en/ruby/working_with_collections.step b/sites/en/ruby/working_with_collections.step deleted file mode 100644 index bfbb27808..000000000 --- a/sites/en/ruby/working_with_collections.step +++ /dev/null @@ -1,16 +0,0 @@ -message <<-CONTENTS -We usually work with multiple things - print a list of groceries, add several numbers, etc. - -We often repeat the same action on each thing in a group - frost a dozen cupcakes. - -Ruby provides a couple of containers, plus ways to perform an action on each item in a collection. - -CONTENTS - -goals do - goal "Hold multiple things with arrays and hashes" - goal "Loop over all the members of a group" - goal "Do a function to each member of a group" -end - -next_step 'arrays' \ No newline at end of file diff --git a/sites/en/workshop/beginners.mw b/sites/en/workshop/beginners.mw deleted file mode 100644 index cbb78cfa9..000000000 --- a/sites/en/workshop/beginners.mw +++ /dev/null @@ -1,22 +0,0 @@ -* What's a program? Operating system? -* What's a framework? -** something that makes it faster to build an application because it contains most of the things you would commonly write -* Workflow - how do you write a program? -** Learn about customer's requirements -> translate to "stories" -** Pick a story that seems doable and start writing code that does it -** Show your work to the customer, get feedback -** Based on feedback, adjust stories (customer's "up front" requirements vs. changes once they see something working) -** Once story is finished, go back to "pick a story"...keep going until you're done! (This is an example of looping!) -* alternate [[programming intro]] -* Basic programming structures - or, how to do the "start writing code" step -** variables - words that hold information -** types of information - text, numbers, collections -** operators - doing stuff with variables -** loops - doing the same action a bunch of times -** printing - to the screen, or to a file -* Writing a simple program -** opening the editor -** opening the command line -** adding two numbers together, storing in a variable -** printing variable to the screen -** save and run diff --git a/sites/en/workshop/closing.deck.md b/sites/en/workshop/closing.deck.md deleted file mode 100644 index 4721dbf88..000000000 --- a/sites/en/workshop/closing.deck.md +++ /dev/null @@ -1,35 +0,0 @@ - -# You have completed RailsBridge #38! -* Congratulations! - - - -# Please thank our awesome sponsor! -![EngineYard](img/ey_logo_rgb.png) - - -# Celebrate! -* After-party -* Conference Party - - -# What did we learn? -* Ruby as a language -* Rails as a framework -* MVC design pattern - - -# Resources: -* http://installfest.railsbridge.org/workshop/resources -* http://pinterest.com/pvnrtmol/ruby-and-rails-resources/ -* http://pinterest.com/eanakashima/learn-the-front-end/ -* Follow-up: -* Ruby Users of Minnesota — a fine group of Ruby enthusiasts from around the Twin Cities metro area, or pretty much wherever they feel like driving from. Our group meets on the last Monday of each month at 7 PM http://ruby.mn/ -* RailsBridge IRC channel -* DevChix E-mail list http://www.devchix.com/ -* Systers mailing list -* Want to organize a workshop? join railsbridge-workshops@googlegroups.com - - -# RIGHT NOW -* TAKE THIS SURVEY RIGHT NOW: http://bit.ly/workshop_survey diff --git a/sites/en/workshop/command_prompt.mw b/sites/en/workshop/command_prompt.mw deleted file mode 100644 index 29eccb110..000000000 --- a/sites/en/workshop/command_prompt.mw +++ /dev/null @@ -1,19 +0,0 @@ -There are several ways of opening a terminal window. You'll be using it often, so the best way is creating an shortcut icon on the Taskbar. - -== Opening a terminal == -=== Windows 7 === -* Click the Windows Icon. In the "Search programs and files" field, type: cmd and press the [enter] key - -[[File:img/Win7_search_programs.jpg]] - -== Creating a terminal shortcut icon on the Taskbar == -=== Windows 7 === -* Click: Windows Icon, "All Programs", "Accessories". Right click on "Terminal", click on "Pin to Taskbar". - -== Recommended setup for command-line windows == - -* Right-click on the menu bar and select "Properties" -* Under the Options tab, check the box for "QuickEdit Mode" (this will let you visually cut and paste) -* Under the Font tab, select Lucida Console from the font chooser box. This lets you view non-ascii characters. -* Under the Layout tab, adjust Window Size so the window spans the screen horizontally and takes up about half the window space vertically (this may require some trial and error). Increase Screen Buffer Size Height to 1000. -* Hit OK. In the dialog that comes up, select "Modify shortcut that started this window." diff --git a/sites/en/workshop/diagrams.mw b/sites/en/workshop/diagrams.mw deleted file mode 100644 index 3651c174a..000000000 --- a/sites/en/workshop/diagrams.mw +++ /dev/null @@ -1,66 +0,0 @@ -* Git Geography: http://github.com/alexch/mission/raw/master/git.png - -* MVC: http://github.com/alexch/mission/raw/master/mvc.png - -* MVC: https://www.railstutorial.org/book/demo_app#sec-mvc_in_action - -* REST: - - - - - - - - - - - - - - - - - - - - - - -
      DBHTTPRESTRailsNotes
      -GET -/topics/new -new -shows the page with the "new topic" form - -
      CreatePOST/topicscreatecreates a new topic in the database
      Read -GET -/topics -index -shows the list of all topics - -
      Read -GET -/topics/2 -show -shows only topic number 2 - -
      Read -GET -/topics/2/edit -edit -shows the page with the "edit topic 2" form - -
      Update -PUT -/topics/2 -update -changes topic number 2 - -
      Delete -DELETE -/topics/2 -destroy -deletes topic number 2 - -
      diff --git a/sites/en/workshop/foundational_skills.deck.md b/sites/en/workshop/foundational_skills.deck.md deleted file mode 100644 index 55b989954..000000000 --- a/sites/en/workshop/foundational_skills.deck.md +++ /dev/null @@ -1,118 +0,0 @@ - -# Foundational Programming Skills - -This presentation covers the basic skills required to be a programmer... - - ...that **don't** involve actually writing code. - - -# Files and Directories - -* The House/Rooms/Drawers Metaphor - * directories store files and keep everything in your ‘house’ organized - - -# The Command Line - - ls - cd - pwd - echo - touch - cat - mv - cp - rm - - -# Special Directories - -* Current directory - * `.` ("dot") -* Parent directory - * `..` ("dot dot") -* Home directory - * `~` ("tilde") - - -# More about directories - -* Explain where home and root are located in relation to all directories. -* Explain difference between absolute paths (starting with a /) and relative paths. - - -# Text Editing - -* text editor vs. word processor - * similarities and differences -* Have group open editor, create and save file with explanation of how and where files are stored. - * after change, go to command line and `cat` the file to see -* Explain file extensions and file types. - * File types tell the editor how to color the special words in each language. -* Explain difference between the buffer (in the editor’s memory) and the file (stored on disk). - * Emphasize the importance of saving the buffer to a file before trying to run it with ruby. - * "Save" makes things unsafe - - -# Compilers, Interpreters and Programming Languages - -* Programming language as an agreed set of rules about syntax for writing source code that is sent to the interpreter and translated into byte code. -* Explain that byte code is the binary that machines understand and use for executing instructions. -* Use metaphor that CPU is like a guy in a factory executing commands that it is handled, and the source code are those instructions. -* Explain differences between compiled vs. dynamic languages. -* Tie everything together by explaining that source code are instructions that are translated into language that machines understand and can execute. - - -# Memory, CPU, Hard Disk - -* Very briefly explain how a computer works and all the moving parts (literally) starting with hard drive, memory, and CPU. -* Give the group basic understanding of where the source code is stored and how and where it is executed. - - -# Operating System - - - - -
      - - - - - -
      - -* The OS is a program that runs other programs - * the term "multitasking" actually started with computers and migrated to common usage -* It also helps programs communicate with hardware (video, memory, disk, network...) - - -# Package Managers -* For installing and updating low-level programs -* Like Apple's "Software Update" for the command line - * or iTunes App Store -* Examples - * *Mac OS*: MacPorts, Homebrew - * *Linux*: apt-get, rpm - * *Ruby*: gem, bundler - * *Perl*: CPAN - * *JavaScript*: npm - - -# Version Control -* Definition -* Terminology - * "check out" - * "check in"/"commit" - * "diff" - * "merge" - - -# Version Control with git -* More Terminology - * "add" - * "push" - * "pull" -* Diagram - * ![git](img/git.png) -* diff --git a/sites/en/workshop/helpful_examples.mw b/sites/en/workshop/helpful_examples.mw deleted file mode 100644 index 5a90c3cbe..000000000 --- a/sites/en/workshop/helpful_examples.mw +++ /dev/null @@ -1,23 +0,0 @@ -The right example or diagram can go a long way toward helping a beginner grasp an abstract concept. Add examples, metaphors, similies, diagram, or approach to teaching concepts or terms here. - -= Classes and Methods = - -== Verbing a noun. == -
      > "word".upcase
      - => "WORD" 
      -
      -This follows the format "object.method". -Method is a verb, and object is our direct object (the thing the method is acting on). -So in this case, we are saying "please take 'word' and make it uppercase" - -== You can also use classes to retrieve characteristics of an object. == -
      > 1.class
      - => Fixnum 
      -So in this case, we are saying "hey 1, what is your class?" -To which it replies, "I'm a FixNum, of course!" - -= MVC = - -This image was really, really helpful to me as I was learning it: - -[[File:http://php-html.net/tutorials/wp-content/uploads/2009/08/mvc-collaboration.png]] diff --git a/sites/en/workshop/img/Win7_search_programs.jpg b/sites/en/workshop/img/Win7_search_programs.jpg deleted file mode 100644 index 6fd59511a..000000000 Binary files a/sites/en/workshop/img/Win7_search_programs.jpg and /dev/null differ diff --git a/sites/en/workshop/img/acrobat.jpg b/sites/en/workshop/img/acrobat.jpg deleted file mode 100644 index ad62627cb..000000000 Binary files a/sites/en/workshop/img/acrobat.jpg and /dev/null differ diff --git a/sites/en/workshop/img/agile.jpg b/sites/en/workshop/img/agile.jpg deleted file mode 100644 index 27a29fc41..000000000 Binary files a/sites/en/workshop/img/agile.jpg and /dev/null differ diff --git a/sites/en/workshop/img/cheatsheet.png b/sites/en/workshop/img/cheatsheet.png deleted file mode 100644 index 13f41ab9e..000000000 Binary files a/sites/en/workshop/img/cheatsheet.png and /dev/null differ diff --git a/sites/en/workshop/img/ey_logo_rgb.png b/sites/en/workshop/img/ey_logo_rgb.png deleted file mode 100644 index ff66b2536..000000000 Binary files a/sites/en/workshop/img/ey_logo_rgb.png and /dev/null differ diff --git a/sites/en/workshop/img/firefox.png b/sites/en/workshop/img/firefox.png deleted file mode 100644 index 36baae5eb..000000000 Binary files a/sites/en/workshop/img/firefox.png and /dev/null differ diff --git a/sites/en/workshop/img/git.png b/sites/en/workshop/img/git.png deleted file mode 100644 index 8563348a1..000000000 Binary files a/sites/en/workshop/img/git.png and /dev/null differ diff --git a/sites/en/workshop/img/git_bash.png b/sites/en/workshop/img/git_bash.png deleted file mode 100644 index 56a001e52..000000000 Binary files a/sites/en/workshop/img/git_bash.png and /dev/null differ diff --git a/sites/en/workshop/img/itunes.png b/sites/en/workshop/img/itunes.png deleted file mode 100644 index 21a532ff2..000000000 Binary files a/sites/en/workshop/img/itunes.png and /dev/null differ diff --git a/sites/en/workshop/img/linux_logo.gif b/sites/en/workshop/img/linux_logo.gif deleted file mode 100644 index a123e43fc..000000000 Binary files a/sites/en/workshop/img/linux_logo.gif and /dev/null differ diff --git a/sites/en/workshop/img/mac_terminal_sm.png b/sites/en/workshop/img/mac_terminal_sm.png deleted file mode 100644 index db27ec46e..000000000 Binary files a/sites/en/workshop/img/mac_terminal_sm.png and /dev/null differ diff --git a/sites/en/workshop/img/os_x_logo.jpg b/sites/en/workshop/img/os_x_logo.jpg deleted file mode 100644 index 162a72b52..000000000 Binary files a/sites/en/workshop/img/os_x_logo.jpg and /dev/null differ diff --git a/sites/en/workshop/img/rails_logo.jpg b/sites/en/workshop/img/rails_logo.jpg deleted file mode 100644 index a847b1933..000000000 Binary files a/sites/en/workshop/img/rails_logo.jpg and /dev/null differ diff --git a/sites/en/workshop/img/railsbridge_logo.png b/sites/en/workshop/img/railsbridge_logo.png deleted file mode 100644 index c578d3449..000000000 Binary files a/sites/en/workshop/img/railsbridge_logo.png and /dev/null differ diff --git a/sites/en/workshop/img/ruby-logo.jpg b/sites/en/workshop/img/ruby-logo.jpg deleted file mode 100644 index 2bf14edc8..000000000 Binary files a/sites/en/workshop/img/ruby-logo.jpg and /dev/null differ diff --git a/sites/en/workshop/img/rubygems.png b/sites/en/workshop/img/rubygems.png deleted file mode 100644 index 84547551a..000000000 Binary files a/sites/en/workshop/img/rubygems.png and /dev/null differ diff --git a/sites/en/workshop/img/windows_logo.gif b/sites/en/workshop/img/windows_logo.gif deleted file mode 100644 index 8347d58ec..000000000 Binary files a/sites/en/workshop/img/windows_logo.gif and /dev/null differ diff --git a/sites/en/workshop/img/wordpress.jpg b/sites/en/workshop/img/wordpress.jpg deleted file mode 100644 index c9a41fb23..000000000 Binary files a/sites/en/workshop/img/wordpress.jpg and /dev/null differ diff --git a/sites/en/workshop/more_teacher_training.deck.md b/sites/en/workshop/more_teacher_training.deck.md deleted file mode 100644 index 4eb95088a..000000000 --- a/sites/en/workshop/more_teacher_training.deck.md +++ /dev/null @@ -1,251 +0,0 @@ -# RailsBridge Teacher Training - -# What is this? - -You're probably at a teacher training for RailsBridge. - -This slide deck is a tool to facilitate conversations about teaching best practices and challenges, specifically for RailsBridge workshops. - -It helps to have a whiteboard or those giant sticky notes for the discussions if possible. - -### Discussion is key! -### Don't let the presenter(s) do all the talking! - -# Why RailsBridge? -We're making tech more diverse and more welcoming! - -### How? -* We throw super-welcoming, fun, free workshops. -* We provide hella networking opportunities for students and volunteers. -* We help our volunteers become more empathetic and better communicators. - -# Introductions -### Who are you? -* What's your name? -* Have you been to a RailsBridge before? How many? -* What do you do for a living? Care to share who you work for? -* What's your favorite structure in the Bay Area? -* Alternate silly questions: - * What's your favorite animal? - * If you could only eat one food for the rest of your life, what would it be? - -# What's a RailsBridge? -Raise your hand if you've been to a workshop before! - -### RailsBridge Fun Facts -* Founded in 2009 as a variety of initiatives, including Rails Mentors, Rails Bug Smashes, and the Open Workshop Project. -* The workshops project was led by Sarah Allen and Sarah Mei. -* Its goal: make the Rails community more diverse and more welcoming to newcomers. -* Workshops are happening all over the world! - -# How does a workshop work? -There are a few different RailsBridge curricula: - -* Intro to Rails (a.k.a. "Suggestotron") -* Job Board (no scaffolds) -* Message Board (doesn't tell you what to type) -* Intro to Ruby -* Front End (HTML, CSS, and a tiny bit of JavaScript). - -First, we get all the necessary technologies onto the students' computers (the Installfest). - -The next day we break into small groups and work through the curriculum. - -# Typical RailsBridge Schedule -* Friday, 6-10pm-ish: Installfest: installing software over pizza & beer (no formal presentations) - - _n.b.: the Front End workshop doesn't usually have an Installfest._ - -* Saturday's schedule, often: - * 9-9:30am: Check-in, coffee, bagels - * 9:30-10am: Opening presentation - * 10am-12:30pm: Class! - * 12:30-1:30pm: Lunch - * 1:30pm-4:30pm: Class! (with a break sometime mid-afternoon) - * 4:30-5:00pm: Closing presentation & retros - * 5:00pm-late: After-party - -# Is RailsBridge Open Source? - -### WHY YES, THANK YOU FOR ASKING! -### RAILSBRIDGE IS VERY OPEN SOURCE! - -All the materials you're using were created by volunteers, and are on GitHub for forking and editing and using! - -If you see something that could be better, make a pull request. Pull requests are the lifeblood of RailsBridge. - -If you don't know how to make one, we'll help! - -# How to make your class awesome -We've made three quasi-arbitrary categories of ways to make your class awesome: -### We want our students to feel: -* socially comfortable -* technically capable -* like you are approachable and can help solve their problems - -# Discussion: Social Comfort - -#### Imagine: -* You're trying to do something difficult -* You're in a group of strangers, many of whom know how to do it better than you -* You've tried before but got lost or bored or confused -* You don't feel like you can articulate your thoughts and questions -* You don't know the right names for anything - -#### When was the last time you felt this way? - -#### How can we help make this easier? -#### How can you help people feel socially comfortable? - - -# Social Comfort (Ideas) - -#### Introductions -* Include name, profession, why are you here / goals for today's class, and something silly. -* Don't rush, even if you have a big class. -* If someone joins the class late, ask them to introduce themselves. - -#### Icebreakers -* Name games! Admit up front that most people are bad at learning new names. -* Get people talking. The more comfortable they are at talking, the more likely they'll speak up when they don't understand something, or to answer someone else's question. - -# Social Comfort (More Ideas) -#### Try to suppress your (understandable) culturally-influenced sexism -* Don't hit on people. No sexual advances. None. Even at the after-party. -* Don't make sexist jokes. Or racist, classist, or ableist jokes. Call people out if they do. A simple "That's not funny" and moving on quickly with the conversation will often suffice. -* Don't make gender-based generalizations ("Women are better at X, because ...") -* Don't make references to people's bodies or state your opinion of them. -* Don't use slurs. - -# Discussion: Technical Capability -### How can you help people feel technically capable? -### What kinds of insecurities might your student have? -### How can you bolster their confidence? - -# Technical Capability (Ideas) -#### Explain that: -* Even professional developers are constantly learning new technologies, so being confused is normal. -* Initial code is often terrible: don't feel bad, just refactor! -* Mistakes == Learning! - -#### Dealing with technical concepts: -* Define technical terms! Several times! -* Assume anyone you're teaching has zero knowledge but infinite intelligence. -* Remember people's professional and code backgrounds (QA, DBA, C++, Java, JS) and relate where possible. If they are a cook, try a cooking analogy. - -# Technical Capability (More Ideas) -#### Encourage collaboration and interaction -* Explicitly encourage students to try to answer each other's questions. -* If a question is asked, ask if anyone in the class thinks they can explain. -* Be especially encouraging of the first few questions, to try to get things rolling. -* Good responses to questions: "I'm glad you asked!" or "I actually wondered that, too." or "Great question!" - -#### Be Super Positive, Always -* Students have diverse backgrounds. Appreciate this fact. -* If they aren't getting a concept, avoid anything that might shame them. -* Don't be surprised when someone hasn't heard of something before. -* Don't grab anyone's keyboard. Avoid taking over unless you think it's *really* necessary. Ask before you do. "Mind if I drive for a sec?" But really, don't. - -# Technical Capability (Even More Ideas) -#### Walk the Middle Path -* Don't go too deep for your class level, but also, don't gloss over things. -* When trying to be accurate, it's easy to go down a rabbit hole of specificity. Avoid. -* Work with the TAs to make sure no one goes down that rabbit hole. Accountability! -* Explain the big picture of a command *before* they type it in. - * i.e., before typing the command to deploy to Heroku, explain the difference between localhost and Heroku. - -# Discussion (Do you know what's up?) -#### How can you help people feel like you know what's going on? -#### What are things you can do to help the students trust you? -#### What are some things to avoid? - -# Know What's Up (Ideas) -#### Know what's going on -* Cover logistics at the beginning of class - * Planned breaks, lunch time - * Remind students that there is a closing presentation at the end - * Make sure they know where the bathroom is - * Encourage them to attend the after-party - -#### Establish a few ground rules -* Questions are always welcome, even if the student thinks it might be dumb. -* Explain that if someone has trouble (e.g., not getting the expected output), the TAs will help troubleshoot. -* If anyone wants to switch classes, tell them they should feel TOTALLY COMFORTABLE switching at any point. - -# Know What's Up (More Ideas) -#### Don't be afraid to: -* Call on people! By name! -* Correct people if they're wrong. Be polite and encouraging. For instance: - * "Well, this might work better and this is why." - * "Can you explain how you came to that conclusion?" - * "Does anyone have a different answer?" -* Ask yourself questions and answer them. - -# Know What's Up (Even More Ideas) -#### Pace yourself! -* Don't go too fast. You will probably go too fast. Check in occasionally to ensure everyone is still with you. -* You can say the same thing THREE TIMES and it will not be boring yet. -* When you ask a question, wait TEN WHOLE SECONDS before saying anything else. People need time to think. -* Don't let the most advanced students dictate the pacing or answer all the questions. - -# Discussion: Challenges -Talk about what problems you might anticipate, and what to do about them. - -#### Some issues: -* Student is in the wrong class level -* Student is disruptive -* Student is disengaged -* TA is not helping - -# What's a TA? - -* At RailsBridge, a TA is a volunteer who isn't leading the class. -* If you're volunteering at your first RailsBridge workshop, you should probably be a TA. -* Sometimes they are the technical experts (rather than the teacher), sometimes not. -* TAs often explain specific concepts for the class or teach a couple of sections to give the teacher a break from talking. - -# Discussion: TAs -#### TAs: How can you best utilize the AWESOME POWER that is a TA? - -# TAs (Some Ideas) -* TAs can ask questions to encourage students to speak up. -* Ask your TA to explain a concept; they may be more technically advanced than you! -* TAs can help people who get lost. -* Co-teaching is also an option if you feel like you can tag-team. There doesn't have to be a hierarchy. -* If someone falls behind, the TA can take them out of the room to do some 1-on-1, if there's another TA in the room. - -# Discussion: Comprehension -#### How can you tell if they understand the words you're saying? -#### What are good questions to ask to check comprehension? -#### What did your favorite teachers do to gauge understanding? - -# Student Comprehension (Some Ideas) -* Pay attention to body language. -* People ask questions most often when they are actively processing material. If they aren't, it might be that the material is too easy or hard. Try to figure out which it is! - -#### Calling on people -* Calling on people makes the class more interactive and engaging, and less lecture-y. -* Don't always ask questions to the whole class: call on individuals by name. -* Consider breaking the class into two teams and addressing questions to teams. -* Ask people what they expect a command to produce BEFORE you hit enter. -* Ask "How would you do \#\{this\}?" or "If I wanted to do \#\{that\}, what would I do?" - -# Installfest! -#### Keep in mind: -* There will be people with _all_ kinds of computers. -* Even though Windows is not an ideal Rails development environment, we're here to encourage people and meet them wherever they are right now. -* Do NOT say bad things about Windows, even if it's frustrating. -* If you're not sure about something, grab another volunteer. - -# Very Important, Very Practical Things -#### Where to find the curriculum: http://docs.railsbridge.org - -You need to read the curriculum through, beginning to end, before teaching it. - -First workshop? Be a TA! - -#### Where to submit pull requests: https://github.com/railsbridge/docs - -#### How to submit pull requests: http://railsbridge.github.io/bridge_troll/ - -We need your help! Thank you!!! diff --git a/sites/en/workshop/noobie-outline.txt b/sites/en/workshop/noobie-outline.txt deleted file mode 100644 index 12faef368..000000000 --- a/sites/en/workshop/noobie-outline.txt +++ /dev/null @@ -1,53 +0,0 @@ -RailsBridge Introductory Curriculum for Non-Programmers - -Target Audience: Students who have not exposure to the command line and/or programming (and may be fuzzy on how the file system works) - -Emphasis: -Hands-on group exercises led by instructor where code is reviewed line-by-line. -TA’s help trouble-shoot students who get stuck while instructor maintains pace of the sessions. -Focus on learning over finishing course material and give students the ‘ah-ha’ where they realize programming is not hard. -Use simple language with metaphors to demonstrate core programming principles. -Prompt students for feedback and no question is too simple or stupid. - -Topics: -File Directories: -Use house / rooms / drawers metaphor for how directories store files and keep everything in your ‘house’ organized. -Review ./ and ~/ references to self and root directories. Explain where home and root are located in relation to all directories. -Explain difference between absolute paths (starting with a /) and relative paths. -.. is the relative path the the parent directory. -Command Line Basics:: pwd, ls, cd, touch, mv, cp, rm, .. (parent directory) -Text Editing: -Explain differences between text editor vs. word processor. -Have group open editor, create and save file with explanation of how and where files are stored. -Explain file extensions and file types. File types tell the editor how to color the special words in each language. -Explain difference between the buffer (in the editor’s memory) and the file (stored on disk). Emphasize the importance of saving the buffer to a file before trying to run it with ruby. -Compilers, Interpreters and Programming Languages: -Use metaphor of programming language as an agreed set of rules about syntax for writing source code that is sent to the interpreter and translated into byte code. -Explain that byte code is the binary that machines understand and use for executing instructions. -Use metaphor that CPU is like a guy in a factory executing commands that it is handled, and the source code are those instructions. -Explain differences between compiled vs. dynamic languages. -Tie everything together by explaining that source code are instructions that are translated into language that machines understand and can execute. -Memory, CPU,Hard Disk:: -Very briefly explain how a computer works and all the moving parts (literally) starting with hard drive, memory, and CPU. -Give the group basic understanding of where the source code is stored and how and where it is executed. ---- -Hello World -Write hello world. Run it. -Extend it to do “hello what’s your name”, “hello, bob!” puts and gets. -Introduce chop (to remove the newline between “bob” and “!”). -Objects, Methods, Variables and Strings: -Relate methods and variables to algebra and how methods are like functions that are fed with variables and parameters. -Review variable assignment. -Explain what objects are, how they are created and the dot operator that allows methods to be called on them. -Quickly review garbage collection and how objects are stored in memory. -Explain ‘method calls’. -Explain to group the important of strings and review string operations. Have group work with strings in IRB. -IRB Console: -Have group open IRB console and create objects, method calls and variable assignments. -Tie in lecture above on Objects, Methods, Variables with exercises in IRB that allow students to see results line-by-line. -Have group query classes for their methods in IRB. -HTTP: -Lead group exercise in using telnet to query Wikipedia, make GET request and view response in command line, then compare to view source of same page in browser. -Sinatra Application -Lead group exercise in writing Sinatra application and run it locally. “Hello, Web!” -Extend to add “the time is Sun Mar 27 09:44:09 PDT 2011” using `date`. \ No newline at end of file diff --git a/sites/en/workshop/resources.md b/sites/en/workshop/resources.md deleted file mode 100644 index 467553b29..000000000 --- a/sites/en/workshop/resources.md +++ /dev/null @@ -1,53 +0,0 @@ -### Learning Ruby -* [TryRuby](http://tryruby.org/) a browser-based interactive tutorial in Ruby -* ["Learning to Program" by Chris Pine](http://www.pragprog.com/titles/ltp2/learn-to-program-2nd-edition) - a beginner's programming book with lots of Ruby exercises. (earlier version [online](http://pine.fm/LearnToProgram)) -* [Why's Poignant Guide](http://mislav.uniqpath.com/poignant-guide/book/chapter-1.html) -* [Hackety Hack](http://hackety-hack.com/) a fun way for beginners to learn Ruby. -* [Ruby Koans](http://rubykoans.com/) - a self-guided journey through topics in Ruby for beginners and experts alike -* [Test-First Teaching](http://testfirst.org) - click on 'Learn Ruby' -* [Ruby Warrior](https://github.com/ryanb/ruby-warrior) - write and refine some Ruby code to get your warrior to the top of a hazardous tower -* [Ruby Quiz](http://www.rubyquiz.com) - a guided tour through the world of possibility; use your Ruby to build simple apps, games, and solve problems -* [Why's Poignant Guide to Ruby](http://mislav.uniqpath.com/poignant-guide/book/chapter-2.html) - A whimsical comic book that teaches you Ruby. Legendary in the community. -* [Learn Ruby the Hard Way](http://ruby.learncodethehardway.org/) It's not actually hard. A great place to start if you're new to programming and want to learn with hands-on examples. -* [PDX tech workshop](http://github.com/caylee-hogg/pdx-ruby-course) This are the slides from the ruby/rails workshop organized in Portland, OR by [PDXtech](http://pdxtechworkshops.org/) - -### Learn about Rails - -* [Rails Guides](http://guides.rubyonrails.org/) - the official how-to articles for Rails -* [Rails API](http://railsapi.com) - online documentation -* [Rails for Zombies](http://railsforzombies.org/) - a series of videos and browser-based Rails exercises -* [Rails Tutorial](http://ruby.railstutorial.org/) - a tutorial that leads you through writing a Rails messaging app - -### Watch screen casts - -* [RailsCasts](http://railscasts.com) (also available as [blog posts](http://asciicasts.com/)) -* [PeepCode](http://peepcode.com) - -### Classes & events in San Francisco - -* [San Francisco Ruby Meetups (we'd love to have you when you're in the area!)](http://www.meetup.com/sfruby/) -* [RailsBridge Workshops organizing team](http://groups.google.com/group/railsbridge-workshops) -* [Women Who Code meetup](http://www.meetup.com/Women-Who-Code-SF/) (monthly hack nights & speakers) - -### Online - -* [RailsBridge](http://railsbridge.org) -* [DevChix](http://www.devchix.com) -blog and mailing list for women developers -* [Stack Overflow](http://stackoverflow.com/) -for answers to programming questions -* [Apprenticeship Patterns](http://apprenticeship-patterns.labs.oreilly.com/) -advice for aspiring programmers - -### Get experience - -* Just do it. Write and publish your own Rails app. -* Volunteer at the next workshop -* Volunteer on a RailsBridge Builders project -* Come to a hack session - -### Meetups and User Groups outside of San Francisco - -* Boulder Ruby (monthly events): http://boulderruby.org/ -* DeRailed - Denver Rails UG: http://groups.google.com/group/derailed -* Mountain.rb (Boulder, Colorado) http://mountainrb.com -* Chicago Ruby (beginners welcome!) http://www.meetup.com/ChicagoRuby/ - -Check for Ruby and Rails meetups anywhere at [Ruby in Person](http://www.rubyinperson.com/) diff --git a/sites/en/workshop/ruby_for_beginners.deck.md b/sites/en/workshop/ruby_for_beginners.deck.md deleted file mode 100644 index b018e4624..000000000 --- a/sites/en/workshop/ruby_for_beginners.deck.md +++ /dev/null @@ -1,688 +0,0 @@ -!SLIDE subsection -# Ruby Programming for Beginners - - -# What we'll cover - -* Programming: languages & applications -* What is Ruby? -* Ruby's common objects -* Ruby syntax basics -* Object oriented programming concepts -* Passing code to a Ruby interpreter - -!SLIDE -# Programming - -!SLIDE -# Operating System (OS) -Talk to a computer's `hardware`. - - - - -
      - - - - - -
      - -!SLIDE -# Application -The `software`. It sends `input` (`commands`, `data`, etc) to the operating system and receive `output` after the operating system has acted on it. - -![](img/acrobat.jpg) -![](img/firefox.png) -![](img/itunes.png) -![](img/wordpress.jpg) - -!SLIDE -# Language -A set of code that can be used to create an application. - -* Ruby -* Python -* Perl -* Java -* C++ - -Many others. - -Q: How is a computer language similar to a human language, like English or Spanish? How is it different? - -# Library -A collection of reusable code to accomplish a generic activity. - -!SLIDE -# Framework -Collection of reusable code to facilitate development of a particular product or solution. - -!SLIDE -## Ruby vs. Rails - -### Ruby is a language - - -### Gems are Ruby libraries - - -### Rails is a framework - - - -!SLIDE -## Ruby vs. Rails -* Rails is written in Ruby language. -* Rails contains many Ruby gems. -* Rails is a framework. -* Rails' purpose is to build websites. - -The rest of this tutorial isn't about Rails. -You're learning how to do _any_ kind of programming with Ruby. - - -# Ruby Philosophy - - -``` -I believe people want to express themselves when they program. - -They don't want to fight with the language. - -Programming languages must feel natural to programmers. - -I tried to make people enjoy programming and concentrate on the fun and creative part of programming when they use Ruby. -``` - -- [Matz](http://linuxdevcenter.com/pub/a/linux/2001/11/29/ruby.html) (Yukihiro Matsumoto), Ruby creator - - -!SLIDE bullets -# Ruby is a scripting language - -* Scripting languages: - * Don't require a compiler. - * Have an interpreter _(more on that later...)_ - * Run "on the fly" - * Easy to change frequently - -Python, Perl, and JavaScript are scripting languages too. - -Java and C++ are examples of compiled languages. - - -!SLIDE centereverything - - -!SLIDE subsection - -# Let's start coding! - -!SLIDE bullets -# Open Your Terminal -You may also hear it called "command Line", "console", "shell", or "Bash" - -* Windows: `git bash` ![](img/git_bash.png) - -* Mac OS X & Ubuntu: `Terminal` ![](img/mac_terminal_sm.png) - - -!SLIDE -# Prompt - -* Terminals show a line of text when you login & after a command finishes -* It's called the `prompt`, and customarily ends with a dollar sign - -Whenever instructions start with `"$ "`, type the rest of the line into terminal. - -Let's give the terminal a `command`, to open Interactive Ruby (IRB) - -```bash - $ irb -``` - - -!SLIDE commandline -# irb: Interactive Ruby - -IRB has its own prompt, which customarily ends with `>` - -``` - $ irb - > -``` - -You can use `Control-C` to exit IRB any time. -Or type `exit` on its own line. - -```ruby - > exit - $ -``` - -Now you're back to the terminal's prompt. - - Windows Users! Some people have experienced trouble with backspace, delete, and arrow keys working properly in irb - what a pain! If you run into this problem, use this command instead to launch irb. - - $ irb --noreadline - -!SLIDE - -## Variables -### A variable holds information. -* We give it a name so we can refer to it -* The info it holds can be changed - -``` - $ irb - > my_variable = 5 - => 5 - > another_variable = "hi" - => "hi" - > my_variable = 10 - => 10 -``` - -What is happening on the lines beginning with `=>` ? - -* Setting a variable equal to something is called "assignment." In the above examples, we are assigning my_variable to 5 and my_other_variable to "hi." -* What types of information can we hold in a variable? (see next slide for answers) - -!SLIDE -## Variable -### Variable Assignment - -Variables are assigned using a single equals sign (`=`). - -The *right* side of the equals sign is evaluated first, then the value is assigned to the variable named on the *left* side of the equals. - -```ruby - apples = 5 - bananas = 10 + 5 - fruits = 2 + apples + bananas - bananas = fruits - apples -``` - -What happened on each line? Is it what you expected? - - - -What could you do to see each's `return value` for confirmation? - - -!SLIDE !bullets -## Variable -### Variable Naming - -Create a variable whose name has: - -* all letters (like 'folders') - -* all numbers like '2000' - -* an underscore (like `first_name`) - -* a dash (like 'last-name') - -* a number anywhere (like `y2k`) - -* a number at the start (like '101dalmatians') - -* a number at the end (like 'starwars2') - -What did you learn? - - -!SLIDE bullets -# Common types of information -* Variables can hold many types of information, including: - * String - * Number - * Collections - * Booleans - -* Don't know what these are? Don't worry! We're about to find out! - -!SLIDE bullets -## String - -A string is text. It must be wrapped in a matched pair of quotation marks. - -```ruby - $ irb - > 'Single quotes work' - => "Single quotes work" - > "Double quotes work" - => "Double quotes work" - > "Start and end have to match' - "> -``` - -What is happening on the last two lines? How would you solve it? - - -### exercise -* Create variables called first_name, last_name, and favorite_color. -* Assign the variables to strings. -* Can you print out a sentence that reads "Hi, my name is (first name) (last name) and my favorite color is (favorite color)." with these variables? - * Hint: you can use a "+" to add strings together. - - -!SLIDE -## Numbers -* Numbers without decimal points are called **integers** and numbers with decimal points are called **floats**. -* Examples of integers: - * 0 - * -105 - * 898989898 - * 2 -* Examples of floats: - * 0.0 - * -105.56 - * 0.33 - * 0.00004 -* You can perform operations on both types of numbers with these characters: +, -, /, * - -### exercises -* Try dividing an integer by an integer. Try dividing an integer by a float. How are the results different? -* Create two integer variables called num1 and num2 and assign them your favorite numbers. -* Next, compute the sum, difference, quotient, and product of these two numbers and assign these values to variables called sum, difference, quotient, and product, respectively. - -!SLIDE -## Collection -### Collection types: Array, Hash - - * In the following slides, we will cover the following topics: - * Definition of an Array - * Array syntax - * Array indexing - * Array methods - * Definition of a hash - * Hash syntax - * Hash indexing - -!SLIDE -## Collection -### Array -An array is a list. - -Each array must be surrounded by `square braces` aka `square brackets`. A comma separates each `member`. - - @@@ Ruby - > fruits = ["kiwi", "strawberry", "plum"] - => ["kiwi", "strawberry", "plum"] - -### exercises -* Make your own array and name it grocery_list. -* Include at least 5 items from your grocery list in the array. - -!SLIDE -## Collection -### Array -#### Indexing - -Members are stored in order. Each can be accessed by its `index`. Ruby starts counting at _zero_. - - @@@ Ruby - > fruits[0] - => "kiwi" - > fruits[1] - => "strawberry" - > fruits[2] - => "plum" - -### exercises -* Still have your grocery_list array? Good, because we're going to use it in this exercise. -* What is at index zero in your grocery_list array? How about index 5? Guess the answers and then use the syntax in the examples above (eg: fruits[0]) to see if your guesses were right. - -!SLIDE -## Collection -### Hash -In a `hash` we can refer to a member by a keyword instead of a number. Each member is a pair: - -* *Key*: address of the hash member - -* *Value*: variable contained by the member, and located by key name - -A hash may also be known as a `dictionary`, `associative array`, or `map`. - - -!SLIDE -## Collection -### Hash -#### Hash Syntax - -A hash is surrounded by `curly braces` aka `curly brackets`. A comma separates each member pair. A key uses `=>` (the `rocket`) to point to its value. - - @@@ Ruby - > states = {"CA" => "California", - "DE" => "Delaware"} - => {"CA"=>"California", "DE"=>"Delaware"} - -In real life, what lists do we make in key/value pairs? - - -### exercises -* Define a Hash variable called my_info which has the following keys: - * "first_name" - * "last_name" - * "hometown" - * "favorite_food" - -!SLIDE -## Collection -### Hash -#### Hash Indexing - -Member pairs can be accessed by their key. So each hash key has to be unique. - -Values don't have to be unique. - - @@@ Ruby - > states["CA"] - => "California" - -### exercises -* Add the key "good_food" to your my_info hash and give it the same value as your favorite_food key. What happens? -* Add a second "favorite_food" key to your my_info hash. What happens when you print out the has hash again? Why? - - -!SLIDE -## Methods - -### things that do stuff. - -* "If objects (like strings, integers, and floats) are the nouns in the Ruby language, then methods are like the verbs." - Chris Pine's "Learn to Program" -* Methods are called (used) with a "." - * Example: 5.to_s (to_s is the method) -* As it turns out, 5 + 5 is really just a shortcut way of writing 5.+ 5. -* Each data type (string, integer, float) has a set of built in methods. You can see all of the string methods here: http://ruby-doc.org/core-1.9.3/String.html (there are tons - don't worry about memorizing them, just good to know where you can go to find out more) - -### exercises -* Create a String variable called old_string and assign it the value "Ruby is cool" -* Use String methods to modify the old_string variable so that it is now "LOOC SI YBUR" and assign this to another variable called new_string. - * Hint: look at the string methods "upcase" and "reverse" - -!SLIDE -## Boolean - -A boolean is one of only two possible values: `true` or `false`. - -``` - > 1 + 1 == 2 - => true - > 1 + 1 == 0 - => false -``` - -( `==` means "is equal to". _More on that later._) - -### exercises -* Create a variable named favorite_color and assign it to your favorite color. -* Create a variable named not_favorite_color and assign it to a different color. -* Test to see if these variables are equal. - -!SLIDE -## Operators - -### Do stuff with objects - -``` - > my_variable + 2 - => 7 - > my_variable * 3 - => 15 -``` -``` - > my_fruits = fruits + ["lychee"] - => ["kiwi", "strawberry", "plum", "lychee"] - > my_fruits = my_fruits - ["plum"] - => ["kiwi", "strawberry", "lychee"] -``` - -### exercises - -* Create an array called "vegetables" than contains 3 vegetables you like and 1 vegetable you don't like. -* Using the vegetables array, create an array called "my_vegetables" that contains only the vegetables you like. -* Extra: can you use the first two arrays to create a third array called "your_vegetables" that only contains the vegetable you don't like? - -!SLIDE -## Loop -### Does something repeatedly - -``` - > fruits.each do |fruit| - ?> puts fruit - > end - kiwi - strawberry - plum - => ["kiwi", "strawberry", "plum"] -``` -On the second line, what does `?>` indicate? - -### exercises -* Create an array of 4 places you would like to visit. -* Print out each of these places using a loop. - * Example: - -``` -"I would like to visit Barcelona" -"I would like to visit Antigua" -"I would like to visit Alaska" -"I would like to visit New Orleans" -``` - -!SLIDE -## Conditional - -### Do something only if a condition is true - -``` - > fruits.each do |fruit| - ?> puts fruit if fruit == "plum" - > end - plum - => ["kiwi", "strawberry", "plum"] -``` - -### exercises -* Create an array called "group" that contains the names of some of the people in your Railsbridge group. Make sure you include your own name. -* Using your group array, create a conditional that prints "My Name is (your name)" for your name only. - -!SLIDE -# Running Your Code - -!SLIDE subsection -# Interpreter - -Ruby is an interpreted language. Its code can't run by the computer directly. It first must go through a Ruby interpreter. - -The most common interpreter is Matz's Ruby Interpreter ("MRI"). There are many others. - -There are various ways to run code through a Ruby interpreter. We were using IRB earlier and now we will use a file. - -!SLIDE -## Running code from a file -### Create the file - -* Why use a file? What's different from, say, irb? - -Note which folder your terminal is currently in, this is your `working directory` - -In your text editor, create a file named `my_program.rb` inside your working directory. - - @@@ Ruby - class Sample - def hello - puts "Hello World!" - end - end - - s = Sample.new - s.hello - -!SLIDE commandline -## Passing code from a file -### Run the saved code - -``` - $ ruby my_program.rb - Hello World! -``` - - -!SLIDE commandline -## Passing code from a file -### We can even load that file's code into IRB! - -```bash - $ irb - > load 'my_program.rb' - > second_time=Sample.new - > second_time.hello -``` - -When might it be useful to do this? - - -!SLIDE subsection -# Your Own Command Line Program - -!SLIDE bullets -# Hello World - - -`hello.rb` - - @@@ Ruby - puts "Hello, World!" - -!SLIDE bullets -# Arguments (ARGV) - -`hello.rb` - - @@@ Ruby - puts "Hello, #{ARGV.first}!" - -`terminal` - -``` -$ ruby hello.rb Alice -Hello, Alice! -``` - -!SLIDE bullets -# Conditionals - -`hello.rb` - - @@@ Ruby - if ARGV.empty? - puts "Hello, World!" - else - puts "Hello, #{ARGV.first}!" - end - -`terminal` - - $ ruby hello.rb - Hello, World! - $ ruby hello.rb Alice - Hello, Alice! - -!SLIDE -# Object Oriented Programming (OOP) - -!SLIDE subsection -## Ruby is very object oriented -### Nearly everything in Ruby is an object. - - -!SLIDE -## Class -Describes the generic characteristics of a single _type_ of object. - -What things of this type _are_. - -e.g. Dog, Vehicle, Baby - - -!SLIDE -## Method -Defines _behavioral_ characteristic. - -What the things of the class's type _do_. - -e.g. Chase, Drive, Talk - - -!SLIDE -## Variable -Defines _attribute_ characteristic. - -What things of the class's type _have_. - -e.g. Breed, Model Year, Favorite Ice Cream - - -!SLIDE -## Instance -A specific incarnation of the class. - -e.g. Rin Tin Tin, garbage truck, the neighbor's kid - - - - -!SLIDE -# Let's Create Projects! - -!SLIDE -## Project 1: -### [Personal Chef Lab](http://tutorials.jumpstartlab.com/projects/ruby_in_100_minutes.html) -_(start at "4. Objects, Attributes, and Methods")_ - -Topics: - -* Commandline program. Practice in Ruby syntax and OOP concepts, and creating commandline programs. - -* Explore strings: concatenation, manipulation, interpolation, coersion. - -* Symbols, nil, basic math operators, blocks, method chaining, passing parameters to methods, iteration, branching, conditionals & conditional looping. - -!SLIDE -## Project 2: -### [Encryptor Lab](http://tutorials.jumpstartlab.com/projects/encryptor.html) - -Topics: - -* Commandline program. Reinforce skills learned in Personal Chef. - -* Explore how to manipulate arrays, do more elaborate strings manipulations, refactor code, take advantage of character mapping, and access the filesystem from within code. - - -!SLIDE -## Project 3: -### [Event Manager Lab](http://tutorials.jumpstartlab.com/projects/eventmanager.html) - -Topics: - -* Commandline program. Reusing others code & data, refactoring your own code & cleaning up data, writing custom code to solve requirements. - -* Gems, `initialize` method, parameters, file input/output, processing/sanitizing data, looping, conditional branching, using file-based data storage (CSV, XML, JSON), accessing an external API, nils, DRY principle, constants, sort_by, more string manipulations. - - -!SLIDE -## Project 4: -### Testing & More - -A follow-up to EventManager focusing more on Ruby object decomposition and working with Command Line Interfaces and program control flow. - -4. [Testing](http://tutorials.jumpstartlab.com/topics/internal_testing/rspec_and_bdd.html) Topics: TDD, BDD, Rspec -_(stop at "Exceptions")_ -4. [Event Reporter Lab](http://tutorials.jumpstartlab.com/projects/event_reporter.html) Topics: Object decomposition, working with Command Line Interfaces, and program control flow. Continues project created in Event Manager lab. - -6. [Rspec](http://tutorials.jumpstartlab.com/topics/internal_testing/rspec_practices.html ) diff --git a/sites/en/workshop/ruby_for_programmers.deck.md b/sites/en/workshop/ruby_for_programmers.deck.md deleted file mode 100644 index 2cef6f030..000000000 --- a/sites/en/workshop/ruby_for_programmers.deck.md +++ /dev/null @@ -1,290 +0,0 @@ -!SLIDE subsection -# Introduction to Ruby for Programmers - - - -This section is intended as a brief, lightweight overview of the Ruby language; following sections will cover all these topics in much more detail. Students are encouraged to ask questions, but instructors are encouraged to answer, "We'll cover that later." - -(Originally based upon [Ruby Quickstart for Refugees](https://gist.github.com/190567) but improved by many.) - -!SLIDE - -# Ruby vs. Rails - -### Ruby is a Language - - -### Rails is a Framework - - -### Rails is written in Ruby - - -# Ruby Philosophy - -Q: Did you have a guiding philosophy when designing Ruby? - -A: Yes, it's called the "principle of least surprise." - -I believe people want to express themselves when they program. - -They don't want to fight with the language. - -Programming languages must feel natural to programmers. - -I tried to make people enjoy programming and concentrate on the fun and creative part of programming when they use Ruby. - -  - [Matz](http://linuxdevcenter.com/pub/a/linux/2001/11/29/ruby.html) (Yukihiro Matsumoto), Ruby creator - -!SLIDE incremental -# Ruby Philosophy, Applied - -* Ruby has a *humane interface* - * many ways to do things -* Ruby favors readability and variety over concision and perfection -* sometimes makes code hard to understand (but usually makes it easier) -* contrast to *minimal interface* - * one (or a few) "right" ways to do things - * Python has a minimal philosophy - -# Many Rubies - -* Ruby 1.0 released in 1996 - * Fully Open Source -* Many implementations - * MRI - * REE - * Kiji - * JRuby - * Rubinius - * MagLev - * MacRuby - * IronRuby - -# Versions common today - -* MRI 1.8.7 -* MRI 1.9.2 -* JRuby - -# Ruby Language Overview - -* Dynamically typed -* Interpreted -* Can be modified at runtime -* Object oriented -* Blocks / lambdas / closures -* Perl-like regular expressions -* Closely tied to shell & OS - -# IRB: Interactive RuBy - -Type `irb` in the terminal to launch IRB - - @@@ ruby - >> 4 - => 4 - >> 4+4 - => 8 - -Please fire up `irb` on your computer and try this out! - -# Everything evaluates to something - - @@@ ruby - >> 2 + 2 - => 4 - - >> (2+2).zero? - => false - - >> "foo" if false - => nil - - >> puts "foo" - foo - => nil - -# Hash mark comments, like perl - - @@@ ruby - # is a comment - 2 + 2 # is a comment - -# Optional semicolons, parens, and `return` - -These are equivalent: - - @@@ ruby - def inc x - x + 1 - end - - def inc(x) - return x + 1; - end - - def inc(x); x + 1; end - -# Line Break Gotcha - - @@@ ruby - x = 1 + 2 - x #=> 3 - - x = 1 - + 2 - x #=> 1 - -Solution: always put operators on top line - - x = 1 + - 2 - x #=> 3 - -# Use parens when you need them - - @@@ ruby - >> "Hello".gsub 'H', 'h' - => "hello" - - >> "Hello".gsub("H", "h").reverse - => "olleh" - -!SLIDE -# Variables are declared implicitly - - @@@ ruby - first_name = "Santa" - last_name = "Claus" - full_name = first_name + last_name - #=> "SantaClaus" - -# String interpolation - - @@@ ruby - "boyz #{1 + 1} men" - => "boyz 2 men" - -* Any Ruby code can go inside the braces -* It gets evaluated and stuck inside the string - -!SLIDE custom -# Built-in Types - -* Numbers - * `42` -* Booleans - * `true` - * `false` -* Strings - * `"apple"` - * `'banana'` -* Symbols - * `:apple` -* Arrays - * `["apple", "banana"]` -* Hashes - * `{:apple => 'red', :banana => 'yellow'}` -* Ranges - * `(1..10)` - -# Functions - - @@@ ruby - def add(a,b) - a + b - end - - add(2, 2) - #=> 4 - -* Note: no 'return' required - -# Classes and methods - - @@@ ruby - class Calculator - def add(a,b) - a + b - end - end - -* a *function* inside a *class* is called a *method* - -# bang and question methods - -* method names can end with `!` or `?` - * `!` means "watch out!" - * `?` means "boolean" - -# equal, double-equal, and threequal - -* `x = 1` means "put the value `1` in the variable `x`" -* `x == 2` means "`true` if `x` is `2`, otherwise `false`" -* `x === 3` means the same as `==` but sometimes more - -# Ruby syntax cheatsheet - -![cheatsheet](img/cheatsheet.png) - -(_The Well-Grounded Rubyist_, p. 5, section 1.1.2) - -# Ruby identifiers - -* `local_variable` - start with letter or underscore, contain letters, numbers, underscored -* `@instance_variable` - start with `@` -* `@@class_variable` - start with `@@` -* `$global_variable` - start with `$` -* `Constant` - start with uppercase letter -* `method_name?` - same as local, but can end with `?` or `!` or `=` -* keywords - about 40 reserved words (`def`) and weirdos (`__FILE__`) -* literals - `"hi"` for strings, `[1,2]` for arrays, `{:a=>1, :b=2}` for hashes - -# Ruby Naming Conventions - -methods and variables are in `snake_case` - -classes and modules are in `CamelCase` - -constants are in `ALL_CAPS` - -> Standard is better than better. -> -> -- Anon. - -# Variable Scopes - - @@@ ruby - var # local variable (or method call) - @var # instance variable - @@var # class variable - $var # global variable - VAR # constant - -# Messages and Methods - -* an object is referenced by a variable or a literal -* the dot operator (`.`) sends a message to an object -* an object receives a *message* and invokes a *method* -* with no dot, the default object (`self`) is the receiver - -# Classes - -* A class defines a group of behaviors (methods) -* Every object has a class, `Object` if nothing else - -# `load` and `require` - -* `load` inserts a file's contents into the current file -* `require` makes a *feature* available to the current file - * skips already-loaded files - * omits the trailing `.rb` - * can also be used for extensions written in C (`.so`, `.dll`, etc.) - -# Credits - -* "Ruby Intro" slides based on [Ruby Quickstart for Refugees](https://gist.github.com/190567) by [Jacob Rothstein](http://about.me/jbr) -* Improved by Alex Chaffee, Sarah Allen, Wolfram Arnold - - diff --git a/sites/en/workshop/teaching_tips.md b/sites/en/workshop/teaching_tips.md deleted file mode 100644 index 8dcd35665..000000000 --- a/sites/en/workshop/teaching_tips.md +++ /dev/null @@ -1,31 +0,0 @@ -## General Teaching Advice - -When planning, don't think about what _you're_ going to do. Think about what _they're_ going to do. - - -## Metaphors and Stories for Teaching Programming: - -A program is like a recipe. There's two parts: a list of ingredients and a list of instructions. Think of code as the instructions and data as the ingredients. - -Also, to extend the metaphor, think about doubling a recipe: the instructions don't change even though the data are different this time. - -Computer memory is like a warehouse with lots of boxes. Each box has something inside (the data) and it also has a label (the variable name). - -The command line as Zork. You are "in" a room (a directory) and can either act on things in the room (commands) or move to a new room (cd). It's very important that you know where you are! Learn how to read the command line, and do an "ls" (or "dir") to look around. - -# Notes -* Have one volunteer be a runner to remind people when it's 10 minutes until the next break. (This worked really well.) -* Make sure all of the projectors have Mac adaptors -* Handouts with all of the code that people need to type -* Tell people at the beginning that the slides are online -* Have a volunteer leader, make sure they are distributed evenly -* Advertise that the Friday night setup is **required**, send notes out 1 week ahead of time, so people can get started ahead of time -* USB keys and/or DVDs with the big stuff like XCode -* Ask the venue about bike policy (can participants bring bikes inside?) and communicate that to participants ahead of time. -* Get a good night's sleep before the class, it is important to be well rested and fresh when teaching or TA'ing. -* Start with live coding - watch and type along, don't even use slides. make sure students & teachers irb prompts display line numbers, so we can say go to line 32 -* Go into IRB to practice basic concepts first, don't discuss what agile and a variable is in the abstract right away. Learning by doing first and talking later worked better. -* At the very beginning, show a designed version of app so people can recognize it as finished product like other web sites they see: screenshots are on Sarah Allen's site. -* Have TAs wear different badge colors so they can recognize each other. -* Discuss rubyisms where appropriate. use code to show elegance & readability of ruby vs other languages: each vs (for i; i = "lame"; i ++) -* Ask students to discuss what they learned, what they thought of it, at end of the day. As beginning of wrap-up session or just before it. diff --git a/sites/en/workshop/topics.md b/sites/en/workshop/topics.md deleted file mode 100644 index e42a15c42..000000000 --- a/sites/en/workshop/topics.md +++ /dev/null @@ -1,48 +0,0 @@ -### Explain what they installed last night -The Friday night install process is very cut-and-paste, and people new to Ruby don't understand any of the things that they did. Show them the components (git, github, ruby, rails, heroku) and explain what each is for and how they fit together in plain language and ''why'' each one is important. Diagrams can help. Don't assume beginners have any context: for example, git is not the only version-control software out there, it is just one way to do it. - -### Make sure they know basic *nix commands -* Remember that some people don't yet know that when you're at the command line, you're actually sitting in a folder, and when you change a directory it's like moving into a folder with a GUI. This is NOT obvious if you've never used it before. -* If they are learning this for the first time, give them a little challenge like: go into the Desktop folder, create a subfolder and then cd into it. Use pwd to prove you're in the right place. -* Check in to make sure everyone knows at least the following unix commands: cd, ls, mkdir, irb, pwd. -* Explain what an argument and a flag are. - curl -O http://whatever.com/text.txt -* (Someone who knows DOS should write the equivalent of this section for DOS) - -### Explain other foundational concepts. -* How does a web server work? -* What is versioning? Why would you need to use it? -* What is the difference between running code at the command line and running code out of a file? -* What is the difference between Ruby and Rails? - -See [Foundational Skills](foundational_skills) for a slide set describing the basic skills required to be a programmer that don't involve writing code. - -### Slides - -The Railsbridge Workshop curriculum lives on http://docs.railsbridge.org, which is backed by the code in http://github.com/railsbridge/docs - -Here's a whiteboarded roadmap/flowchart of the old slides: - -* http://www.flickr.com/photos/alexchaffee/5885335854 - -Contact Sarah Allen (sarah _at_ ultrasaurus _dot_ com) and send your github name if you want to be a collaborator. Or just fork the github project and send a pull request when you've made changes. - -### Ruby Language -* For novices group: [Ruby for Beginners](ruby_for_beginners) -* [Ruby for Programmers](ruby_for_programmers) - -#### Key Concepts -* everything is an object -* everything returns something -* open classes -* blocks -* symbols - -#### Additional Notes for Programmers -* http://gist.github.com/190567 -* http://betterexplained.com/articles/starting-ruby-on-rails-what-i-wish-i-knew/ - -### Rails - -* Intro (Suggestotron) Curriculum -* Intermediate (Message Board) Curriculum diff --git a/sites/en/workshop/web_apps.deck.md b/sites/en/workshop/web_apps.deck.md deleted file mode 100644 index 08d0b5bdb..000000000 --- a/sites/en/workshop/web_apps.deck.md +++ /dev/null @@ -1,26 +0,0 @@ -!SLIDE -## Web App Network Architecture -![](img/web-application.png) - -!SLIDE -## Web App MVC Architecture -![](img/mvc_simple.png) - -!SLIDE -# REST -* Representational State Transfer -* Application state and functionality are abstracted into resources -* Each resource may be referenced with a global identifier (URI over HTTP) -* Resources share a uniform interfaces -* Note - * introduced in 2000 in the doctoral dissertation of Roy Fielding - * http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm - -!SLIDE -# REST URIs and HTTP actions -* GET http://myserver.com/topics - a list of all the topics -* GET http://myserver.com/topics/1 - the first topic -* POST http://myserver.com/topics - create a topic -* PUT http://myserver.com/topics/1 - modify the first topic -* DELETE http://myserver.com/topics/1 - delete the first topic - diff --git a/sites/en/workshop/welcome.deck.md b/sites/en/workshop/welcome.deck.md deleted file mode 100644 index 736f26a64..000000000 --- a/sites/en/workshop/welcome.deck.md +++ /dev/null @@ -1,104 +0,0 @@ -!SLIDE centereverything bullets -![Railsbridge](img/railsbridge_logo.png) -# Ruby on Rails Workshop - - - -# Open source workshop - -* It's a community project! - * Many individuals - * RailsBridge - * DevChix - -* All materials are open! - * RailsBridge wiki - * Slides: github, deck - * See - -* Spin-off Workshops - * RailsGirls, PyStar, Python Ladies, Scala - * Learn the Front End, Confident Coding JS, and...? - - -# Why are we here? -We want the community of software developers to reflect the diversity of our society - - -# Why are we here? -* Ruby on Rails! - - -# What is Ruby on Rails? - -!SLIDE center -# Ruby vs. Rails - -|Ruby is a Language | Rails is a Framework | -|----|-----| -| Ruby | Rails | - - -# Ruby: programming language - -* Object oriented -* General purpose - - -# Rails: web application framework - -* Database agnostic -* Built using the Ruby Language -* History - * 37signals - * 2004 - first released as open source - * 2007 - shipped with Mac OS 10.5 "Leopard" - - -# The Rails Philosophy - -* Opinionated -* Convention over configuration -* DRY (Don't Repeat Yourself) - * less code means it's easier to maintain & modify -* Test Driven Development (TDD) -* Minimal code - maximal effect - - -# Agile development - -![Agile Manifesto](img/agile.jpg) - -* Pair programming -* Test-driven or Behavior-driven development - - -# Goal: -###   -### By the end of the day, you will have built and deployed a web application - live on the internet! - - -# Don't be shy! -* Ask questions! -* TAs and teachers are here to help - - -# Tools we'll be working with -* **rails** -* **rake**: like make for Ruby. An easy way to run tasks. -* **git**: source code control. -* **database**: we'll use SQLite, but could be any relational database. -* **editor**: Sublime Text 2 -* **heroku**: free Rails hosting. - - -# Materials -* Slides: -* Suggestotron Curriculum: - - -# What will you learn today? -* Ruby - * understanding the Ruby programming language -* Rails - * learn tools and patterns for building web apps in Ruby on Rails diff --git a/sites/en/workshop/workshop.md b/sites/en/workshop/workshop.md deleted file mode 100644 index ad6f2d764..000000000 --- a/sites/en/workshop/workshop.md +++ /dev/null @@ -1,38 +0,0 @@ -# Materials for Teachers - -* [Foundational Skills](foundational_skills) -* [Ruby for Beginners](ruby_for_beginners) -* [Ruby for Programmers](ruby_for_programmers) -* [Diagrams (Git, MVC, REST) ](diagrams) - -### Teacher Training -* [Teacher Training Deck](more_teacher_training) - -# Materials for Organizers - -### Workshop Intro & Closing Presentation Slide Decks - -If you can edit HTML, this is the presentation for you. It's the prettiest: - -* [Welcome and Closing Reveal.js deck (zip file)](http://cl.ly/0T341w3X130q) - -Download, then open up the index.html file in a text editor. Edit pages 0 -(dates, location, logo), 1 (sponsor logos), and 7 (after party location), and -you're good to go. (Run it locally for the presentation itself.) - -#### Or copy one of these other formats: - -Google Docs presentations - -* [Welcome (google doc)](https://docs.google.com/presentation/d/1VT8J6CTuN8ot_-0ZElLv49_-cxuNmXTp83DBonD1x5w/edit#slide=id.p) -* [Closing (google doc)](https://docs.google.com/presentation/d/19ik5tm_enCNRIM4zaY9rIoeRhDoMMfFUDgNXnd2lW6A/edit#slide=id.p) - -deck.rb - -* [Welcome](welcome) -* [Closing](closing) - -Or make a presentation in the format of your choice. Powerpoint, Keynote, your own [reveal.js](http://lab.hakim.se/reveal-js/) deck — follow your heart! - -# Other? -See the Table of Contents for a full list of materials. diff --git a/sites/es/hola/hola.step b/sites/es/hola/hola.step deleted file mode 100644 index f0e5f45b0..000000000 --- a/sites/es/hola/hola.step +++ /dev/null @@ -1 +0,0 @@ -message "Hola! Que tal?" diff --git a/sites/zh-tw/nihao/nihao.step b/sites/zh-tw/nihao/nihao.step deleted file mode 100644 index 76a2c10f7..000000000 --- a/sites/zh-tw/nihao/nihao.step +++ /dev/null @@ -1 +0,0 @@ -message "世界你好!"