Rubocop Lint: Useless assignment to variable - ruby

This code runs perfectly in the console but the linters keep failing with the error below..
This is the error:
refactored.rb:17:5: W: Lint/UselessAssignment: Useless assignment to variable - user_name. Did you mean user_age?
user_name = gets.chomp
refactored.rb:14:5: W: Lint/UselessAssignment: Useless assignment to variable - user_age. Did you mean user_name?
user_age = Integer(gets.chomp)
^^^^^^^^
This is the code:
require './school-library/student'
require './school-library/rental'
require './school-library/persons'
require './school-library/teacher'
require './school-library/book'
class Methods
def initialize
#person_array = []
end
def user_input
print 'Age: '
user_age = Integer(gets.chomp)
print 'Name: '
user_name = gets.chomp
end
def create_person
puts 'Do you want to create a student (1) or a teacher (2)? [Input the number]: '
person_option = Integer(gets.chomp)
case person_option
when 1
(user_age, user_name) = user_input
print 'Has parent permission? [Y/N]: '
user_permission = gets.chomp.to_s.upcase
case user_permission
when 'Y'
user_permission = true
when 'N'
user_permission = false
end
student = Student.new(user_age, user_name, parent_permission: user_permission)
#person_array.push({
output: "[Student] Name: #{student.name}, ID: #{student.id}, Age: #{student.age}",
object: student
})
puts 'Person created successfully!'
puts "\n"
when 2
(user_age, user_name) = user_input
print 'Specialization: '
user_specialization = gets.chomp
teacher = Teachers.new(user_age, user_name, user_specialization)
#person_array.push({
output: "[Teacher] Name: #{teacher.name}, ID: #{teacher.id}, Age: #{teacher.age}",
object: teacher
})
puts 'Person created successfully!'
puts "\n"
else
puts 'Person not created.'
end
end
def people_list
#person_array.each do |person|
puts person[:output]
end
end
def person_rent
#person_array.each_with_index do |person, index|
puts "#{index}) #{person[:output]}"
end
end
end
class BooksList
def initialize
#books = []
end
def create_book
print 'Title: '
book_title = gets.chomp
print 'Author: '
book_author = gets.chomp
puts 'Book created successfully!'
book = Book.new(book_title, book_author)
#books.push({
output: "Title: #{book.title}, Author: #{book.author}",
object: book
})
end
def book_list
#books.each do |book|
puts book[:output]
end
end
def rent_book
#books.each_with_index do |book, index|
puts "#{index}) #{book[:output]}"
end
end
end

RuboCop is trying to tell you that a useless variable exists in your code, but before fix that we need to talk about a bug happening right here:
(user_age, user_name) = user_input
In Ruby, a method returns the last line of code. Looking at the method user_input we can see that it returns only the user_name variable. The problem is that the (user_age, user_name) expects two values. The first is being assigned, but the second is given nil.
To fix that, update the method user_input to:
def user_input
print 'Age: '
user_age = Integer(gets.chomp)
print 'Name: '
user_name = gets.chomp
[user_age, user_name]
end
This will fix both the RuboCop offense and the bug.

Related

JSON::ParserError in Ruby

