Ruby puts command creates a new line in bash - ruby

When I put the final puts command in the code :
#!/usr/bin/env ruby
#Este comando cita sua idade e nome
puts "digite sua idade:"
idade = gets.to_i
puts "digite seu nome:"
nome = gets
puts "Olá #{nome}! você nasceu em #{2021-idade}"
and run it on bash, it creates a new line inside the line.
how to make it to be just one line?
bash image

The print method will continue to output on the same line.
puts will always add a new line.
There is a great reference here: https://flexiple.com/puts-vs-p-vs-print-ruby/
You can also always check the documentation:
puts - https://www.rubydoc.info/stdlib/core/IO:puts
"Note that puts always uses newlines"
print- https://www.rubydoc.info/stdlib/core/IO:print
If you are worried about the input having a new line, check out gets.chomp
https://www.rubyguides.com/2019/10/ruby-chomp-gets/
puts "digite sua idade:"
idade = gets.to_i
puts "digite seu nome:"
nome = gets.chomp #<- add .chomp here to remove \n from input
puts "Olá #{nome}! você nasceu em #{2021-idade}"

I'm assuming there's a typo in your code, and it's supposed to be:
#!/usr/bin/env ruby
#Este comando cita sua idade e nome
puts "digite sua idade:"
idade = gets.to_i
puts "digite seu nome:"
nome = gets
puts "Olá #{nome}! você nasceu em #{2021-idade}"
The newline appears after the name because gets includes the newline character, which you then interpolate into the string you're printing. You can use #chomp or #strip to remove the newine (and potentially any unwanted whitespace around the input. You can see this by calling these in irb.
irb(main):003:0> gets
hello
=> "hello\n"
irb(main):004:0> gets.chomp
hello
=> "hello"
irb(main):005:0> gets.strip
hello
=> "hello"
irb(main):006:0>

Related

Converting file to string and replacing string text with user input

I need to replace placeholders NOUN, VERB, ADJ, and ADV in a file solution09.txt with user input.
Madlib solution09.txt:
One day I was watching my son [ADV] play with his [NOUN]. He was pretending the [NOUN] were [ADJ]. After a few minutes he was pretending to [VERB], because one of the [NOUN] drove away. When i asked him about it he [ADV] said, umm it's funny when [NOUN] [VERB] because [NOUN] can't really [VERB].
I think I successfully put the file into a string, but I have to read the string, and replace the placeholders with user input. Once I replace, I need to output the new madlib. I'm getting the user input into variables, but I'm not sure how to correctly replace the placeholder with the users input.
Current code:
file = File.open("solution09.txt", "r")
contents = file.read
puts "Enter a noun: "
noun = gets.chomp
puts "Enter a verb: "
verb = gets.chomp
puts "Enter an adjective: "
adj = gets.chomp
puts "Enter an adverb: "
adv = gets.chomp
if file.include?('NOUN')
file1= file.gsub("[NOUN]", noun, "[VERB]", verb, "ADJ", adj, "ADV", adv)
end
You can also build a replacement hash:
filename = "solution09.txt"
contents = File.read(filename)
replacements = {}
puts "Enter a noun: "
replacements['[NOUN]'] = gets.chomp
puts "Enter a verb: "
replacements['[VERB]'] = gets.chomp
puts "Enter an adjective: "
replacements['[ADJ]'] = gets.chomp
puts "Enter an adverb: "
replacements['[ADV]'] = gets.chomp
And pass it to gsub:
contents.gsub(Regexp.union(replacements.keys), replacements)
Regexp.union creates a pattern that matches any of the given keys.
Your code should look like
filename = "solution09.txt"
contents=File.read(filename)
puts "Enter a noun: "
noun=gets.chomp
puts "Enter a verb: "
verb=gets.chomp
puts "Enter an adjective: "
adj=gets.chomp
puts "Enter an adverb: "
adv=gets.chomp
if contents.include?('NOUN')
{ "\[NOUN\]" => noun,
"\[VERB\]" => verb,
"\[ADJ\]" => adj,
"\[ADV\]" => adv
}.each do |key, value|
contents.gsub!(key, value)
end
File.open(filename, "w") { |f| f << contents }
end
You need separate operation for read and write. There are other ways to do this
You can see how to do with single file pointer https://stackoverflow.com/a/10173112/1380263
You can also use ruby methods which interact with shell and use sed command (system, backticks, peopen)
Really depends on what suits your situation the best
file = File.read("solution09.txt")
.gsub(/\[(NOUN|VERB|ADJ|ADV)\]/) do
part = case $1
when "NOUN" then "a noun"
when "VERB" then "a verb"
when "ADJ" then "an adjective"
when "ADV" then "an adverb"
end
puts "Enter #{part}: "
gets.chomp
end

