Ruby programming assignment - ruby

So i need some support with my Ruby assignment, I'm not from US so you have to excuse my English.
We are building a hotel and this is the second assignment. It's a console based application and I have a class called main.rb that handles the runtime and a guest-class.
In this second assignment we are to preload the app with five guest-objects, I guess I have to use an array but don't really know how. Below are my guest class and my main class is simply a while-loop with a case statement.
I need help with:
adding 5 guests (not to a db or textfile only to a array or so) when the program starts
the hotel has 20 rooms and i need to randomize the room number and exclude already rented rooms
Hope you can help! Thanks!
class Guest
#Instance variables.
attr_accessor :firstName,
:lastName,
:address,
:phone,
:arrival,
:plot,
:gauge
#Constructor sets the guest details.
def initialize(first, last, adress, phone, arrival)
#firstName = first
#lastName = last
#address = address
#phone = phone
#arrival = arrival
#plot = range_rand(1,32)
#gauge = range_rand(2000,4000)
end
#Using rand()-method to randomize a value between min and max parameters.
def range_rand(min,max)
min + rand(max-min)
end
def to_string
"Name = #{#firstName} , Plot = #{#plot}"
end
end

Creating an array:
number_array = [1, 2, 3, 4, 5]
Accessing the elements of an array:
number_array[2]
# this would return the integer 3
Adding a new element to an array:
number_array << 6
# this would return [1, 2, 3, 4, 5, 6]
You can create a new guest by doing something like this:
Guest.new("John", "Doe", "1500 main street", "123-456-7890", "1/1/2010")
Since this is a homework assignment, I'll leave it to you to combine everything into a working solution ;)

Other people have already answered the first part of your question, so I'll help you with the second one (I'll provide the minimum, so that you still have some work to do :) )
You could create an array containing the 20 room numbers :
empty_rooms = (1..20).to_array
Then for each guest :
1) Take a random number in this array ( hint : randomize the index )
2) Remove this number from the array
3) And assign the room number to a Guest
4) Add the guest to the array of guests

I think what you mean is that you want 5 guest objects. You could put them in an array by creating an array literal and then adding guests to it
#guests = []
#guests << Guest.new()
#guests << Guest.new()
now your #guests array has two guests, etc.

Related

interpolate a string with an incrementing number

