Last active
May 24, 2016 14:05
-
-
Save roschaefer/11a214c456dbbd2cc51d to your computer and use it in GitHub Desktop.
Challenges
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
####################################################################### | |
# Programming challenge 1: Christmas Tree # | |
# To solve this challenge you need to know how to iterate over arrays # | |
# Also, you need to know how to print with 'puts' or 'print' # | |
# And finally basic arithmetic operations like 1 * 2 or 1 + 2 # | |
####################################################################### | |
# TODO: Paint a christmas tree on the command line which is 'lines' long | |
# TODO: This is how the christmas tree looks like for 20 lines | |
# | |
# * | |
# *** | |
# ***** | |
# ******* | |
# ********* | |
# *********** | |
# ************* | |
# *************** | |
# ***************** | |
# ******************* | |
# ********************* | |
# *********************** | |
# ************************* | |
# *************************** | |
# ***************************** | |
# ******************************* | |
# ********************************* | |
# *********************************** | |
# ************************************* | |
# *************************************** | |
# || | |
# | |
# TODO: You should be able to change only this variable to print a bigger tree | |
lines = 20 | |
# TODO: To give you a starting point: | |
# TODO Let's say we have a number X | |
# TODO: Then you can run a code block X times like so | |
lines.times do | |
puts "Gets printed " + lines.to_s + " times" | |
end | |
# TODO: You can assign a variable |i| to get the current step counter | |
lines.times do |i| | |
puts "The current step is : " + i.to_s | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
####################################################################### | |
# Programming challenge 2: Guess my number # | |
# To solve this challenge you need to know how to use a 'while' loop # | |
# You need to know how to get user input from the command line # | |
# Also how to normalize the input (removing trailing whitespaces) # | |
# You should know about if-clauses and numeric comparisons, like '>' # | |
# How to write methods # | |
# And you should know what sequences are, e.g. 1..100 # | |
####################################################################### | |
class Chooser | |
def initialize(lower_bound, upper_bound) | |
@number = rand(lower_bound..upper_bound) | |
@steps = 0 | |
end | |
def guess(number) | |
@steps = @steps + 1 | |
if (@number == number) | |
puts "Congratulations, the number is #{@number} and you needed #{@steps} steps!" | |
return "correct" | |
elsif @number > number | |
return "greater" | |
else | |
return "smaller" | |
end | |
end | |
end | |
def ask_human(chooser, lower_bound, upper_bound) | |
response = "" | |
while response != "correct" | |
# TODO: ask the user for input! | |
# TODO: you can convert a string "42" to the number 42 by calling "42".to_i | |
end | |
end | |
def computer_search(chooser, lower_bound, upper_bound) | |
# TODO: implement a smarter solution than just guessing randomly | |
response = "" | |
while response != "correct" | |
# 'rand' generates a random number in a sequence | |
# you don't need to know how it works | |
# because you can replace it with sth. better | |
a_number = rand(lower_bound..upper_bound) | |
response = chooser.guess(a_number) | |
end | |
end | |
lower_bound = 1 | |
upper_bound = 100 | |
chooser = Chooser.new(lower_bound, upper_bound) | |
# TODO: implement and call 'ask_human' | |
#ask_human(chooser, lower_bound, upper_bound) | |
computer_search(chooser, lower_bound, upper_bound) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################ | |
# Programming challenge 3: Advanced User Input # | |
# To solve this challenge you need to know about arrays and hashes # | |
# You should know how to use 'puts' and 'gets' # | |
# And you should know how to use blocks and certain methods like 'select' etc. # | |
################################################################################ | |
group_template = { | |
:where => {:city => ["Berlin", "Potsdam", "Hamburg", "Munich"]}, | |
:when => {:weekday => ["Mo", "Tue", "Wed","Thu","Fr"], | |
:time => ["18:30", "19:00", "19:30"], | |
} | |
} | |
# TODO: Add more groups to 'ruby_groups' from the website 'rorganize.it' | |
# TODO: http://rorganize.it/groups | |
ruby_groups = [] | |
ruby_groups << { | |
:name => "Rubies-in-the-woods", | |
:where => {:city => "Potsdam"}, | |
:when => {:weekday => "Tue", | |
:time => "18:30"} | |
} | |
ruby_groups << { | |
:name => "RubyMonstas", | |
:where => {:city => "Berlin"}, | |
:when => {:weekday => "Mo", | |
:time => "19:00"} | |
} | |
ruby_groups << { | |
:name => "rubycorns", | |
:where => {:city => "Berlin"}, | |
:when => {:weekday => "Tue", | |
:time => "19:00"} | |
} | |
def choose_from(hash, key) | |
hash[key].each_with_index do |option, index| | |
puts "#{index+1}. #{option}" | |
end | |
choosen = hash[key][Integer(gets.chomp)-1] | |
hash[key] = choosen | |
# NOTE: This function has side effects | |
# NOTE: because we change the argument 'hash' directly | |
end | |
preferred_options = group_template | |
puts "Hello lovely user! Do you want to learn programming with ruby?" | |
puts "There are many ruby learners groups out there, let's find one!" | |
puts "What's the city you live in?" | |
choose_from(preferred_options[:where], :city) | |
puts "Which day of the week do you prefer?" | |
choose_from(preferred_options[:when], :weekday) | |
puts "Now choose a time slot from below:" | |
choose_from(preferred_options[:when], :time) | |
puts "Thank you!" | |
matching_groups = [] | |
#matching_groups = ???? TODO: find matching groups! | |
# TODO: First, see how the hash 'preferred_options' looks like | |
# TODO: E.g. with 'p preferred_options' | |
# TODO: The goal is to find groups that match the 'preferred_options' hash | |
# TODO: You can compare two hashes e.g. with '==' | |
# TODO: But if you do that, no group will match, because these hashes have the | |
# TODO: key :name, which is missing in the 'preferred_options' hash | |
# TODO: What can we do here? | |
# NOTE: As a tip: check out the documentation for 'Hash#reject' | |
# NOTE: http://ruby-doc.org/core-2.1.5/Hash.html#method-i-reject | |
puts "The following groups were found" | |
matching_groups.each_with_index do |group, index| | |
puts "#{index+1}. #{group[:name]}" | |
end | |
# TODO: Print a better message if no groups were found |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################ | |
# Programming challenge 4: Sinatra web application with some links # | |
# To solve this challenge you need to know how install a so called 'gem' # | |
# In particular, how to install the 'sinatra' gem # | |
# How to use blocks and how to return a value from a block # | |
# How to concatenate strings (with << or with + ) # | |
# You should know a little bit about HTML and have an idea of a 'get request' # | |
# And how the last part of the URL maps to a so called 'route' in sinatra # | |
################################################################################ | |
require 'sinatra' | |
# This method 'get' is defined as soon we 'require' the sinatra library | |
# It receives a so called 'route', which is the "/" here | |
# Sinatra will try to match an incoming get request to a corresponding route | |
get("/") do | |
# NOTE: The block here! Between do ... end | |
# We pass that block to the method 'get' | |
response = "<h1> What is this all about? </h1>" | |
response << "<p> Check it out </p>" | |
return response | |
# The last line of block is the return value. But we can also use an explicit | |
# return statement like above. Makes things more obvious. But in this case it | |
# is absolutely optional. | |
end | |
get("/about") do | |
response = "<h1> It's just for fun! </h1>" | |
response << "<p> Do you want to go back? </p>" | |
return response | |
end | |
# If you run this script it will start a server. You can access the two routes | |
# if you point your browser at http://localhost:4567/ or | |
# http://localhost:4567/about respectively. | |
# Wouldn't it be nice, if you could get from one site to the other with a click? | |
# TODO: Change the response strings from above to link to the other route. | |
# TODO: Learn about how links look like in HTML: | |
# TODO: http://www.w3schools.com/html/html_links.asp | |
# TODO: You can use the two sentences in the paragraphs as the text for a link. | |
# TODO: E.g. "Do you want to go back?" With 'back' as a link to the main page. | |
# TODO: You might need to escape the double quotes " in your string with a | |
# TODO: backslash \ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################ | |
# Programming challenge 5: Ruby regexes # | |
# For this programming exercise, you must know regular expressions # | |
# How to read and write to files # | |
# And how to get the first element of an array # | |
################################################################################ | |
# This programming exercise is a real world example of ruby in action. | |
# A friend of mine, who is working as a journalist, spent nearly two hours | |
# manually replacing html tags on a website. | |
# His task was to copy html from one site to another and to fix the footnotes: | |
# http://isj.org.uk/the-internationalist-case-against-the-european-union/ | |
# http://europeonthestrand.ideasoneurope.eu/ | |
# | |
# In order to make the backlinks working, the links that looked like this: | |
# <a id="footnote-263-72-backlink" href="http://blabla/#footnote-263-72">72</a> | |
# Must be transformed to into two separate links that look like this: | |
# <a id="backlink-72"></a><a href="#72">[72]</a> | |
# | |
# We can solve this problem automatically with so called regular expressions: | |
# http://ruby-doc.org/core-2.1.1/Regexp.html | |
# https://en.wikipedia.org/wiki/Regular_expression | |
# TODO: Important! Before you run this script, you must save the whole website | |
# TODO: http://isj.org.uk/the-internationalist-case-against-the-european-union/ | |
# TODO: into a file 'input.html' in the same directory! | |
# We open a certain file and read the content into a string called 'text' | |
text = File.open("input.html", 'rb') do |f| | |
f.read | |
end | |
# If we have the file opened with a block, it automatically closes the file | |
# after reading. See: http://ruby-doc.org/core-2.1.4/File.html#method-c-open | |
# Why is it important to close files? See: http://stackoverflow.com/q/8175827 | |
# Here we initialize a regular expression in ruby: | |
pattern = %r{<a id="footnote-263-(\d+)-backlink" href=".*#footnote-263-\d+">\d+</a>} | |
# See: http://ruby-doc.org/core-2.1.1/Regexp.html | |
# There are two possible syntax variations for regular expressions: | |
# %r{ ... } or / ... / or you can use the explicit constructor: Regexp.new(...) | |
# | |
# What is the meaning of the special characters here? There is a nice online | |
# tester for ruby regular expressions: http://rubular.com/ wich also features an | |
# overview of all the special character groups. | |
# So in this case, \d means any decimal digit, \d+ means many decimal digits but | |
# at least one, .* means any character sequence (even the empty one) and | |
# everything between paranthesis (..) is a 'group'. | |
# Ruby strings have a method #gsub (global substitution) that expects a regular | |
# expression as a parameter and substitutes matches with the result of a block | |
result = text.gsub(pattern) do |footnote| | |
# Some debug output. The 'footnote' is the match of the pattern here. | |
puts "Footnote: " | |
puts footnote | |
# The method Regexp#match returns a matchdata object, that contains all the | |
# different groups of the matched regex. | |
match_data = pattern.match(footnote) | |
# You can use this line of code to have a look of the elements of it: | |
#puts match_data.to_a.inspect | |
# TODO: We want to extract the id of the backlink here: | |
number = '' #TODO: What element of the match data is our backlink id?? | |
# TODO: After we extracted the number, we want to replace the whole match | |
# TODO: Create a string and put the number at the correct position! | |
# TODO: The final string should look somehow like this: | |
replacement = %{<a id="backlink-72"></a><a href="#72">[72]</a>} | |
# TODO: But of course '72' must be replaced with the extracted number | |
# NOTE: Ah, and %{...} is just another syntax for strings, so we don't have | |
# NOTE: to escape so many quotation marks with backslashes \" | |
# NOTE: https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Literals#Strings | |
# More debug output. | |
puts "Replacement" | |
puts replacement | |
puts # ----- empty line ----- | |
replacement # last line of the block is the final replacement of the match | |
end | |
# Write the output to a file called 'output.html' and close it | |
File.open("output.html", 'w') do |f| | |
f.write(result) | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################# | |
## Programming challenge 6: Rendering templates in Sinatra # | |
## For this programming exercise you should have created a 'hello world' # | |
## program in sinatra and you should know what routes are # | |
## Learn more about sinatra here: http://www.sinatrarb.com/intro.html # | |
## Short ERb overview: http://fireapp.kkbox.com/doc/tutorial_2.html # | |
################################################################################# | |
require 'sinatra' | |
class Person | |
attr_reader :first_name, :last_name, :phone_number # a person has these 3 methods | |
def initialize(name, phone_number) | |
@first_name, @last_name = name.split(" ") | |
@phone_number = phone_number | |
end | |
end | |
get '/' do | |
@participants = [ | |
Person.new("Laura Liegener" , 999) , | |
Person.new("Leo Eckwert" , 123) , | |
Person.new("Meike Fischer" , 567) , | |
] | |
erb :index | |
end | |
# TODO: Copy the following code into a file called views/index.erb | |
=begin | |
<table> | |
<tr> | |
<th> First Name </th> | |
<th> Last Name </th> | |
<th> Phone Number </th> | |
</tr> | |
<tr> | |
<td> TODO: Dynamically </td> | |
<td> create a row </td> | |
<td> for every entry in @participants! </td> | |
</tr> | |
<tr> | |
<td> How can you do that? </td> | |
<td> ... here is just one example: </td> | |
<td> <a href="https://teamtreehouse.com/community/loop-through-array-in-an-erb-template">Follow this link!</a> </td> | |
</tr> | |
<tr> | |
<td> E.g. display the first name </td> | |
<td> ... the last name here </td> | |
<td> ... and the phone number </td> | |
</tr> | |
</table> | |
=end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################ | |
## Programming challenge 7: Using different routes for post and get requests ## | |
## The goal of this challenge is to use a post request to distinguish if the ## | |
## user has just visited the root page '/' or refreshed it, or if the user is ## | |
## attempting to solve the secret (she sends a character to the server). ## | |
## You will need to know how to handle post requests and redirect to a get ## | |
## request from there. Learn more about it: ## | |
## http://www.sinatrarb.com/intro.html#Routes ## | |
## http://www.sinatrarb.com/intro.html#Browser%20Redirect ## | |
################################################################################ | |
require 'sinatra' | |
secret = "Erdbeermarmelade" | |
guesses = [] | |
missed_guesses = 0 | |
get("/") do | |
guesses << params["character"] | |
unless secret.chars.include? params["character"] | |
missed_guesses += 1 | |
end | |
# TODO: How can we split this request to handle the delivered paramters in a | |
# 'post' route and render the :interface template in a get route? | |
# TODO: How can we immediately render the :interface template after processing | |
# the parameters? | |
@secret = secret | |
@missed_guesses = missed_guesses | |
@guesses = guesses | |
erb :interface | |
end | |
# TODO: put this code into a file called 'interface.erb' in folder 'views' | |
# TODO: What has to be changed in order to send the parameters as a post request | |
# instead of URL parameters? | |
# TODO: How can we limit the number of characters in the text input field? | |
# TODO: See http://www.w3schools.com/tags/att_input_size.asp | |
=begin | |
<body> | |
Missed guesses <%= @missed_guesses %> | |
<% if @missed_guesses <= 8 %> | |
<form action="/" method="get"> | |
Guess a character: <input type="text" name="character"><br> | |
<input type="submit" value="Submit"> | |
</form> | |
<% @secret.chars.each do |c| %> | |
<% if @guesses.include? c %> | |
<%= c %> | |
<% else %> | |
_ | |
<% end %> | |
<% end %> | |
<% end %> | |
</body> | |
=end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################ | |
# Programming challenge 8: Create a simple file server with Sinatra | |
# Sinatra serves static files by default in the /public folder | |
# However, as a toy example, you may want to serve static file from another | |
# folder | |
# | |
# Place your files in a folder /downloads | |
# If a user accesses your web-app, the path in the URL should be matched onto | |
# this /download folder, ie. http://localhost/to/some/file will be mapped to | |
# a location on your machine like | |
# /path/to/your/sinatra/app/downloads/to/some/file | |
# | |
# Read: | |
# http://www.sinatrarb.com/intro.html#Routes | |
# http://www.rubydoc.info/github/sinatra/sinatra/Sinatra%2FHelpers%3Asend_file | |
# http://ruby-doc.org/core-1.9.3/File.html#method-c-exists-3F | |
# | |
# Beware the security risks! Google for "Path traversal" and "Security" | |
# So don't deploy your server ;) | |
################################################################################ | |
require 'sinatra' | |
# TODO: no template application here ;) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment