Build Diamond with '#" with methods - ruby

I am stuck in my program which is to build a rhombus. I want to build a diamond with one pyramid going up (full_pyramid) and another pyramid going down (wtf_pyramid). I would like to glue the 2 so to make a diamond via the perform method, but I am stuck. I don't know how to get the values ​​of "etages" to put them in my wtf_pyramid method.
I would like to solve my problem and know how.
Thanks in advance and sorry for my english!
def ask_etages
puts "Salut, bienvenue dans ma super pyramide ! Combien d'étages veux-tu ?"
print '>'
gets.chomp
end
def full_pyramid(etages)
espace = etages.to_i - 1
carre = 1
etages.to_i.times do
espace.times do
print ' '
end
espace -= 1
carre.times do
print '#'
end
carre += 2
puts ' '
end
end
def wtf_pyramid(etages)
espace = 0
carre = etages.to_i * 2 - 1
etages.to_i.times do
espace.times do
print ' '
end
espace += 1
carre.times do
print '#'
end
carre -= 2
puts ' '
end
end
def perform
full_pyramid(ask_etages)
wtf_pyramid
end
perform

You are almost there. In your perform method, try to save the result of your ask_etages method to a variable. Then you can re-use this variable as input for both your full_pyramid and your wtf_pyramid methods.
I think this might be a homework or personal practice question, so I'll give you these hints instead of writing it out for you.

Related

Metrics/AbcSize: Assignment Branch Condition size for chart_wise_results is too high. (Ruby)

I am trying to solve the mentioned offense
firstly, my function looks like this
def chart_wise_results
require 'colorize'
require 'time'
_arg, year, path, _month = ARGV
folder_name = path.split('/')
year = year.split('/')
collection = file_collection("#{path}/#{folder_name[2]}_#{year[0]}_#{Date::ABBR_MONTHNAMES[year[1].to_i]}.txt")
collection.shift
collection.each do |w|
puts ( '+' * w[1].to_i).red + "#{w[1]}C", ('+' * w[3].to_i).blue + "#{w[3]}C"
end
end
end
What I have tried:
I have tried removing the w[1].to_i and tried printing it with static number.
I need this library as I have to print colored output.
AbcSize is a metric which tells how many assignments, branches and conditions there are (more info here or here).
You can try to simplify your code, e. g. using extract method refactoring technique.
def print_element(element)
puts ( '+' * element[1].to_i).red + "#{element[1]}C", ('+' * element[3].to_i).blue + "#{element[3]}C"
end
and then
collection.each do |w|
print_element(w)
end

call a method from another file in ruby