Im trying to interpolate a string with a number and increment that number as I iterate a list of attendees...
String "Hello #{name}. You are guest number #{num}." I know how to iterate each guest name, but how do I get a number to increment within the string from 1..7? I know this is simple. I am very beginner.
Tried everything.
def assign_rooms(attendees)
room_assignments = []
rooms.to_s = [1, 2, 3, 4, 5, 6, 7]
attendees.each_with_index {|x| room_assignments<< "Hello #{x}! You'll be assigned room #{rooms}!"}
room_assignments
end
Enumerable#each_with_index gives two arguments to the block: the item itself (the attendee), and the item's index which increments as desired. You can also combine with Array#map to avoid having to explicitly create and append the output to a second array. Enumerator#with_index allows specifying a start offset for the index (so that the room numbers are not zero-based).
def assign_rooms(attendees)
attendees.map.with_index(1) {|attendee, room|
"Hello #{attendee}! You'll be assigned room #{room}!"
}
end
puts assign_rooms(['Alice', 'Bob', 'Jack'])
Outputs:
Hello Alice! You'll be assigned room 1!
Hello Bob! You'll be assigned room 2!
Hello Jack! You'll be assigned room 3!
You could also achieve your goal with an enumerator. Suppose the first room number is 2.
attendees = %w| Flora Billy-Bob Hank Trixie Herb |
#=> ["Flora", "Billy-Bob", "Hank", "Trixie", "Herb"]
nbr = 2.step
#=> (2.step)
nbr.is_a?(Enumerator)
#=> true
attendees.each { |name|
puts "Hello, #{name}, you've been assigned to our best room, number #{nbr.next}!" }
Hello, Flora, you've been assigned to our best room, number 2!
Hello, Billy-Bob, you've been assigned to our best room, number 3!
Hello, Hank, you've been assigned to our best room, number 4!
Hello, Trixie, you've been assigned to our best room, number 5!
Hello, Herb, you've been assigned to our best room, number 6!
Note the following.
nbr.next #=> 7
nbr.next #=> 8
nbr.rewind
nbr.next #=> 2
See Numeric#step, Enumerator#next and (only if you are curious) Enumerator#rewind.
For fun, I'd like to show a more structured way, using a Hash as a model for storing information.
Let's use these input data:
rooms = [110, 111, 112, 210, 211, 212].map { |n| [n, {free: true, host: nil}] }.to_h
reception_queue = %w|Kirk Picard Spock McCoy Riker LaForge|
Let's say one room is already booked:
rooms[210] = {free: false, host: 'Uhura'}
rooms #=> {110=>{:free=>true, :host=>nil}, 111=>{:free=>true, :host=>nil}, 112=>{:free=>true, :host=>nil}, 210=>{:free=>false, :host=>"Uhura"}, 211=>{:free=>true, :host=>nil}, 212=>{:free=>true, :host=>nil}}
Now we want to assign the free rooms to each attendee. It is required to find the first room available matching some condition (free, but in can be one bed, two beds, suite, etc, depending on the complexity of the model).
This can be achieved by Enumerable#find:
rooms.find { |_, v| v[:free] }
#=> [110, {:free=>true, :host=>nil}]
Once we find a room, we want to assign the host there, removing her from the queue (Array#shift). Breaking the loop if there is no match.
For example:
reception_queue.size.times do |person|
nr = rooms.find { |_,v| v[:free] }
break unless nr
rooms[nr[0]][:host] = reception_queue.shift
rooms[nr[0]][:free] = false
end
So you can end up with:
rooms #=> {110=>{:free=>false, :host=>"Kirk"}, 111=>{:free=>false, :host=>"Picard"}, 112=>{:free=>false, :host=>"Spock"}, 210=>{:free=>false, :host=>"Uhura"}, 211=>{:free=>false, :host=>"McCoy"}, 212=>{:free=>false, :host=>"Riker"}}
reception_queue #=> ["LaForge"]

Ruby array access position in array

#product
returns a single record. By relationship this product belongs to a slot
#slot = Slot.where(['id = ?', #product.slot_id]).first
what needs to be accessed is the position x in the array of all #slots = Slot.order('id asc').all so that I can identify or iterate over the following n slots as per ruby array Class:
arr[x, n]
I am not sure I understand the question there are many methods of accessing the index for an Array e.g.
alphabet = ('a'..'z').to_a
alphabet[0]
#=> "a"
alphabet.values_at(2,3,12)
#=> ["c","d","m"]
alphabet.index('r')
#=> 17
alphabet.fetch(15)
#=> "p"
There are many more such as #at, #find_index, even #rindex which will look for the last occurance. If you need to iterate index's you can use each_index or each_with_index. Since your question does not truely explain the scenario all I can do is explain how to deal with Array indices. For a more pertinent answer please update your question to show both data and expected results.
Here is what I can gather from your question
#product = Product.find(some_id)
#slot = #product.slot
#slots = Slot.where("id > ?", #slot.id) #return all slots after the #product.slot
If want to get the Slot for a given Product you can just do this:
slot = #product.slot
assuming you have your relationships well defined.

Ruby randomly shuffle an array so that no element keeps its original place

I have an array that stores some names. Each person solves a task and then I want to assign each solution to a different person for verification. In short this means that I need to perform a shuffle in an array in a way that no element keeps its original place. The solution I thought of is to perform a shuffle in the array until the second condition is met and here is the code for it:
copied = names.dup
loop do
copied.shuffle!
valid = true
(0...copied.size).each do |i|
if copied[i] == names[i]
valid = false
break
end
end
break if valid
end
puts copied
Still I feel there may be a more optimal solution to this problem. Anyone has a better idea?
Looks like what you're trying to do is to create a map of {verifier => task_solver} where verifier != task_solver. A simple way to achieve this is simply have each person's verify the next person's task:
verifiers = {}
task_solvers.each_with_index do |task_solver, index|
verifiers[task_solver] = task_solvers[(index + 1) % task_solvers.size]
end
If you want a little bit more randomisation, you could use this, which uses the same algorithm but just shuffles your list before anything happens:
verifiers = {}
shuffled_task_solvers = task_solvers.shuffle
shuffled_task_solvers.each_with_index do |task_solver, index|
verifiers[task_solver] = shuffled_task_solvers[(index + 1) % shuffled_task_solvers.size]
end
What you are after might be called a derangement. Take a look here: http://rosettacode.org/wiki/Permutations/Derangements (There is an example in Ruby).
I think you need just one shuffle. After that if some element in the copied array is in its original place you can swap it with one of its neighbours (it is clear that new places of the two elements cannot be the same as original places).
Here is what I came up with. I don't know if it's any better though :P
list = [1,2,3,4,5,6,7,8]
def jumble (array)
new = array.shuffle
array.each_with_index do |item, index|
if new[index] == item
new[index], new[index - 1] = new[index - 1], new[index]
end
end
new
end
new = jumble (list)
puts new.inspect
Output:
[4, 1, 8, 3, 7, 2, 6, 5]

Ruby Is it possible to create directory for variables?

I am not sure how to put this question without it being wordy and confusing. I want to store a variable inside of another variable, and have those variables be specific to their home variable (basically creating a directory). Say I have three characters, Max, Sam, and Greg. I want to store how many treats each of these characters has.
So:
Max = [3 cookies, 4 donuts, 1 cakes]
Sam = [1 cookies, 5 donuts, 0 cakes]
Greg =[2 cookies, 4 donuts, 5 cakes]
And then later, I want to give or take away certain treats from a character, or ask how many of a certain kind of treat they have. How would I do this?
I want Max’s cookies to be independent from Sam’s cookies. However, I still want to be able to write a general method that can increase everyone’s cookies.
def givecookies
#cookies=(#cookies+1)
But then I want to be able to call how many cookies Max has. So, is there a way I can store a variable inside another variable, and then how do I call it? Like, instead of puts cookies, could I do something like puts (Max/cookies)?
I'm sorry for the awkwardness of the question. I've only been programming a few weeks, and I am still trying to pick up on the basics. There is probably a method out there for it, but I don't know what to look for.
You shell use hash-like structures, like Hash itself, Struct, or Hashie-based classes. I'd prefer to use, for example, Hashie gem and Hashie::Mash class as follows:
#h = Hashie::Mash.new
# ...
#h.Max = Hashie::Mash.new
#h.Max.cookies = 3
#h.Max.donuts = 4
#h.Max.cakes = 1
#h
# => #<Hashie::Mash Max=#<Hashie::Mash cakes=1 cookies=3 donuts=4>>
def givecookies
#h.each {|_,y| y.cookies += 1}
end
Or with built-in Struct:
s = Struct.new( :cookies, :donuts, :cakes )
#s = { :Max => s.new( 3, 4, 1 ),
:Sam => s.new( 1, 5, 0 ),
:Greg => s.new( 2, 4, 5 ) }
def givecookies
#s.each {|_,y| y.cookies += 1}
end
class Person
attr_accessor :name, :cookies
def initialize name, cookies = 0
#name = name
#cookies = cookies
end
end
p_max = Person.new 'Max', 3
puts "Max has #{p_max.cookies} cookies"
# ⇒ Max has 3 cookies
p_max.cookies += 2
puts "Max has #{p_max.cookies} cookies"
# ⇒ Max has 5 cookies
Hope it helps.