Ruby case usage taking Array

I'm having problem with this case statement, the scenario is the follow
subDomainBlock are multi-line strings coming from other function and they are like
"fo-ds-ats.member.g02.yahoodns.net has address 98.139.21.169
fo-ds-ats.member.g02.yahoodns.net has IPv6 address 2001:4998:58:2201::50
Host wiki.yahoo.com not found: 3(NXDOMAIN)"
The complete function involve is
def data_filter(subDomainBlock)
line = subDomainBlock.split("\n")
#puts " yo soy #{line.class}"
line.each do | choise |
puts "-------------------"# puts "#{choise}#{choise.class}"
case choise
when choise.include?('not found')
nil
when choise.include?('has address')
puts "tiene una di"
when choise.include?('is an alias')
puts "es un alias"
when choise.include?('IPv6')
else
puts choise
end
end
end
I also tried to do the #{choise.include?('XXXXXXX')} but doesn't work.
Don't pass a variable to the case condition
case
when choise.include?('not found')
nil
when choise.include?('has address')
puts "tiene una di"
when choise.include?('is an alias')
puts "es un alias"
when choise.include?('IPv6')
else
puts choise
end
You can use regex matchers for when statements.
def data_filter(subDomainBlock)
line = subDomainBlock.split("\n")
line.each do |choise|
case choise
when /not found/
nil
when /has address/
puts "tiene una di"
when /is an alias/
puts "es un alias"
when /IPv6/
else
puts choise
end
end
end
You can not use choise variable in when condition.
don't use case-when, use if-elsif

loop through json array and retrieve one attribute, gives errors also

i am new to programming in ruby, and i am trying to get the value of json['earning_rate_hr'] but i get an error, in '[]': no implicit conversion of String into Integer (TypeError)
i know and i understand the error, however this is not my main question here is my file :
checkingchecker.rb :
#require_relative '../lib/hackex/net/typhoeus'
require_relative '../lib/hackex'
require 'rubygems'
require 'json'
file = 'accounts1.txt'
f = File.open file, 'r'
puts "MADE BY THE PEOPLE, FOR THE PEOPLE #madebylorax"
puts ""
puts "--------------------------------------------------------"
puts ""
while line = f.gets
line = line.chomp.split(';')
email, password = line
puts "logging in as " + email
HackEx.LoginDo(email, password) do |http, auth_token, user|
puts "getting info..."
user = HackEx::Request.Do(http, HackEx::Request.UserInfo(auth_token))['user']
puts "receieved user info!"
bank = HackEx::Request.Do(http, HackEx::Request.UserBank(auth_token))['user_bank']
puts "recieved bank info!"
json = HackEx::Request.Do(http, HackEx::Request.UserSpam(auth_token))['spam']
puts "recieved spam info!"
puts json['earning_rate_hr'] #error line, the error is because this is an array, and it cant be turned into integer, i was wondering if there is a way to use puts on it without trying to make it an integer
userchecking = bank["checking"]
checking = userchecking.scan(/.{1,3}/).join(',')
puts email + " has in Checking: BTC #{checking}"
puts ""
puts "--------------------------------------------------------"
puts ""
end
end
i tried to do puts json, it puts items like this one :
{"id"=>"9867351", "user_id"=>"289108", "victim_user_id"=>"1512021",
"victim_ip"=
"86.60.226.175", "spam_level"=>"50", "earning_rate_hr"=>"24300", "total_earning s"=>"13267800", "started_at"=>"2015-11-01 07:46:59",
"last_collected_at"=>"2015- 11-24 01:46:59"}
what i want to do is select the earning_rate_hr for each one of them and add them together, however i do not have a clue on how to do that, since the error is not fixed and i cant get the value of it
ps : i tried turning it into a Hash, and i also tried using .first, but .first only shows the firs one, i want to show all of them, thank you
I know you from line messenger, I haven't used ruby codes in a long time and this one keeps giving me cloudflare errors, I'm not sure if its because of server downtime/maintainance or whatever but yeah anyway heres your script, enjoy farming ;) -LineOne
PS, I changed a few strings to make it look a lil cleaner so you can see the spam income easier, and added the sleep (1) because sleeping for one second before reconnecting helps to prevent cloudflare errors
also you don't need to require json or rubygems in your hackex scripts because its required in the library so its all covered pre-user-input/script
require_relative 'libv5/lib/hackex'
while 1<2
begin
print'Filename: '
fn=gets.chomp
file = fn+'.txt'
f = File.open file, 'r'
puts "MADE BY THE PEOPLE, FOR THE PEOPLE #madebylorax" #helped by lineone
puts ""
puts "--------------------------------------------------------"
puts ""
while line = f.gets
line = line.chomp.split(';')
email, password = line
HackEx.LoginDo(email, password) do |http, auth_token, user|
puts "Retrieving Info..."
puts''
user = HackEx::Request.Do(http, HackEx::Request.UserInfo(auth_token))['user']
bank = HackEx::Request.Do(http, HackEx::Request.UserBank(auth_token))['user_bank']
json = HackEx::Request.Do(http, HackEx::Request.UserSpam(auth_token))['spam']
cash_count=0
tot_count=0
json.each do |j|
earn_rate = j['earning_rate_hr']
total= j['total_earnings']
cash_count+=earn_rate.to_i
tot_count+=total.to_i
end
print "#{email}: current earnings: #{cash_count} per hour, Total earnings #{tot_count},"
userchecking = bank["checking"]
checking = userchecking.scan(/.{1,3}/).join(',')
puts " #{checking} BTC in Checking"
puts ""
puts "--------------------------------------------------------"
puts ""
sleep 1
end
end
rescue
puts"#{$!}"
end
end
Thats fine you can also calculate the total income of your farms by adding new variables at the top example a=0 then adding the number at the end a+=tot_count
This should help:
earning_rates = json.map{|e| e["earning_rate_hr"]}
puts "Earning rates per hour: #{earning_rates.join(" ")}"
puts "Sum of earning rates: #{earning_rates.map{|e| e.to_i}.inject{|sum, x| sum + x}}"

