Adding an Array to an Array Ruby - arrays

Im trying to learn how to add arrays into arrays, I have the following code:
puts "would you like to save a data set"
response = gets.chomp
if response == "y"
puts "create a new dataset?"
create_data_set = gets.chomp
while create_data_set == "y"
puts "what do you want to name the data set?"
dataset = gets.chomp
dataset = Array.new
puts 'would you like to add some grades to the array?'
store_grades_response = gets.chomp
while store_grades_response == "y"
puts 'enter grade ->'
grade = gets.chomp.to_i
dataset << grade
puts 'would you like to store another grade?'
store_grades_response = gets.chomp
end
all_data_sets = Array.new
all_data_sets.push(dataset)
puts "would you like to create a new data set?"
create_data_set = gets.chomp
end
end
puts all_data_sets
Im basically asking a user to enter a array name which should create an array, add values to the array and if required by the user add some more arrays and values to it. At last the array should be added to an array. And then I'm trying to display all the arrays.
The code works fine, I'm looping through everything but when it puts all_data_sets It only shows the last array that was created? i would like to store all the arrays within the one array called all_data_sets

The problem is that you are creating a new array all_data_sets at the end of each loop. One solution will be to have it before the loop.
puts "would you like to save a data set"
response = gets.chomp
all_data_sets = []
if response == "y"
puts "create a new dataset?"
create_data_set = gets.chomp
while create_data_set == "y"
puts "what do you want to name the data set?"
dataset = gets.chomp
dataset = Array.new
puts 'would you like to add some grades to the array?'
store_grades_response = gets.chomp
while store_grades_response == "y"
puts 'enter grade ->'
grade = gets.chomp.to_i
dataset << grade
puts 'would you like to store another grade?'
store_grades_response = gets.chomp
end
all_data_sets << dataset
puts "would you like to create a new data set?"
create_data_set = gets.chomp
end
end
puts all_data_sets
This way, you keep pushing the datasets into the all_data_sets after each loop.
I hope this is explanatory enough.

Fix
Its because your create new_data_sets array each time you do the loop, declare it outside enclosing while loop
Code
def main
mainDataSet = [] # All datasets
dataSetNames = [] # Incase you want to store data set names
response = getInput("Would you like to save a data set")
if(response == "y")
choice = getInput("Create a new dataset?")
while choice == "y"
dataset = getInput("What do you want to name the data set?")
dataSetNames << dataset
dataset = []
choice_2 = getInput("would you like to add some grades to the array?")
while choice_2== "y"
grade = getInput("Enter grade")
dataset << grade
choice_2 = getInput("Store another grade?")
end
mainDataSet << dataset
choice = getInput("Create a new data set?")
end
end
puts mainDataSet
puts dataSetNames
end
def getInput(message)
puts "#{message} -> "
gets.chomp
end
Hope this helps.

you can concat, prepend or append arrays just like this
dataset.concat all_dataset
dataset + all_dataset
Concat documentation
prepend or append
dataset.push(*all_dataset)
all_dataset.unshift(*dataset)
Array stuffs
Also you can do slice and whole bunch of stuffs check at the ruby docs link

Related

Output display as null (Ruby)