Am trying to read data I just stored in the .json file, when running the script, am getting this error:
/Users/topazjos/.rvm/gems/ruby-3.0.0/gems/json-2.6.1/lib/json/common.rb:216:in `parse': 859: unexpected token at '[] (JSON::ParserError)
from /Users/topazjos/.rvm/gems/ruby-3.0.0/gems/json-2.6.1/lib/json/common.rb:216:in `parse'
from /Users/topazjos/Documents/SQL & Ruby Projects/school-library/savedata.rb:48:in `fetch_people_datas'
it is showing that the error is coming from thefecth_people_datas method
class IOmanager
def save_people(persons)
file = File.open('./people.json', 'a')
person_data = persons.map do |person|
if person.instance_of?(Teacher)
{ occupation: 'Teacher', name: person.name, age: person.age, specialization: person.specialization }
else
{ occupation: 'Student', name: person.name, age: person.age, parent_permission: person.parent_permission }
end
end
file.puts(JSON.generate(person_data))
end
def fetch_people_datas
return [] unless File.exist?('./people.json')
file = File.read('./people.json')
array = []
if file.empty?
array
else
person_data = JSON.parse(file)
person_data.map do |data|
if data['occupation'] == 'Teacher'
teacher = Teacher.new(data['age'], data['specialization'], data['name'])
array.push(teacher)
else
student = Student.new(data['age'], data['classroom'], data['name'], data['parent_permission'])
array.push(student)
end
end
end
array
end
end
then am calling that method like this
class CreatePeople
def initialize
#iomanager = IOmanager.new
#books = #iomanager.fetch_book_data
#persons = #iomanager.fetch_people_datas
#rentals = []
end
def create_student
puts 'Create a new student'
print 'Enter student age: '
age = gets.chomp.to_i
print 'Enter name: '
name = gets.chomp
print 'Has parent permission? [Y/N]: '
parent_permission = gets.chomp.downcase
case parent_permission
when 'n'
Student.new(age, 'classroom', name, parent_permission: false)
#persons << student
puts 'Student doesnt have parent permission, cant rent books'
when 'y'
student = Student.new(age, 'classroom', name, parent_permission: true)
#persons << student
puts 'Student created successfully'
end
end
def create_teacher
puts 'Create a new teacher'
print 'Enter teacher age: '
age = gets.chomp.to_i
print 'Enter teacher name: '
name = gets.chomp
print 'Enter teacher specialization: '
specialization = gets.chomp
teacher = Teacher.new(age, specialization, name)
#persons << teacher
puts 'Teacher created successfully'
end
def json_runner
#iomanager.save_book(#books)
#iomanager.save_people(#persons)
#iomanager.save_rental(#rentals)
end
end
I have used the same way to read from the previous file fecth_book_data inside the same class and it has worked but I don't understand what went wrong here

Why will this not iterate through the file like I want it to?

It will just output two blank lines to the screen when it should be printing the card id and the balance
I have completely re-written the code.
I have fiddled with that code for an hour
class RBC
def initialize
#args = ["Create a new card"]
#functions = ["create_rbc"]
puts "Do you have an RBC ID yet? Yes(0) No(1)"
hasrbc = gets.chomp.to_i
if hasrbc == 1
#balance = 5
create_rbc
else
login
end
end
def create_rbc
puts "\nGenerating your rbc\n\n"
puts "\nWelcome to your Ruby Binary Card(RBC)!\n\n"
puts "Your RBC will keep track of your RubyCredits(RC).\n"
puts "You will get paid RC for work apps, and pay for game apps.\n"
puts "If you lose track of your RBC ID, you can get a new one.\n"
puts "Doing this, however, will reset your balance to the default of $5\n\n"
puts "What is your name? Do first last\n"
#fullname = gets.chomp
#card_name = get_name_codec(#fullname)
#card_cipher = "#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}"
#card_id = "#{#card_name} - #{#card_cipher}"
instance_variable_set("#Id#{#card_cipher}", #balance)
puts "Write down your RBC ID: #{#card_id}"
file = File.open("Cards.rbc", "w")
file.puts #card_id
file.puts #balance
end
end
def get_name_codec(name)
names = name.split(" ")
fname = names[0]
lname = names[1]
fchar = fname.split(//)
fcodec = "#{fchar[0]}#{fchar[1]}"
name_codec = "#{fcodec}#{lname}"
return name_codec
end
def login
#found = false
puts "What is your RBC Id"
input = gets.chomp
File.open("Cards.RBC", "r") do |f|
f.each_line do |line|
if input == "#{line}"
#card_id = line.to_s
#found == true
elsif #found == true
#balance = line.to_i
end
end
end
puts "#{#card_id}#{#balance}"
end
RBC.new
Then the Cards.RBC
TiLan - 1122632527
5
I want it to print the balance and card Id.
It should give me my card id and then the balance like this:
0000...etc
5
input = gets.chomp removes the newline off the input, but f.each_line does not. So input == "#{line}" is comparing, for example, "1234" with "1234\n".
Chomp the line as well.
input = gets.chomp
File.open("Cards.RBC", "r") do |f|
f.each_line do |line|
line.chomp!
if input == line
#card_id = line
#found == true
elsif #found == true
#balance = line.to_i
end
end
end
You can debug this sort of thing by printing the values with p. This will show them as quoted strings and show any special characters including newlines.
p line
p input

Ruby Exceptions Initialize Error

I have to create a program where I have to ask the user for their first and last name on a single line. If the user puts only their first OR last name, it will be rejected through the exception. I keep getting an error at the end (below).
class MyNewException < Exception
attr_accessor :first, :last
def initialize (first, last)
#first = first
#last = last
end
end
print "Enter your first and last name:"
begin
first, last = gets.chomp.split
print "Hello," + first + " " + last + "!"
if last.size == 0
raise MyNewException, "Sorry, I didn't catch that! Try again:"
end
rescue MyNewException
puts "Sorry, I didn't catch that. Try again:"
retry
end
Keep getting an error:
testing.rb:15:in `+': no implicit conversion of nil into String (TypeError)
The raise() docs are faulty. You can do this:
puts "Enter your first and last name:"
name = gets.chomp
class MyNewException < Exception
def initialize(str)
super(str) #pass the value for the message property to the parent class
end
end
begin
raise MyNewException, "Sorry, I didn't quite catch that! Try again:"
rescue MyNewException => e
puts e.message
end
--output:--
Enter your first and last name:
Sarah Kim
Sorry, I didn't quite catch that! Try again:
Or:
puts "Enter your first and last name:"
name = gets.chomp
class MyNewException < Exception
attr_accessor :first, :last
def initialize(user_name, exception_message)
#first, #last = user_name.split
super exception_message
end
end
begin
raise MyNewException.new(name, "I didn't quite catch that! Try again:")
rescue MyNewException => e
puts e.message
puts e.first
puts e.last
end
--output:--
Enter your first and last name:
Sarah Kim
I didn't quite catch that! Try again:
Sarah
Kim
Here's how to write an infinite loop to get user input:
class Person
attr_accessor :first, :last
def initialize(first, last)
#first = first.capitalize
#last = last.capitalize
end
end
while true
puts "Enter your first and last name:"
first, last = gets.chomp.split
#Show what you got:
p first
p last
if first and last
#If no names were entered, both first and last will be nil.
#If one name was entered, first will evaluate to true and last will be nil.
#If two names were entered, first and last will evaluate to true.
#If two or more names were entered, first and last will evaluate to true.
user = Person.new first, last
break #jump to the line immediately after the infinite loop
end
puts "Sorry, you must enter both a first and a last name. Try again"
end
puts "Thanks #{user.first} #{user.last}!"
Create a loop that do your trial and error.
as for my answer I choose while loop
i = 0
while i < 1 do
if condition == true
# display your greetings then increment loop to end
i += 1
else
# display error message
end
end
So your code would be like this
class MyNewException < Exception
attr_accessor :first, :last, :valid
def initialize(first, last)
#first = first
#last = last
#valid = true
if first.empty? || last.empty? then
#valid = false
end
end
end
i = 0
while i < 1 do
print "Enter your first name: "
firstname = gets.chomp
print "Enter your last name: "
lastname = gets.chomp
name = MyNewException.new(firstname, lastname)
if name.valid then
puts "Greetings " << name.first << " " << name.last
i += 1
else
puts "I didn't quite catch that! Try again:"
end
end