Can you include `gets.chomp` in a variable with a prompt?

I am wondering if it is possible to include both a prompt character and gets.chomp in a variable. I can do:
prompt = "> "
puts prompt
input = gets.chomp
but is there a way to put both of them in a single prompt variable so that I don't need to type input = gets.chomp when I type puts prompt?
I used to always use the highline gem
require 'highline/import'
name = ask "whats your name"
You could wrap them in a method:
def ask_for_input
prompt = "> "
puts prompt
gets.chomp
end
input = ask_for_input # both prints a prompt and reads input
You can create your own gets method in the Kernel module :
module Kernel
def my_gets
gets.chomp
end
end
input = my_gets
print(input)

Using puts.chomp after reading a File object on Ruby

I'm writing a Call Detail Record (CDR) parser on Ruby. CDRs are files with lines, where every line is an action, and the fields of these lines are separated by tabs.
My problem happens after reading every line of the file using CDRFileParser. When I'm using gets.chomp to get some interactivity with the user, gets.chomp won't wait until I press enter, instead it starts using the lines from the file that was already closed. It seems to be a IO buffer problem. (In C I use fflush() for this kind of issue.)
The files of my program are:
command_line_loader.rb:
def comm_line_loader
begin
raise ArgumentError, 'Invalid number of arguments' unless ARGV.length == 1
return File.new(ARGV[0],"r")
rescue ArgumentError
warn "Debe ingresar el nombre del archivo que contiene los CDR"
exit
rescue Errno::ENOENT
warn "El archivo no existe o hay un error en su lectura"
exit
end
end
objects.rb:
class CDRFileParser
def initialize(cdr_source)
#cdr_source = cdr_source
#cdr_list = cdr_to_array
end
def cdr_to_array
cdr_list_aux = Array.new
cdr_list_aux.push #cdr_source.readline.split("\t") unless #cdr_source.eof?
return cdr_list_aux
end
attr_accessor :cdr_list
end
cdr_parser.rb (useless program that shows the problem):
#!/usr/bin/env ruby
require "./command_line_loader"
require "./objects"
cdr = CDRFileParser.new (comm_line_loader)
loop do
a = gets.chomp
puts a
end
Your help and coding suggestions will be really appreciated :)
The Kernel#gets method only reads from standard input if ARGV is empty. Try using $stdin.gets.chomp instead. Alternatively, clear ARGV after you are done reading from it with ARGV.clear and gets will work as you expect.

Resources