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.
Related
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
the problem is it cannot print all the text of the from a .txt file. I am able to print the first 3 lines of the txt file but not the rest. So far, I am getting an error which is in print_album': undefined local variable or methodtracks' for main:Object (NameError).
Here's the code:
*I know using global variable is no good in Ruby but this exercise ask me to do it.
module Genre
POP, CLASSIC, JAZZ, ROCK = *1..4
end
$genre_names = ['Null', 'Pop', 'Classic', 'Jazz', 'Rock']
class Album
# NB: you will need to add tracks to the following and the initialize()
attr_accessor :title, :artist, :genre, :tracks
# complete the missing code:
def initialize (atitle, aartist, agenre, arrtrk)
# insert lines here
#genre = agenre
#tracks = arrtrk
#title = atitle
#artist = aartist
end
end
class Track
attr_accessor :ttitle, :tlocation
def initialize (tname, tloc)
#ttitle = tname
#tlocation = tloc
end
end
# Reads in and returns a single track from the given file
def read_track music_file
mytrk_name = music_file.gets
mytrk_location = music_file.gets
mytrk = Track.new(mytrk_name, mytrk_location)
mytrk
end
# Returns an array of tracks read from the given file
def read_tracks music_file
count = music_file.gets().to_i
tracks = Array.new
$i = 0
# Put a loop here which increments an index to read the tracks
while $i < count do
track = read_track(music_file)
tracks << track
$i += 1
end
tracks
end
# Takes an array of tracks and prints them to the terminal
def print_tracks tracks
# print all the tracks use: tracks[x] to access each track.
$i = 0
while $i < tracks.length do
print_track(tracks[$i])
$i +=1
end
tracks
end
# Reads in and returns a single album from the given file, with all its tracks
def read_album music_file
# read in all the Album's fields/attributes including all the tracks
# complete the missing code
album_title = music_file.gets
album_artist = music_file.gets
album_genre = music_file.gets.to_i
tracks = read_tracks(music_file)
album = Album.new(album_title, album_artist, album_genre, tracks)
album
end
# Takes a single album and prints it to the terminal along with all its tracks
def print_album album
# print out all the albums fields/attributes
# Complete the missing code.
puts 'Album title is '+ album.title
puts 'Artist is ' + album.artist
puts 'Genre is ' + album.genre.to_s
puts $genre_names[album.genre]
# print out the tracks
print_tracks(tracks)
end
# Takes a single track and prints it to the terminal
def print_track track
puts('Track title is: ' + track.ttitle)
puts('Track file location is: ' + track.tlocation)
end
# Reads in an album from a file and then print the album to the terminal
def main
music_file = File.new("album.txt", "r")
album = read_album(music_file)
music_file.close()
print_album(album)
end
main
Here's is the album.txt
Greatest Hits
Neil Diamond
1
3
Crackling Rose
sounds/01-Cracklin-rose.wav
Soolaimon
sounds/06-Soolaimon.wav
Sweet Caroline
sounds/20-Sweet_Caroline.wav
Currently my output is :
Album title is Greatest Hits
Artist is Neil Diamond
Genre is 1
Pop
Expected output is :
Album title is Greatest Hits
Artist is Neil Diamond
Genre is 1
Pop
Track title is: Crackling Rose
Track file location is: sounds/01-Cracklin-rose.wav
Track title is: Soolaimon
Track file location is: sounds/06-Soolaimon.wav
Track title is: Sweet Caroline
Track file location is: sounds/20-Sweet_Caroline.wav
The problem is inside your def print_album album method. On the last line of the method it uses print_tracks(tracks), but tracks variable is undefined (that's exactly what error tells you).
You need to call print_tracks(album.tracks)
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
It stores the first employee, but when I try to add another employee I am unable to view the additional employees entered. Below is the method for viewing employee record. Thanks for any help!
Employee Class
class Employee
attr_accessor :employee, :role, :location
def initialize(employee, role, location)
#employee = employee
#role = role
#location = location
end
def employee_change(new_emp)
#employee = new_emp
end
def role_change(new_role)
#role = new_role
end.
def location_change(new_loc)
#location = new_loc
end
end
Main Menu
def main_menu
puts "Welcome to the Employee Portal"
puts "Please select an option below: "
puts "---------------------"
puts "1. Create New Employee Record."
puts "2. View an existing record."
puts "3. Modify an existing record."
puts "4. Exit Portal"
option = gets.chomp.to_i
if option == 1
create_record
main_menu
elsif option == 2
view_record
elsif option == 3
modify
elsif option == 4
puts "Thank you for using the Employee Portal"
exit
else
puts "Not a valid option. Please try again."
main_menu
system("clear")
end
end
Create New Employee (Option 1 from Main Menu)
def create_record
puts "Create New Employee Record, click 'Enter' to begin"
puts "Enter Employee Information: "
employee = gets.chomp.capitalize
puts "Enter Employee's Role: "
role = gets.chomp.capitalize
puts "Enter Employee's Current Work Location: "
location = gets.chomp.capitalize
puts "\n"
new_record = Employee.new(employee, role, location)
#record.push(new_record)
puts "New Employee Record has been created."
puts "Name: #{employee}"
puts "Role: #{role}"
puts "Location: #{location}"
system("clear")
main_menu
end
View Employee (Option 2 from Main Menu)
def view_record
puts "Enter Employee Name to view record: "
name = gets.chomp.capitalize
system("clear")
#record.each do |a|
if a.employee == name
puts "\n"
puts "Employee Information "
puts "--------------------"
puts " Name : #{a.employee}"
puts " Role(s) : #{a.role}"
puts " Location(s) : #{a.location}"
puts " Type 'Exit' to return to the Main Menu "
else
puts "That is not a valid entry, please try again."
view_record
main_menu
end
end
end
Modify Employee (Option 3 from Main Menu)
def modify
system("clear")
puts "Enter employee name to modify existing record: "
name = gets.chomp.capitalize
#record.each do |r|
if r.employee == name
puts "Employee found."
puts "Select an option to modify."
puts "-----------------------------------"
puts "1.) Modify employee's name."
puts "2.) Modify employee's role."
puts "3.) Modify employee's location."
puts "4.) Return to Main Menu"
puts "\n"
option = gets.chomp.to_i
if option == 1
change_employee
elsif option == 2
change_role
elsif option == 3
change_location
elsif option == 4
main_menu
else
puts "Invalid selection. Please try again."
modify
end
end
end
end
Change Employee (Option 1 from Modify)
def change_employee
puts "Enter new employee name: "
new_emp = gets.chomp.capitalize
#record.each do |r|
if r.employee == employee
r.employee_change(new_emp)
puts "#{r.employee} has been updated to #{r.employee}"
end
end
end
Change Employee Role (Option 2 from Modify)
def change_role
puts "What is #{r.employee}\'s new role?: "
new_role = gets.chomp.capitalize
#record.each do |r|
if r.employee == employee
r.role_change(new_role)
puts "#{r.employee}\'s new role is #{r.role}"
end
end
end
Change Employee Location (Option 3 from Modify)
def change_location
puts "What is #{r.employee}\'s new location?: "
new_loc = gets.chomp.capitalize
#record.each do |r|
if r.employee == employee
r.location_change(new_loc)
puts "#{r.employee} has been transfer to new location, #{r.location}."
end
end
end
Run the Program
#record = []
system("clear")
main_menu
The problem is with your view_record method. If you change it to look something like:
def view_record
puts "Enter Employee Name to view record: "
name = gets.chomp.capitalize
system("clear")
if a = #record.detect { |rec| rec.employee == name }
puts "\n"
puts "Employee Information "
puts "--------------------"
puts " Name : #{a.employee}"
puts " Role(s) : #{a.role}"
puts " Location(s) : #{a.location}"
puts " Type 'Exit' to return to the Main Menu "
else
puts "That is not a valid entry, please try again."
view_record
end
end
It works properly.
The problem was that you were calling the if...else statement on every record in #record. So if you create 2 Employees the first one named "John" and the second named "Jane". When you go to view "Jane", you call the else portion for "John", since he's the first record and then once he finishes the else you call the if portion for "Jane". The else for "John", however, never returns because after you finally finish a [possibly lengthy] stack of view_record calls, with the same issue, you then go back to main_menu which never returns (due to the final else condition in that method that re-calls main_menu)
Hope that helps and makes sense.
Notes:
The modify seems to have the same issue and the change_x methods will loop through and check each employee against the if statement, but since no else no problem (I'd still change them personally, to use the detect on these as well).
The change_x methods don't look like they would run, because employee isn't defined in them
If more than 1 employee can have the same name, you can use select instead of detect and then check for empty? or iterate through only those returned by select and call only the if portion on them.
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