Hello I'm new to programming and I started with ruby. I'm trying to do my first program. I found online this code that generate a dice roll
class Die
def initialize(sides)
#sides = sides
end
def generate_die_roll
rand(#sides) + 1
end
def roll(number=1)
roll_array = []
number.times do
roll_array << generate_die_roll
end
total = 0
roll_array.each do |roll|
new_total = total + roll
total = new_total
end
total
end
end
and I would like to use in they way that if the number generated is inferior o equal to another print something otherwise something else.
It's probably very easy but i'm trying in every way and now I will need some help please.
that's my code:
require "./newdado.rb"
energia_vitale = 30
puts "Lancia un dado scrivendo (D) da sommare alla tua Energia Vitale iniziale di #{energia_vitale} punti"
scelta = gets.chomp
case scelta
when "D"
SIX_SIDED_DIE = "#{Die.new(6)}"
values = Array[]
values.push(SIX_SIDED_DIE.roll)
puts values
if values < 2
puts "c"
else puts "b"
end
end
when I run it i receive this error
C:/Users/fix/workspace/D&D Ruby/energia vitale.rb:11:in <main>': undefined methodroll' for "#":String (NoMethodError)
Sorry to bother the community with this beginner problem
Why as string?
this line
SIX_SIDED_DIE = "#{Die.new(6)}"`
should be something like
die = Die.new(6)
then you can do die.roll

Repeat Method to Give "string" an "x" amounts of times

I'm trying to write a method that will take two arguments, one for the string, and the other the number of times it will be repeated. here is the code of i have:
def repeat(text,c=2)
c.times do print text end
end
repeat ("hi")
problem here is, I want to have the result to be "hi hi"
i tried "puts" but that starts a new line...
[ print text " + " text ] doesn't work as well...
thanks for the help!
Your question is unclear. If all you want is to print the text repeated n times, use String#*
def repeat(text, n=2)
print text * n
end
Your example result says you want "hi hi" implying you would like spaces between each repetition. The most concise way to accomplish that is to use Array#*
def repeat(text, n=2)
print [text] * n * ' '
end
Simply multiply the string by the number, Ruby is smart enough to know what you mean ;)
pry(main)> "abcabcabc" * 3
=> "abcabcabcabcabcabcabcabcabc"
Or you could do something like:
def repeat(text, c=2)
print c.times.collect { text }.join(' ')
end
Enumerator#cycle returns an enumerator:
puts ['hi'].cycle(3).to_a.join(' ')
# => hi hi hi
Breaking down the code:
['hi'] creates an array containing a string
cycle(3) creates an enumerator from the array that repeats the elements 3 times
.to_a creates an array from the enumerator so that the join method of Array can create the final output string.
def repeat(text, c=2)
print Array.new(c, text).join(' ')
end
I am new to ruby, but I thought this solution worked well for me and I came up with it myself.
def repeat(word, i=2)
word + (" #{word}" * (i-1))
end
You can try this:
def repeat(text, c=2)
print ((text + ' ')*c).strip
end
def repeat(text, c=2)
print ([text]*c).join(' ')
end
Perhaps easier to read. Unless, is there any reason to use the .collect method instead?
I don't see the point in creating an array (with or without collect()) and then calling join(). This works too:
def repeat(text, c=2)
c.times { |i| print text; print ' ' unless i+1 == c }
end
Although, it is a little more verbose (which is arguably un-ruby like) it does less work (which maybe makes more sense).

read file into an array excluding the the commented out lines

I'm almost a Ruby-nOOb (have just the knowledge of Ruby to write some basic .erb template or Puppet custom-facts). Looks like my requirements fairly simple but can't get my head around it.
Trying to write a .erb template, where it reads a file (with space delimited lines) to an array and then handle each array element according to the requirements. This is what I got so far:
fname = "webURI.txt"
def myArray()
#if defined? $fname
if File.exist?($fname) and File.file?($fname)
IO.readlines($fname)
end
end
myArray.each_index do |i|
myLine = myArray[i].split(' ')
puts myLine[0] +"\t=> "+ myLine.last
end
Which works just fine, except (for obvious reason) for the line that is commented out or blank lines. I also want to make sure that when spitted (by space) up, the line shouldn't have more than two fields in it; a file like this:
# This is a COMMENT
#
# Puppet dashboard
puppet controller-all-local.example.co.uk:80
# Nagios monitoring
nagios controller-all-local.example.co.uk::80/nagios
tac talend-tac-local.example.co.uk:8080/org.talend.admin
mng console talend-mca-local.example.co.uk:8080/amc # Line with three fields
So, basically these two things I'd like to achieve:
Read the lines into array, stripping off everything after the first #
Split each element and print a message if the number id more than two
Any help would be greatly appreciated. Cheers!!
Update 25/02
Thanks guy for your help!!
The blankthing doesn't work for at all; throwing in this error; but I kinda failed to understand why:
undefined method `blank?' for "\n":String (NoMethodError)
The array: myArray, which I get is actually something like this (using p instead of puts:
["\n", "puppet controller-all-local.example.co.uk:80\n", "\n", "\n", "nagios controller-all-local.example.co.uk::80/nagios\n", ..... \n"]
Hence, I had to do this to get around this prob:
$fname = "webURI.txt"
def myArray()
if File.exist?($fname) and File.file?($fname)
IO.readlines($fname).map { |arr| arr.gsub(/#.*/,'') }
end
end
# remove blank lines
SSS = myArray.reject { |ln| ln.start_with?("\n") }
SSS.each_index do |i|
myLine = SSS[i].split(' ')
if myLine.length > 2
puts "Too many arguments!!!"
elsif myLine.length == 1
puts "page"+ i.to_s + "\t=> " + myLine[0]
else
puts myLine[0] +"\t=> "+ myLine.last
end
end
You are most welcome to improve the code. cheers!!
goodArray = myArray.reject do |line|
line.start_with?('#') || line.split(' ').length > 2
end
This would reject whatever that either starts with # or the split returns an array of more than two elements returning you an array of only good items.
Edit:
For your inline commenting you can then do
goodArray.map do |line|
line.gsub(/#.*/, '')
end

How to pass variable between methods in Ruby?

Newbie ruby question.
I have a class
class ReportPage < Page
def badge_item(item_int)
case item_int
when 1..50 then #item= 1
when 50..100 then #item= 50
end
def check_completed_items_badge
badge_item(50)
puts #item
end
end
Sure enough, it puts nil. And here comes my question - how can I use #item variable inside of the other method of the class?
Thank you a lot!
The thing is you miss end keyword for your case. And there is another problem in this program. when(1..50) contain all cases between 1 to 50, and when(50..100) covers 50 to 100, this will lead confusion cause badge_item(50) will go into the first line, set #item to 1 and quit the case ... end block. So at the end it will print 1 on the screen.
To make your intent more clearly, you should use
def badge_item(item_int)
#item = case item_int
when 1..49 then 1 #two dots, cover 1 to 49
when 50..100 then 50
end
end
OR
def badge_item(item_int)
#item = case
when 1...50 then 1 #three dots between, cover 1 to 49
when 50..100 then 50
end
end
The problem is not with the variable assignment but instead with your usage of the case/when syntax. When you give case an argument it uses exact matching to compare the different scenarios. A better way in your case would probably be to use something like this instead:
def badge_item(item_int)
case
when (1..50).include?(item_int) then #item = 1
when (50..100).include?(item_int) then #item = 50
end
end
Edit
Corrections from Tumtu:
case uses === method to compare values. i.e.: (1..50) === 50
The correct approach in your case is to use the OOP:
class ReportPage < Page
class BadgeItem
def initialize( int )
fail "Badge item integer should be in the range 0..99!" unless 0..99 === int
#int = int
end
def classify
case #int
when 0...50 then 1
when 50..99 then 50
end
end
end
def check_completed_items_badge
badge_item = BadgeItem.new 50
puts badge_item.classify
end
end
I know an answer has already been accepted but I wanted to present a more general answer to the question about how instance variables get tossed around.
Straight from ruby-lang you get the following:
Ruby needs no variable declarations. It uses simple naming conventions
to denote the scope of variables.
var could be a local variable.
#var is an instance variable.
$var is a global variable.
These sigils enhance readability by allowing the programmer to easily
identify the roles of each variable. It also becomes unnecessary to
use a tiresome self. prepended to every instance member
It is important to understand the distinction between these different types of variables. To do this I whipped up a small example that should help give anyone with navigates here a good starting point on how these behave.
class Scoping
#unreachable = "but found it. trololol"
$instance = "and found it. swag swag"
def initialize( int )
trial = #unreachable ? #unreachable : " but failed to find."
puts "reaching for the unreachable . . ." + trial
#int = int
end
end
puts $instance
Scoping.new 10
trial = #int ? #int : " but failed to find."
puts "Reaching for instance from class . . ." + trial
trial = $instance ? $instance : " but failed to find."
puts "Reaching for global variable . . ." + trial

Resources