I was wondering how I can get rid of a space at the end of a string. I'm trying to make a repeat method that repeats a string a certain amount of times using default values. This is what I have so far.
def repeat(word, num = 2)
num.times do
print word + " "
end
end
repeat("hello")
I need this to give me "hello hello" but it gives me "hello hello " with the space. How can I get rid of that extra space? I tried chop but I can't seem to implement it right.
def repeat(word, num = 2)
print ([word] * num).join(" ")
end
repeat("hello")
If you assign a new string to your repeat method you can use chop!.
It will modify the string in place, removing the last space you have. Before, calling chop will return a copy of the string thus leaving the space you had.
Try doing:
chopped = repeat("hello").chop!
One more option:
def repeat(word, num = 2)
print ("#{word} " * num).strip
end
Related
Here is my code and output below, i would like to have it so that instead of saying how many occurences, it would output the number of times the letter appears in asterisk form.
For exmaple if "a" appeared four times within a sentence the output would produce:
"a": ****
the_file='C:\Users\Jack\Documents\Ruby\Lab1\lyric.txt'
h = Hash.new
f = File.open(the_file, "r")
f.each_line { |line|
words = line.split(//)
words.each { |w|
if h.has_key?(w)
h[w] = h[w] + 1
else
h[w] = 1
end
}
}
# sort the hash by value, and then print it in this sorted order
h.sort{|a,b| a[1]<=>b[1]}.each { |elem|
puts "\"#{elem[0]}\" : #{elem[1]} occurrences"
}
Screenshot of my current program and output
Instead of #{elem[1]} occurences you just need to write #{'*' * elem[1]}
See method description for more details.
I would like to show another possible alternative way to achieve the word count.
Letting apart the file reading, let's consider the following string:
line = 'Here is my code and output below, i would like to have it so that instead of saying how many occurrences, it would output the number of times the letter appears in asterisk form.'
h = Hash.new(0)
line.downcase.each_char{ |ch| h[ch] += 1 if ('a'..'z').include? ch }
h.to_a.sort_by(&:last).reverse.each { |ch, count| puts "#{ch}: " + "*" * count}
Initialise the hash with default = 0 allow you to start the count without checking if key exists: Hash#default.
Iterate over the line by String#each_char
I counted only case insensitive letters, up to you
For sorting change the Hash into an Array with Hash#to_a
For printing the histogram, as shown in other posts
puts "\"#{elem[0]}\": " + '*' * elem[1]
+ for concatenate, string * number is to repeat certain string number times.
With strings in Ruby, you can use math operators against them. So, you know how many times the letter appears (in elem[1]). In that case you can just multiply the asterisks symbol by that amount:
"\"#{elem[0]}: #{'*' * elem[1]}\""
I'm trying to reverse a string using the code:
puts("Hi now it's going to be done!")
string = gets.chomp.to_s
i = string.length
while i >= 0
puts(string[i])
i = i - 1
end
It prints the string in backward order, but each word is on a single line. How can I keep all of them on a single line?
puts adds a newline to the end of the output if one isn't already present.
print does not. So do this:
while i >=0
print string[i]
i=i-1
end
puts
The final puts is because you want any further printing to be on a new line.
Try this:
"Hi now it's going to be done!".chars.inject([]) { |s, c| s.unshift(c) }.join
Or This is a little easier to follow:
string = 'Hi now it's going to be done!'
string.reverse!
Here's a small part of my code, pretty self explanatory, it copies all characters to temp from input and skips spaces.
input = gets.to_s.chomp
temp=String.new
for i in 0..input.length-1
if (input[i]==" ")
next
else
temp[i]=input[i]
end
end
puts "#{temp},END"
gets
However, i tested it with a 'hello world' input, and it should've given me helloworld But i'm getting
8:in '[]=':index 6 out of string(IndexError)
meaning the problem starts while it's skipping the space, for some reason.
keep in mind that i don't get any errors if i put a string that doesn't contain a space
Whenever string manipulation is required, it may be desirable to convert the string to an array of its parts, manipulate those parts and then join them back into a string, but more often as not it is simpler to just operate on the string itself, mainly using methods from the class String. Here you could Kernel#puts the following.
"%s END" % gets.delete(" \n")
#=> "helloworld"
String#delete removes both spaces and the return character ("\n") that Kernel#gets tacks onto the end of the string that is entered. A variant of this is "%s END" % gets.chomp.delete(" ").
Another way would be to puts
"%s END" % gets.gsub(/\s/, '')
#=> "helloworld"
The regular expression /\s/, causes String#gsub to remove all whitespace, which includes both spaces (and tabs) that are entered and the "\n" that gets tacks on to the end of the string.
I guess your error is due to the difference between the string 'hello world' and that you're "rejecting" whitespaces. In such case, for each whitespace in the string being used, the temp will have one less.
You can assign the input[i] when isn't a whitespace to the temp variable in the position temp.size, this way you don't skip indexes.
It could be temp[temp.size] or just modifying temp with +=.
for i in 0...input.size
if input[i] == ' '
next
else
temp[temp.size] = input[i]
end
end
Note you can replace the for loop for each (the Ruby way):
input = 'hello world'
temp = ''
(0...input.size).each do |index|
input[index] == ' ' ? next : temp[temp.size] = input[index]
end
# helloworld
If you want to skip all white spaces from your input and print the output, you can do so with a one-liner:
puts "#{gets.chomp.split.join}, END"
In ruby, you hardly need to write loops using for construct unlike other traditional languages like Java.
I have a string of text:
string = "%hello %world ho%w is i%t goin%g"
I want to return the following:
"Hello World hoW is iT goinG
The % sign is a key that tells me the next character should be capitalized. The closest I have gotten so far is:
#thing = "%this is a %test this is %only a %test"
if #thing.include?('%')
indicator_position = #thing.index("%")
lowercase_letter_position = indicator_position + 1
lowercase_letter = #thing[lowercase_letter_position]
#thing.gsub!("%#{lowercase_letter}","#{lowercase_letter.upcase}")
end
This returns:
"This is a Test this is %only a Test"
It looks like I need to iterate through the string to make it work as it is only replacing the lowercase 't' but I can't get it to work.
You can do this with gsub and a block:
string.gsub(/%(.)/) do |m|
m[1].upcase
end
Using a block allows you to run arbitrary code on each match.
Inferior to #tadman, but you could write:
string.gsub(/%./, &:upcase).delete('%')
#=> "Hello World hoW is iT goinG
I need to make a method that repeats a given word but I think I am designing it wrong. I need spaces between the words, what am I missing here?
def repeat(word, repeats=2)
sentence = word.to_s * repeats
return sentence
end
Of course, you are missing spaces.
You could have done it like this:
def repeat(word, repeats = 2)
Array.new(repeats, word).join(" ")
end
You can write the code as below :
def repeat(word, repeats=2)
([word] * repeats).join(" ")
end
repeat("Hello",4)
# => "Hello Hello Hello Hello"
Here's one closer to your approach and without using a temporary array:
def repeat(word, repeats=2)
("#{word} " * repeats).chop
end
"#{word} " converts word to a string using string interpolation and appends a space
… * repeats creates a string containing repeats copies
.chop returns the string with the last character removed (the trailing space)
Not having to create an array makes the code a bit faster.
w = 'kokot'
n = 13
n.times.map { w.each_char.to_a.shuffle.join }.tap { |a, _| a.capitalize! }.join(' ') << ?.