I can't interpolate my hash because apparently it is nil class? Could anyone shed some light on this?

Is there an alternative to iteration or a condition I can make that will allow me to interpolate the values of just one hash? I've inspected the results of my input and apparently the array that i'm saving my hashes into disappears when there is only one hash. I've also tested the results and they're of Nil class.
def print_with_index(students)
students.each_with_index do |student, index|
index_plus_one = index + 1
puts "#{index_plus_one}. #{students[:name]} (#{students[:cohort]} cohort)"
end
end
How do i solve my problem and also why do hashes behave this way?
Full code:
def print_header
puts "The students of Villains Academy"
puts "--------------"
end
def print_footer(names)
puts "Overall, we have #{names.count} great students"
end
def input_students
puts "Please enter the names and then the cohort of the students"
puts "To finish, just hit return twice"
#created an empty array
students = []
#getting the first name
name = gets.chomp
cohort = gets.chomp.to_sym
if cohort.empty?
cohort = :november
end
if cohort !~ /january|february|march|april|may|june|july|august|september|october|november|december/
puts "Please enter a valid month"
puts "Warning months are case sensitive. Please enter in lowercase characters."
cohort = gets.chomp.to_sym
end
while !name.empty? do
# add the student hash to the array called students
students << {name: name, cohort: cohort}
if students.count > 1
puts "Now we have #{students.count} students"
else students.count == 1
puts "Now we have #{students.count} student"
end
#getting another name from the user
name = gets.chomp
cohort = gets.chomp.to_sym
if cohort.empty?
cohort = :november
end
if cohort !~ /january|february|march|april|may|june|july|august|september|october|november|december/
puts "Please enter a valid month"
puts "Warning months are case sensitive. Please enter in lowercase characters."
cohort = gets.chomp.to_sym
end
end
bycohort = students.sort_by { |v| v[:cohort] }
filter = students.select! { |student| student[:cohort] == :november }
puts bycohort #This allows me to see all of my hashes before they are filtered
puts ""
bycohort
filter
end
def print_with_index(students)
students.each_with_index do |students, index|
index_plus_one = index + 1
puts "#{index_plus_one}. #{students[:name]} (#{students[:cohort]} cohort)"
end
end
### body ###
students = input_students
print_header
print_with_index(students)
print_footer(students)
this works for me though, i think with each_with_index enum, you have to pass in an array of hashes i.e. [{...}, {...}, {...}], not a single hash with multiple keys-values
def print_with_index(students)
students.each_with_index do |students, index|
index_plus_one = index + 1
puts "#{index_plus_one}. #{students[:name]} (#{students[:cohort]} cohort)"
end
end
print_with_index([{name:"b", cohort: "c"}])
# 1. b (c cohort)
You should use student instead of students as the block parameter. You can check if the student object is nil.
def print_with_index(students)
students.each_with_index do |student, index|
if !student.nil?
index_plus_one = index + 1
puts "#{index_plus_one}. #{student[:name]} (#{student[:cohort]} cohort)"
end
end
end

