Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions 4_Arrays/1_Creating_Arrays/solution.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# e.g.:
objects = [2.75, true, []]
question_marks = Array.new(3, '?')
93 changes: 93 additions & 0 deletions 4_Arrays/1_Creating_Arrays/solution_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
require 'rspec'
require 'rspec/expectations'
require 'code_breaker'

VARIABLES = [:objects, :question_marks].freeze

def code_lines
%q{[['solution::code']]}
end

def statements
@statements ||= Array(CodeBreaker.parse(code_lines))
end

def assignment?(statement)
statement.is_a?(Hash) && statement.keys.first == :lvasgn
end

def brackets_statement
@brackests_statement ||= statements.select do |statement|
assignment?(statement) && statement[:lvasgn].first == VARIABLES.first
end
end

def new_statement
@new_statement ||= statements.select do |statement|
assignment?(statement) && statement[:lvasgn].first == VARIABLES.last
end
end

def array_assigned?(variable)
!!defined?(variable) && variable.is_a?(Array)
end

def array_defined_with_new?(variable, statement)
array_assigned?(variable) &&
statement.first[:lvasgn][1][0..1] == [{ const: :Array }, :new]
end

describe 'Your code' do
[['solution::code']]

VARIABLES.each do |name|
it "defines a variable with name \"#{name}\"" do
expect(local_variables.include?(name)).to be true
end

if local_variables.include?(name)
it "assigns an Array to the variable \"#{name}\"" do
expect(eval(name.to_s)).to be_an Array
end
end
end

if (local_variables & VARIABLES).sort == VARIABLES.sort
describe 'assings an Array to "objects" which' do
it 'is created by using []' do
expect(array_assigned?(objects)).to be true
expect(brackets_statement.first[:lvasgn].last.keys.first).to eq :array
end

if array_assigned?(objects)
before { @values = brackets_statement.first[:lvasgn].last[:array] }

it 'holds a Float' do
expect(@values.include?(Float)).to be true
end

it 'holds a Boolean' do
included = @values.include?(TrueClass) || @values.include?(FalseClass)
expect(included).to be true
end

it 'holds an empty Array' do
empty_array = { array: [] }
expect(@values.include?(empty_array)).to be true
end
end
end

describe 'assings an Array to "question_marks" which' do
it 'is created by using #new' do
expect(array_defined_with_new?(question_marks, new_statement)).to be true
end

if array_defined_with_new?(question_marks, new_statement)
it 'holds three times "?"' do
expect(question_marks).to eq ['?'] * 3
end
end
end
end
end
88 changes: 88 additions & 0 deletions 4_Arrays/1_Creating_Arrays/task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Creating Arrays

---

*You will learn:*
- what an Array is
- what you can store in an Array
- how to create Arrays

---

An Array is a *collection of objects*.

This collection is *ordered*, which means that each object in an Array has a fixed
place assigned, a so called *index*.
The index is defined by an integer starting with 0: The first object in the Array
has the index 0, the second has the index 1, etc.

The index can be used to access the objects in an Array. You will learn more
about using the index in the next unit "Accessing elements".

An Array can hold all kinds of Ruby objects, such as Strings, Numbers, Booleans,
other Arrays, etc. The objects in an Array don‘t need to be of the same type.
An Array can hold all kinds of different objects (e.g. Strings, and Numbers) at the same time.

Let‘s create some Arrays!

## Creating an Array with []

Arrays can be created in different ways.
The shortest is surrounding a comma-separated list of objects with square brackets:

` [1, 'Mary', true]` *# => [1, "Mary", true]*

An Array is a Ruby object itself. If you ask for an Array‘s class with the `class` method
you will get `Array`:

` numbers = [1, 2, 3]`
` numbers.class` *# => Array*

An Array is an object of type *Array*.

Instead of using `[]` you can also use the the longer way and call the `[]` method
of the *Array* class:

` Array[1, 2, 3]` *# => [1, 2, 3]*

## Creating an Array with #new

Besides using `[]`, you can create an Array by instantiating an Array with the `new` method.
The `new` method accepts two optional parameters: The number of elements, and the element itself.

If you call `new` without any parameter it will create an empty Array:

` Array.new` *# => []*

If you only define the first parameter as an Integer, it will use this Integer to define
the length of the new Array and will assign *nil* for each element:

` Array.new(2)` *# => [nil, nil]*

If you pass an Array as first parameter it will return the defined Array:

` Array.new([1, 2, 3])` *# => [1, 2, 3]*

The actual interesting case is, if you pass both parameters.
It will create an array of the length given in the first parameter, with each element
being the second parameter. Here is an example:

` Array.new(3, 4.5)` *# => [4.5, 4.5, 4.5]*
` Array.new(2, ['a', 'b'])` *# => [['a', 'b'], ['a', 'b']]*


Another way of creating an Array is calling `Array()` with a single parameter:

` Array('banana')` *# => ["banana"]*

This will create a new Array with only the given value and is the same as calling `['banana']`.

---

Assign an Array to a variable *objects* by using the square brackets syntax for creating the Array.
The Array should have 3 elements: a Float, a Boolean, and an empty Array.

Create an Array that holds 3 times the String *'?'* by using the `new` method.
Assign the Array to a variable *question_marks*.

---
7 changes: 7 additions & 0 deletions 4_Arrays/2_Accessing_elements/solution.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# e.g.:
languages = ['Ruby', 'Elixir', 'Scala', 'Erlang', 'OCaml']

