In the gets portion at the lower half of the program, the terminal is not asking me for input but automatically taking input. I am unable to understand how this is happenening.
The Code is:
puts "Welcome to my automatic file opener"
puts "Version - 2.0"
if ARGV[0] && ARGV[1] #to ensure Arguements are given as input
old_data = File.open(ARGV[0]).readlines
new_data = File.open(ARGV[1]).readlines
class Differentiator
def old_stuff
puts "the old files are:-"
puts old_data
end
def new_stuff
puts "The new files are:-"
puts new_data
end
def updated_list
puts "The newly added files are:-"
newly_added = new_data - old_data
puts newly_added
end
def deleted_list
puts "The deleted files are:-"
deleted_data = old_data - new_data
puts deleted_data
end
def stable_list
puts "The unchanged/stable files are:-"
unchanged_data = new_data - newly_added
puts unchanged_data
end
end#end of class
while true
puts "Choose your option:"
puts "1.Old Files of System"
puts "2.New Files of System"
puts "3.Added Files of System"
puts "4.Deleted Files of System"
puts "5.Stable Lists"
puts "6.Exit"
print " Please Choose your Output:-"
**option_method=gets.chomp.to_i**
filecase1 = Differentiator.new
if option_method == 1
filecase1.old_stuff
end
if option_method == 2
filecase1.new_stuff
end
if option_method == 3
filecase1.updated_list
end
if option_method == 4
filecase1.deleted_list
end
if option_method == 5
filecase1.stable_list
end
if option_method == 6
break
exit
end
if option_method != (1..6)
puts "Sorry,Wrong Input"
end
end
else
puts "The Right Method of Usage is : ruby <scriptname>.rb old_file new_file"; exit;
end
Because you have to use $stdin.gets otherwise it will read the files given in ARGV.
It is written in the man page http://www.ruby-doc.org/core-2.0/Kernel.html in the first line talking about gets
Related
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
Hey the code I created only repeats 2 times.
After I type the second time "y" for the "continue_question"-method the code only stops.
def greeting
puts "Hello! Please type your name: "
name = gets.chomp.capitalize
puts "It is nice to meet you #{name}. I am a simple calculator application."
puts "I can add, subtract, multiply, and divide."
end
greeting
def calculator
puts "First number: "
#n1 = gets.chomp.to_i
puts "Secons number: "
#n2 = gets.chomp.to_i
def calculation
puts "Type 1 to add, 2 to subtract, 3 to multiply, or 4 to divide two numbers: "
operation_selection = gets.chomp.to_i
if operation_selection == 1
#result = #n1 + #n2
elsif operation_selection == 2
#result = #n1 - #n2
elsif operation_selection == 3
#result = #n1 * #n2
elsif operation_selection == 4
#result = #n1 / #n2
else
puts "Something went wrong!"
calculation
end
end
calculation
puts "Your Result is #{#result}"
end
calculator
def continue_question
puts "Do you want to continue? (y/n)"
continue = gets.chomp.to_s
if continue == "y"
calculator
elsif continue == "n"
puts "Bye!"
else
puts "What?"
continue_question
end
end
continue_question
Your code does not repeat 2 times, it repeats once.
The reason is because in your continue_question method, you do not tell it to repeat again:
def continue_question
puts "Do you want to continue? (y/n)"
continue = gets.chomp.to_s
if continue == "y"
calculator # <-- This causes it it repeat ONCE!
elsif continue == "n"
puts "Bye!"
else
puts "What?"
continue_question
end
end
A quick fix is to re-call the continue_question method below that line, to recursively repeat itself:
def continue_question
puts "Do you want to continue? (y/n)"
continue = gets.chomp.to_s
if continue == "y"
calculator
continue_question # <-- Add this to repeat indefinitely
elsif continue == "n"
puts "Bye!"
else
puts "What?"
continue_question
end
end
The problem is that continue_question only executes once, at the end of your code, but you need to loop until user exits (i.e types n).
So simply add a loop inside continue_question, for example:
def continue_question
continue = "y"
until continue == "n" do
puts "Do you want to continue? (y/n)"
continue = gets.chomp.to_s
if continue == "y"
calculator
elsif continue == "n"
puts "Bye!"
else
puts "What?"
end
end
end
Hey the code I created only repeats 2 times.
I think you misunderstand the following:
if continue == "y"
calculator
elsif continue == "n"
puts "Bye!"
When you call the above function calculator, you are still executing the continue_question function. So when the calculator finishes executing, continue_question will finish as well and the program will stop. For the wanted result you can try using a loop.
I'm having difficulty in adding underscores in my program. Also what is troubling me is that I can't seem to figure out how to remove the underscores when the user inputs the correct letter.
class Game
attr_reader :guess_count, :is_over, :word_length
def initialize (secret_word)
#secret_word = secret_word
#guess_count = 0
#is_over = false
#word_length = secret_word.length
end
def check_word(guess)
#guess_count += 1
if #secret_word == guess
puts "Congratulations!"
#is_over = true
else
#is_over = false
puts "Sorry, try again!"
end
end
def subtract_guess_count
counter = #word_length - #guess_count
end
end
puts "User 1, What is your secret word?"
secret_word = gets.chomp
anything = Game.new(secret_word)
while !anything.is_over
puts "User 2, Guess the secret word"
guess = gets.chomp
anything.check_word(guess)
if anything.subtract_guess_count == 0
puts "You lose! the correct word was #{secret_word}"
exit!
end
if anything.is_over == false
puts "You have #{anything.subtract_guess_count} left!"
end
end
Major Edit
To create a string of underscores you can do this:
word = ""
1.upto(#secret_word.length) do
word << "_"
end
To replace a character with an underscore (and vice versa) in a ruby string you can use the syntax:
word[i] = "_"
To print a word with spaces between each letter you can use the following:
array = word.split(//)
array.join(" ")
For your code a check_letter function could be useful:
def check_letter (guess)
if (#secret_word[guess])
for i in 0..((#secret_word.length) -1 )
if #secret_word[i] == guess
#progress[i] = guess
end
end
end
show_progress
check_word(#progress)
end
Working code
#! /usr/bin/env ruby
#
class Game
attr_reader :guess_count, :is_over, :word_length, :progress
def initialize (secret_word)
#secret_word = secret_word
#guess_count = 0
#is_over = false
#word_length = secret_word.length
#progress = ""
1.upto(secret_word.length) do
#progress << "_"
end
end
def check_word(guess)
if #secret_word == guess
puts "Congratulations!"
#is_over = true
else
#is_over = false
puts "Sorry, try again!"
end
end
def check_letter (guess)
if (#secret_word[guess])
for i in 0..((#secret_word.length) -1 )
if #secret_word[i] == guess
#progress[i] = guess
end
end
end
show_progress
check_word(#progress)
end
def show_progress
array = #progress.split(//)
word = ""
array.each do |letter|
word << letter + " "
end
puts word
end
def one_less_guess
#guess_count += 1
end
def subtract_guess_count
counter = #word_length - #guess_count
end
end
puts "User 1, What is your secret word?"
secret_word = gets.chomp
anything = Game.new(secret_word)
while !anything.is_over
puts "User 2, Guess the secret word"
guess = gets.chomp
anything.one_less_guess
if guess.length == 1
anything.check_letter(guess)
else
anything.check_word(guess)
end
if anything.subtract_guess_count == 0
puts "You lose! the correct word was #{secret_word}"
exit!
end
if anything.is_over == false
puts "You have #{anything.subtract_guess_count} left!"
end
end
I have a file check and sort script. Now I wanted the user to be to choose how he/she wishes to have the final output sorted. Sadly Ruby seems to ignore the gets command. If I comment out the entire section the script finishes just fine. Please ignore the def readout. I never finished that one....
So my question is: Why does Ruby skip over the gets command.
class Product
attr_reader :id, :name, :price, :stock
def initialize(id,name,price,stock)
#id = id
#name=name
#price=price
#stock=stock
end
def readout
self.each do |product|
print product.id
print "|"
print product.name
print "|"
print product.price
print "|"
print product.stock
puts ""
end
end
end
products = []
newproducts= []
if ARGV[0] != nil
if File.exist?(ARGV[0])
File.open(ARGV[0] , "r") do |f|
f.each_line do |line|
products << line
end
end
products.each do |product|
data = product.split(",")
newproducts.push(Product.new(data[0].strip, data[1].strip, data[2].strip.to_i, data[3].strip.to_i))
end
puts "What to sort by?"
question = gets.strip
if question == "name"
newproducts.sort! {|a,b| b.name <=> a.name}
elsif question == "price"
newproducts.sort! {|a,b| b.price <=> a.price}
elsif question =="id"
newproducts.sort! {|a,b| b.id <=> a.id}
elsif question == "stock"
newproducts.sort! {|a,b| b.stock <=> a.stock}
else
puts "Wrong Answer."
end
#End of File Check
else
puts "File #{ARGV[0]} does not exist."
end
if ARGV[1] != nil
File.open(ARGV[1], "w") do |f|
newproducts.each do |product|
puts "Added #{product.name} to the file."
data = {product.id, product.name, product.price, product.stock}
f.puts(data)
end
end
#End of ARGV check.
else
puts "No output file assigned."
end
#End of master ARGV check.
else
puts "No command given."
end
The Kernel#gets method reads from ARGF not $stdin. This means that if command line arguments were given (or more accurately if ARGV is not empty) it reads from the files in ARGV. Only otherwise does it read from stdin.
To always read from stdin, use $stdin.gets instead of gets.
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).