Creating and adding to arrays within a program -- Ruby

I'm a fairly new Ruby user and I was wondering how you create and edit arrays within a program. I'm making a sentence-generator-type program where you can add to arrays of nouns, verbs, and other sentence parts, but I'm currently not sure how to make the arrays in the first place.
Here's the code:
#!/usr/bin/ruby Make_a_Sentence!
#This will eventually create the sentence
def makeSent (*arg)
for i in 0...arg.length
print arg[i].sample if arg[i].kind_of?(Array)
print arg[i] if arg[i].kind_of?(String)
end
end
#this is supposed to add to the array (it's not working)
def addWord (array, word)
if array.kind_of?(Array)
array.push(word)
puts "#{ word } added to #{ array }"
else
puts "#{ array } does not exist"
end
end
#This is supposed to create the arrays
def addType (name)
#name = Array.new
puts "#{ name } created"
end
while 1 > 0
input = gets
$words = input.split
if $words[0] == "addWord" && $words.length == 3
addWord($words[1], $words[2])
end
if $words[0] == "addType" && $words.length == 2
addType($words[1])
end
end
**Sorry! I guess I didn't phrase the question well enough! I was mainly wondering how to create new arrays while the program is running, but the arrays have specific names that are given. I actually ended up just using hashes for this, but thanks for the responses nonetheless!
Making an Array is done like so:
array = ["val1","val2","val3"]
array = %w{value value value}
# The second example is a shorthand syntax (splits values with just a space)
Familiarize yourself with the documentation: http://www.ruby-doc.org/core-2.1.0/Array.html
Also when you're using methods like: def makeSent (*arg) just be aware that *args with the * in front of it - is what's called a splat. Which means this method takes many arguments without the [] syntax and automatically converts all of the arguments into an array for you.
So you would call this method like: makeSent (first, second, third, etc)
Creating arrays is easy: simply enclose the objects in square brackets, like so:
my_array = [12, 29, 36, 42]
another_array = ['something', 64, 'another', 1921]
Notice you can mix and match types within the array. If you want to add items to the end of the array, you can use << to do it:
my_array = [1, 3, 5, 7]
my_array << 9
# my_array is now: [1, 3, 5, 7, 9]
You can access and modify specific items within the array by indexing it within square brackets:
my_array[2] # <-- this will be 5, as arrays are 0-indexed
my_array[2] = 987
# my_array is now [1, 3, 987, 7, 9]
There are a lot of great methods for accessing, modifying, and comparing arrays that you can find in the documentation.

Resources