Here when we print array elements it display null value all time like "[nil, nil, nil, nil]"
Values are not getting stored in array.
class Flight
def initilize(flight_id, flight_num, flight_orgin, flight_destination)
#id= flight_id
#number = flight_number
#origin = flight_origin
#destination = flight_destination
end
def read_flight()
puts "enter flight id"
flight_id = gets.chomp
puts "enter flight number"
flight_number = gets.chomp
puts "enter flight origin location"
flight_origin = gets.chomp
puts "enter destination"
flight_destination = gets.chomp
end
def print_flight(id, number, orgin, destination)
puts "_____Flight details______"
puts "Flight_id :#{id}"
puts "Flight_number :#{number}"
puts "Flight_orgin :#{orgin}"
puts "Flight_destination:#{destination}"
end
def read_flights(id, number, orgin, destination)
puts "_______Array of flights______"
flightid = Array.new
flightid.push(id, number, orgin, destination)
puts "#{flightid}"
end
end
input_flight = Flight.new
input_flight.read_flight
input_flight.print_flight(#id, #num, #orgin, #destination)
input_flight.read_flights(#id, #num, #orgin, #destination)
Without using a class or instance variable we want to do it
User input
enter flight id
2
enter flight number
2342
enter flight origin location
cochin
enter destination
tvm
output
Flight details_
Flight_id :
Flight_number :
Flight_orgin :
Flight_destination:
_Array of flights
[nil, nil, nil, nil]
The #id, #num, #orgin, #destination parameters will be nil if you don't set them anywhere.
So when you make these two calls:
input_flight.print_flight(#id, #num, #orgin, #destination)
input_flight.read_flights(#id, #num, #orgin, #destination)
You basically just send nils into the function:
input_flight.print_flight(nil, nil, nil, nil)
input_flight.read_flights(nil, nil, nil, nil)
If you want to access the variables read from the input:
First, you need to store them somewhere. For ex: store them inside the instance variables when read_flight function is called.
Then, refer the instance variable when you want to push values in the array.
Ex:
def read_flight
puts "enter flight id"
#id = gets.chomp # store inside instance variable
puts "enter flight number"
#number = gets.chomp
puts "enter flight origin location"
#origin = gets.chomp
puts "enter destination"
#destination = gets.chomp
end
def read_flights
...
flightid.push(#id, #number, #origin, #destination) # access instance variables here
...
end
You can learn more about Ruby's variable scoping (instance variables, global variables, etc) here: https://www.techotopia.com/index.php/Ruby_Variable_Scope
Here is my version of adjustion:
class Flight
attr_reader :id, :number, :origin, :destination
def read_flight
puts "enter flight id"
#id = gets.chomp
puts "enter flight number"
#number = gets.chomp
puts "enter flight origin location"
#origin = gets.chomp
puts "enter destination"
#destination = gets.chomp
end
def print_flight
puts "_____Flight details______"
puts "Flight_id :#{id}"
puts "Flight_number :#{number}"
puts "Flight_orgin :#{origin}"
puts "Flight_destination:#{destination}"
end
def read_flights
puts "_______Array of flights______"
flightid = [id, number, origin, destination]
puts "#{flightid}"
end
end
input_flight = Flight.new
input_flight.read_flight
input_flight.print_flight
input_flight.read_flights
Explanation:
Each instance of ruby class can have as many instance variables (which begin with #) as possible. Those instance variables live in an instance so they keep their value across the methods.
So you should assign the value you want to instance variables, for example:
#id = gets.chomp
then use it in another method:
def print_flight
puts "_____Flight details______"
puts "Flight_id :#{#id}"
end
However, add # everytime we want to use the instance variables is pretty tedious. That's why attr_reader comes in. When you write attr_reader:
attr_reader :id, :number, :origin, :destination
You actually declare 4 methods inside Flight:
def id
#id
end
def number
#number
end
def origin
#origin
end
def destination
#destination
end
Then you can just use id, number, origin, destination without the leading #`
You're initializing with nil values in your constructor (def initialize), to fix that you can pass the values to the .new or change the read_flight as follows:
def read_flight()
puts "enter flight id"
#flight_id = gets.chomp
puts "enter flight number"
#flight_number = gets.chomp
puts "enter flight origin location"
#flight_origin = gets.chomp
puts "enter destination"
#flight_destination = gets.chomp
end
This will modify the class-scoped variables.
Or alternatively you can have default values in the constructor (not recommended) using the || operator:
def initilize(flight_id, flight_num, flight_orgin, flight_destination)
#id= flight_id || 0
#number = flight_number || 0
#origin = flight_origin || ""
#destination = flight_destination || ""
end
First of all, be careful, because you did a lot of little but important mistakes. It's ok, we all started like that)
For example, your 'initialize' method name is not correct!
Your: 'initilize'
Correct: 'initialize'
It's important to name default methods correct.
Also, when you initialize variables with method arguments:
def initilize(flight_id, flight_num, flight_orgin, flight_destination)
#id= flight_id
#number = flight_num #you have to name it just like argument in method not flight_number, because it does not exist at all
#origin = flight_origin #same here, you forgot one letter
#destination = flight_destination
end
If you want user to initialize your instances then don't initialize them by yourself, delete arguments in initialize method.
Also, you can use instance variables in entire class, it's really helpful!
So, i corrected a little:
class Flight
def read_flight
puts "enter flight id"
#id = gets.chomp
puts "enter flight number"
#number = gets.chomp
puts "enter flight origin location"
#origin = gets.chomp
puts "enter destination"
#destination = gets.chomp
end
def print_flight
puts "_____Flight details______"
puts "Flight_id : " + #id.to_s
puts "Flight_number : " + #number.to_s
puts "Flight_origin : " + #origin
puts "Flight_destination: " + #destination
end
def read_flights
puts "_______Array of flights______"
flightid = Array.new
flightid.push({ #id,#number,#origin,#destination })
puts "#{flightid}"
end
end
Check:
input_flight = Flight.new
input_flight.read_flight
input_flight.print_flight
input_flight.read_flights

I want to list "user inputs" with using method

So i create a new class and i have a lot of objects in this class such as name, surname age etc.
But i am geting the same error everytime. And also i do not now how to list my arrays with using method.
Error: no implicit conversion of Array into String
def main
patients = []
puts "What do you want to do \nadd \nlist \nexit"
process = gets.chomp
if process == "add"
puts "Please enter patient's name"
patient1 = Patient_Covid_19.new()
patient1.Name = gets.chomp.to_s
patient1.Name << patients #error line
elsif process == "list"
#And i want to print the arrays(patients, ages, surnames etc.) in here but using a method.
elsif process == "exit"
puts "Have a nice day"
else
puts "Please enter add, list or exit"
main
end
end
main
Edit: It was small syntax mistake(error line). But i still need help for the list process.
You probably meant to do patients << patient1.Name.
You can loop over and print out attributes as follows:
patients.each do |patient|
puts "Name: #{patient.Name}, etc"
end
class Patient_Covid_19
attr_accessor :Ssn, :Name, :Surname, :Sex, :Age
end
def main
patients = []
puts "What do you want to do \nadd \nlist \nexit"
process = gets.chomp
if process == "add"
puts "Please enter patient's name"
patient1 = Patient_Covid_19.new()
patient1.Name = gets.chomp.to_s
patients << patient1.Name
main
elsif process == "list"
elsif process == "exit"
puts "Have a nice day"
else
puts "Please enter add, list or exit"
main
end
end
main
This is my code. When the user writes Add, he will enter the patient's information from the console and this information will be added to an array. When the user writes list, he/she will be able to see the information of the patients he has written before. I want to do the listing with a method.

How to solve Ruby Wizardry "Staying in the loop" example program?

The book Ruby Wizardry Chapter 4 includes the following sample program
we_wanna_ride = true
stops = ["East Bumpspark", "Endertromb Avenue", "New Mixico", "Mal Abochny"]
while we_wanna_ride
print "Where ya headin', friend?"
destination = gets.chomp
if stops.include? destination
puts "I know how to get to #{destination}! Here's the station list:"
stops.each do |stop|
puts stop
break if stop == destination
end
else
puts "Sorry, we don't stop at that station. Maybe another time!"
we_wanna_ride = false
end
end
It then goes on to pose a few additional challenges:
"What if a passenger is going the other way on the train (for instance, from Mal Abochny to East Bumpspark)? How could you update your program to work in both directions? Even trickier, what if the train route is a big circle (meaning if a passenger goes from East Bumpspark to Mal Abochny, the next stop after Mal Abochny should be East Bumpspark again)? How could you update your program to print out the right list of train stops if a passenger wants to go all the way around the circle?"
Does anybody have any ideas how to proceed here ? I'm a beginning programmer so any help would be greatly appreciated. Here's my progress so far. I figured I would get a departure from the user and then use to.i to get the input into an integer. I could then use the integer value to compare to the index position in the array. If the rider wants to go in the opposite direction I could use something like stops.each.reverse to print out the array items in reverse order.
we_wanna_ride = true
stops = ["East Bumpspark(1)", "Endertromb Avenue(2)", "New Mixico(3)", "Mal Abochny(4)"]
puts "#{stops}"
while we_wanna_ride
print "Select a destination number"
destination = gets.chomp.to_i
print "Select a departure number"
departure = gets.chomp.to_i
if departure <= destination
stops.each do |stop|
puts stop
break if stop == destination
end
else puts "Sorry"
we_wanna_ride = false
end
end
Here is how I solved this challenge. It works but is rather lengthy. More advanced ruby coders may be able to provide a shorter solution:
we_wanna_ride = true
stops = ["East Bumpspark", "Endertromb Avenue", "New Mixico", "Mal Abochny"]
while we_wanna_ride
print "Where do you wish to depart from?: "
depart = gets.chomp.split.map(&:capitalize).join(' ')
depart_index = stops.index(depart)
# puts depart_index
print "Where ya headin' friend?: "
destination = gets.chomp.split.map(&:capitalize).join(' ')
destination_index = stops.index(destination)
# puts destination_index
index_diff1 = depart_index - destination_index
index_diff2 = destination_index - depart_index
if stops.include? destination && depart
puts "\nI know how to get to #{destination}! Here's the station list:"
if destination_index > depart_index && index_diff2 < 3
stops[depart_index..-1].each do |stop|
puts stop
break if stop == destination
end
we_wanna_ride = false
elsif destination_index > depart_index && index_diff2 >= 3
dubstops = stops.concat(stops)
dubstops[0..depart_index+4].reverse_each do |stop|
puts stop
break if stop == destination
end
we_wanna_ride = false
elsif destination_index < depart_index && index_diff1 < 3
stops[0..depart_index].reverse_each do |stop|
puts stop
break if stop == destination
end
we_wanna_ride = false
elsif destination_index < depart_index && index_diff1 >= 3
dubstops = stops.concat(stops)
dubstops[depart_index..-1].each do |stop|
puts stop
break if stop == destination
end
we_wanna_ride = false
end
else
puts "Sorry, we don't service that station. Maybe another time!"
we_wanna_ride = false
end
end

Ruby, how can i compare a string with a specific element of array?

I create an array from a text file which contains the english irregular verbs. I want the code to ask me the verbs in random order letting me proceed only if I respond correctly. I need to compare a string with an element of array. I wrote this:
a = []
File.open('documents/programmi_test/verbi.txt') do |f|
f.lines.each do |line|
a <<line.split.map(&:to_s)
end
end
puts ''
b = rand(3)
puts a[b][0]
puts 'infinitive'
infinitive = gets.chomp
if infinitive = a[b][1] #--> write like this, I receive alway "true"
puts 'simple past'
else
puts 'retry'
end
pastsimple = gets.chomp
if pastsimple == a[b][2] #--> write like this, I receive alway "false"
puts 'past participle'
else
puts 'retry'
end
pastpart = gets.chomp
if pastpart == a[b][3]
puts 'compliments'
else
puts 'oh, no'
end
can somebody help me?
if infinitive = a[b][1] is assigning to inifinitive the value of a[b][1], unlike pastsimple == a[b][2] that's a comparation between both values.
You could try replacing the = for ==.
a = []
File.open('documents/programmi_test/verbi.txt') do |file|
file.lines.each do |line|
a << line.split.map(&:to_s)
end
end
puts ''
b = rand(3)
puts a[b][0]
puts 'infinitive'
infinitive = gets.chomp
puts infinitive == a[b][1] ? 'simple past' : 'retry'
pastsimple = gets.chomp
puts pastsimple == a[b][2] ? 'past participle' : 'retry'
pastpart = gets.chomp
puts pastpart == a[b][3] ? 'compliments' : 'oh, no'

Class-Array Interaction Ruby

I'm trying to set up a program to help me take care of grading for students in a class. I've set it up to make a class of student then to read in from the file (something I'm not very familiar with in Ruby) via an array. My programming experience is in java so if there are errors that can be explained by that I apologize. Thank you in advance for your help.
class Student
def initialize(str_LastName, str_FirstName, arr_Score)
#str_LastName = str_LastName
#str_FirstName = str_FirstName
#arr_Score = arr_Score
str_Grade = ""
int_OutOf = 415
end
def get_LastName
str_LastName
end
def get_FirstName
str_FirstName
end
def get_Grade
str_Grade
end
def set_TotalScore()
sum = 0
arr_Score.each do |item|
sum += item
end
arr_Score[12] = sum
end
def set_Grade
if arr_Score[12]/int_OutOf >= 0.9
str_Grade = "A"
elsif arr_Score[12]/int_OutOf >= 0.8
str_Grade = "B"
elsif arr_Score[12]/int_OutOf >= 0.7
str_Grade = "C"
elsif arr_Score[12]/int_OutOf >= 0.6
str_Grade = "D"
else
str_Grade = "F"
end
end
end
def main
file_name = "Grades"
arr_students = Array.new(31)
arr_scores = Array.new(12)
int_i = 0
file_io = open(file_name).readlines.each do |line|
array = line.split(",").map(&:strip)
student = Student.new(array[0],array[1],array[2..-2]) #the final element in the array is for the final score
arr_students[int_i] = student
puts "read #{arr_students[int_i]}"
end
file_name = "Graded"
file_io = open(file_name,"a+")
arr_students.each do |student|
set_TotalScore
set_Grade
file.io_write(student)
puts "write #{student}"
end
end
main if __FILE__==$0
Here is my run at it. I tried to stay true in general to the original intent of your code while introducing more Rubyish ways of doing things.
class Student
def initialize(firstname, lastname, *scores)
#firstname, #lastname, #scores = firstname, lastname, scores
end
def total_score
#scores.map(&:to_i).inject(:+)
end
def grade
raise "TOO HIGH!" if total_score > MAX_SCORE
case total_score / MAX_SCORE
when 0.9..1.0; "A"
when 0.8...0.9; "B"
when 0.7...0.8; "C"
when 0.6...0.7; "D"
else "F"
end
end
def to_s
"#{#lastname}, #{#firstname}: #{total_score}, #{grade}"
end
end
MAX_SCORE = 415.0
DATA.each_line do |line|
arr = line.split(",").map(&:strip)
student = Student.new *arr
puts student
end
__END__
Herb,Goldberg,22,99,44,22,88,88
Mark,Sullivan,77,88,88,44,33
You can read and write to files like this(not tested):
outfile = File.open("Graded", "a+")
File.open("Grades").each_line do |line|
...
outfile.puts student
end
outfile.close
We can not easily reproduce your code because you open a file called "Grades" and we do not have or know of its content.
You should also add some code to first check whether your file exists, before continuing - right now your script exits with a Errno::ENOENT.
I would also suggest putting the logic in main into your class instead - let your class handle everything.
In the part:
if __FILE__ == $PROGRAM_NAME
end
You can then simply initialize your class with a simple call such as:
Foobar.new(ARGV)
You described the "Grades" file but I did not understand what you wrote - it would be easier if you could link in to a sample, like via a pastie or gist, then link it in; and to also say what the part is that is not working, which is also unclear.
The style issues are secondary, I consider your code ok - the other poster here does not.
You should go through codecademy to get your ruby syntax down.
To access your initialized instance variables (#str_LastName (which should be #last_name), etc) you need to use "attr_reader :str_LastName", preferably at the top of the class. That'll definite you getter (setter is attr_writer, both is attr_accessor).
You can also do a sum on an array like this: [1,4,6,7].inject(:+).
Does Java not allow case statements? You should use that in set_grade. You also don't need to initialize str_Grade. In set grade, you could do #grade_letter ||= "A", and then calling set_grade will return that value on each call.
I didn't look through your main method. It's ugly though. Ruby methods probably shouldn't be more than 5 lines long.

Resources