Help! check_in': undefined method `push' for nil:NilClass (NoMethodError)

Hi Im getting an core error which is really standard I suppose in Ruby but dont know what to make of it. I have a program that I have written. Its purpose is to register guests at a camping. You have a menu with 5 different options. 1. Checkin. When i do this I get a undefined method generateParkingLot' for #<Camping:0x10030a768> (NoMethodError)
When I choose Checkout I get a undefined local variable or methoddeparture' for Menu:Class (NameError).
So please i someone has a clue to my problem it would be great. I will here paste all my code. The code is separated in different files and I have used require for the different files. Here though I will paste all the code in one trace. Thankful for all help.
-Sebastien
require 'guest'
require 'parking_lot'
class Camping
attr_accessor :current_guests, :parking_lots, :all_guests, :staticGuests
def initialize(current_guests, parking_lots, all_guests, staticGuests)
#current_guests = Array.new()
# initiera husvagnsplatserna
#parking_lots = Array.new(32)
32.times do |nr|
#parking_lots[nr] = Parking_Lot.new(nr)
#staticGuests = Array[
Guest.new("Logan Howlett", "Tokyo", "07484822",1, #parking_lots[0]),
Guest.new("Scott Summers", "Chicago", "8908332", 2, #parking_lots[1]),
Guest.new("Hank Moody", "Boston", "908490590", 3, #parking_lots[2]),
Guest.new("Jean Grey", "Detroit", "48058221", 4, #parking_lots[3]),
Guest.new("Charles Xavier","Washington DC", "019204822",5, #parking_lots[4])
]
end
#all_guests = []
#staticGuests.each do |guest|
#current_guests[guest.plot.nr] = guest
#all_guests.push(guest)
end
end
def to_s
# creates an empty string
list = " "
# loop from 1 to 32
(1..32).each do |n|
if (!#current_guests[n-1].nil?)
list += #current_guests[n-1].to_s
else
# else adds the text "Vacant"
list += n.to_s + ": Vacant!\n"
end
return list
end
def generateParkingLot
randomNr = 1+rand(32)
# exists a guest at the (0-based) position?
if (!#current_guests[randomNr-1].nil?)
# if so generate a new figure
generateEmpty(array)
else
# returns the generated number
return randomNr
end
end
end
end
class Guest
attr_accessor :firstname, :lastname, :address, :phone, :departure
attr_reader :arrived, :plot
def initialize (firstName, lastName, address, phone, plot)
#firstName = firstName
#lastName = lastName
#address = address
#phone = phone
#arrived = arrived
#plot = plot
end
def to_s
"Personal information:
(#{#firstName}, #{#lastName}, #{#address}, #{#phone}, #{#arrived}, #{#departure}, #{#plot})"
end
end
require 'ruby_camping'
require 'camping_guests'
class Main
if __FILE__ == $0
$camping = Camping.new(#current_guests, #all_guests, #parking_lots,#staticGuests)
puts "\n"
puts "Welcome to Ruby Camping!"
while (true)
Menu.menu
end
end
end
require 'date'
require 'camping_guests'
require 'guest'
class Menu
def initialize(guests = [])
#camping = Camping.new(guests)
end
def self.menu
puts "---------------------------"
puts " Menu"
puts " 1. Checkin"
puts " 2. Checkout"
puts " 3. List current guests"
puts " 4. List all guests"
puts " 5. Exit\n"
puts ""
puts " What do you want to do?"
puts "---------------------------"
print ": "
action = get_input
do_action(action)
end
# fetches menu choice and returns chosen alternativ
def self.get_input
input = gets.chomp.to_i
while (input > 5 || input < 1) do
puts "Ooups, please try again."
input = gets.chomp.to_i
end
return input
end
def self.do_action(action)
case action
when 1:
check_in
when 2:
check_out
when 3:
puts $camping.current_guests
when 4:
puts $camping.all_guests
when 5:
puts "You are now leaving the camping, welcome back!"
exit
end
end
def self.check_in
puts "Welcome to the checkin"
puts "Please state your first name: "
firstName = gets.chomp
puts "Please state your last name:"
lastName = gets.chomp
puts "Write your address: "
address = gets.chomp
puts "and your phone number: "
phone = gets.chomp
puts "finally, your arrival date!"
arrived = gets.chomp
newPLot = $camping.generateParkingLot
newGuest = Guest.new(firstName, lastName, address, phone,arrived,$camping.parking_lots[newPLot-1])
$camping.current_guests[newPLot-1] = newGuest
#all_guests.push(newGuest)
puts "The registration was a success!! You have received the " + newPLot.to_s + "."
end
def self.check_out
puts "Welcome to checkout!"
puts $camping.all_guests
puts "State plot of the person to checkout!"
plot = gets.chomp.to_i
puts "Ange utcheckningsdatum: "
departureDate = gets.chomp.to_i
guest = $camping.current_guests[plot-1]
#departure = departure
guest.departure = departureDate
guestStayedDays = departureDate - guest.arrived
guest.plot.increase(guestStayedDays)
puts guest
$camping.current_guests[plot-1] = nil
end
end
class Parking_Lot
attr_accessor :nr
attr_reader :electricity_meter
def initialize (nr)
#nr = nr
#electricity_meter = 4000-rand(2000)
end
def increase_meter(days)
generatedUse = (10+rand(70))*days
puts "Increases the meter with " + generatedUse.to_s + " kWh."
#electricity_meter += generatedUse
end
def to_s
"Plot #{#nr+1} Electricity meter: #{#electricity_meter} kWh"
end
end
It looks (although I haven't tried this out) like some of your your 'end's are wrong.
The one which is causing your first error (generateParkingLot undefined) is that generateParkingLot is actually defined inside to_s, so you need an extra 'end' at the end of your to_s method.
As for the second error (departure not recognised), the folowing line in self.check_out is at fault:
#departure = departure
because there is no 'departure' variable. (Perhaps you meant DepartureDate?). I suspect there may be a few other issues with this code, but I'm afraid I don't really have time to check now.
One I noticed was that when you have
32.times do |nr|
#parking_lots[nr] = Parking_Lot.new(nr)
I think you might want to end that, either with an 'end' or curly brackets, e.g.
32.times do |nr|
#parking_lots[nr] = Parking_Lot.new(nr)
end
Although that would make your other blocks not match.. In general, just try and make sure your blocks are all defined properly (e.g. everything has a matching end).

Resources