first = languages.first
last = languages.last

some_languages = languages[1..3]
44 changes: 44 additions & 0 deletions 4_Arrays/2_Accessing_elements/solution_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'rspec'
require 'code_breaker'

VARIABLES = [:languages, :first, :last, :some_languages].freeze

describe 'Your code' do
[['solution::code']]

VARIABLES.each do |name|
it "defines a variable with name \"#{name}\"" do
expect(local_variables.include?(name)).to be true
end

if local_variables.include?(name)
if [:languages, :some_languages].include?(name)
it "assigns an Array to the variable \"#{name}\"" do
expect(eval(name.to_s)).to be_an_instance_of Array
end
elsif local_variables.include?(:languages) && name == :first
it "assigns the first language to the variable \"#{name}\"" do
expect(eval(name.to_s)).to eq languages.first
end
elsif local_variables.include?(:languages) && name == :last
it "assigns the last language to the variable \"#{name}\"" do
expect(eval(name.to_s)).to eq languages.last
end
end

if name == :languages
it "assigns an Array to the variable \"#{name}\" with 5 String elements" do
values = Array.new(eval(name.to_s))
expect(values.length).to eq 5
values.each { |value| expect(value).to be_an_instance_of String }
end
end

if local_variables.include?(:languages) && name == :some_languages
it "assigns an Array to the variable \"#{name}\" with 5 String elements" do
expect(eval(name.to_s)).to eq languages[1..3]
end
end
end
end
end
81 changes: 81 additions & 0 deletions 4_Arrays/2_Accessing_elements/task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Accessing elements

---

*You will learn:*
- how to get a certain element from an Array
- how to get subsets of elements from an Array

---

Each element in an Array is associated with a fixed place – its *index*.
The index is an Integer by which you can access an element in the Array.

The index 0 points to the first element, the index 1 to the second element, etc.
Negative indexes point to elements backwards from the last element. E.g. -1 points
to the last element, -2 points to the second last element, and so on.

## Getting an element from an Array

You can get the object from an Array at a certain index by using squared brackets:

` numbers = [2, 4, 9]` *# defining an Array `numbers`*
` numbers[0]` *# => 2*
` numbers[1]` *# => 4*
` numbers[2]` *# => 9*
` numbers[-1]` *# => 9*

If there is no element present for the given index you will get a *nil* value:

` numbers[3]` *# => nil*

`[]` is just an ordinary method that is defined for an instance of Array.

Another way for getting a single element is using the alias method `at`:

` numbers.at(0)` *# => 2*
` numbers.at(-1)` *# => 9*
` numbers.at(3)` *# => nil*

There are two methods for getting special elements of an Array: `first` and `last`.
The method `first` – as you might have guessed – returns the first element
(at index 0), and `last` returns the last element (at index -1):

` numbers.first` *# => 2*
` numbers.last` *# => 9*

## Getting a subset of elements from an Array

You can also pass two parameters to the `[]` method. This allows to select a subarray
by defining the index to start at and the number of elements you want to grab, e.g.:

` numbers[1, 2]` *# => [4, 9]*

returns two elements starting at index 1. If there are no elements for the given indexes
available, it returns *nil*:

` numbers[10, 2]` *# => nil*

Another way to select a subarray from an Array is to pass a *Range* of the wanted
indexes to `[]`:

` numbers[1..2]` *# => [4, 9]*

In case the elements are not available for the indexes it will again return *nil*:

` numbers[5..10]` *# => nil*

For more information about the `[]` method, see (ruby-doc core: Array#[]).

---

Create an Array of 5 different programming languages (as Strings) and store it in
a *languages* variable.

Define a variable *first* and assign the first programming language to it.

Define a variable *last* and assign the last programming language to it.

Store the three middle programming languages in a variable *some_languages*.

---
7 changes: 7 additions & 0 deletions 4_Arrays/3_Adding_elements/solution.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
baggage = ['shirt']
baggage.unshift('glasses')
baggage.push('shoes')
baggage.insert(2, 'trousers', 'socks')

# baggage
# => ["glasses", "shirt", "trousers", "socks", "shoes"]
41 changes: 41 additions & 0 deletions 4_Arrays/3_Adding_elements/solution_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'rspec'
require 'code_breaker'

describe 'Your code' do
[['solution::code']]

VARIABLE = :baggage
ITEMS = ['glasses', 'shirt', 'trousers', 'socks', 'shoes']

it 'defines a variable with name "baggage"' do
expect(local_variables.include?(VARIABLE)).to be true
end

if local_variables.include?(VARIABLE)
before(:all) do
@statements = CodeBreaker.parse( %q{ [['solution::code']] })
end

it 'uses the unshift method to add "glasses"' do
unshift = [{ lvar: VARIABLE }, :unshift, String]
expect(@statements.include?(unshift)).to be true
end

it 'uses the push or << method to add "shoes"' do
push = [{ lvar: VARIABLE }, :push, String]
arrows = [{ lvar: VARIABLE }, :<<, String]

includes_code = @statements.include?(push) || @statements.include?(arrows)
expect(includes_code).to be true
end

it 'uses the insert method to add "trousers" and "socks"' do
insert = [{ lvar: VARIABLE }, :insert, Fixnum, String, String]
expect(@statements.include?(insert)).to be true
end

it 'changes your baggage to contain "glasses", "shirt", "trousers", "socks", & "shoes"' do
expect(eval(VARIABLE.to_s)).to eq ITEMS
end
end
end
Loading