Задача 9-2: не печатет звезды

[А] Алексей Щёголев, 21 июля 2016, 19:51 , 3 подписчика
def cicle_sq (radius)
    puts radius
    cicle_sq = 3.14159 * radius.to_r * radius.to_r
end 

puts "Введите радиус круга"
user_enter = gets.chomp
puts "Площадь круга " + cicle_sq(user_enter).to_s

Это решение 9-1 и оно отработало на отлично.

def puts_stars (number)
    puts_stars = ""
    while number.to_i !=0
        puts_stars = puts_stars + "*"
        number = number.to_i - 1
    end
end

puts "Сколько вам звезд?"
user_enter = gets.chomp
puts "Вот ваши звезды"
puts puts_stars(user_enter).to_s

И печатается пустая строка.

При этом, если в самой процедуре puts_stars добавить в конце строку puts puts_stars.to_s то звезды будут нормально напечатаны...

ЧЯДНТ?

ЗЫ понятно, что нужно вставлять валидацию данных, которые вводит пользователь, но это потом.

Обсуждение (5)


Алексей Щёголев

[А]

Ау, ребята ?


[Д]

У вас переплетение строк с числами и в конце вы пишите:

puts puts_stars(user_enter).to_s

puts и to_s здесь лишние. puts(ом) вы хотите напечатать метод и после него пишете to_s. Ни puts, ни to_s, работать не будут.

Для вашего варианта, больше подходит такой:

def puts_stars(number)  
    if number != 0
        print "*"
        puts_stars (number - 1)
    end
end
puts "Сколько вам звезд?"
 user_enter = gets.to_i
puts "Вот ваши звезды"
 puts_stars(user_enter)

А если хотите с циклом, тогда см. исходник.

Если чего недосмотрел надеюсь учителя поправят.


Вадим Венедиктов Учитель

[В]

Тут небольшая путаница в возвращаемых значениях:

Давайте посмотрим, что делает ваш метод puts_stars:

def puts_stars (number) # принимает на вход число
  puts_stars = ""
  # Cоздаёт переменную puts_stars и присваивает ей
  # значение пустой строки ""
  # Плохо, что название переменной совпало с именем метода, так недолго и запутаться,
  # лучше так не делать :)

  # Теперь запускается цикл до тех пор, пока number не окажется равным 0 
  while number.to_i !=0
    puts_stars = puts_stars + "*" # в цикле добавляются звёздочки
    number = number.to_i - 1 # а число уменьшается
  end

  # Всё отлично, в принципе, вот в этот момент, после цикла,
  # в переменной puts_stars действительно лежит то, что нужно
  # Но вы забыли поставить return, поэтому ruby сам пытается догадаться, что вы
  # хотите вернуть и возвращает результат последней операции.
end

Последняя операция в методе — цикл while, который после себя возвращает nil, именно его метод и возвращает вашему puts-у, который выводит nil на экран в качестве пустой строки:

puts puts_stars(user_enter).to_s

Мораль: пока вы новичок, всегда пишите в методе, что вы хотите вернуть, чтобы ruby не удивлял вас своими догадками.

def puts_stars (number)
    puts_stars = ""
    while number.to_i !=0
        puts_stars = puts_stars + "*"
        number = number.to_i - 1
    end
    return puts_stars
end

Или другой выход: можно сказать методу puts_stars, чтобы он сам выводил звёзды, а никому ничего не возвращал:

def puts_stars (number)
    puts_stars = ""
    while number.to_i !=0
        puts_stars = puts_stars + "*"
        number = number.to_i - 1
    end
    puts puts_stars
end

Тогда перед вызовом метода puts уже не нужен:

puts puts_stars(user_enter).to_sputs_stars(user_enter)

p.s. Простите за долгий ответ, «проморгали» ваш вопрос. Зато Дмитрий пришёл на помощь товарищу. Отвечать на вопросы других учеников, на самом деле — ничем незаменимый опыт, который позволяет лучше разобраться в материале и закрепить его.


Алексей Щёголев

[А]

return!!!

Вот где собака порылась.

Ну ,и название переменной... Я почему то думал что это будет не переменная а именно сама функция..я думал что это работает аналогично паскалевским функциям...

Сосбеннно, как я поимаю, первый мой пример работает корректно. только потому, что руби правильно догадась, что нужно возвращать... Надо конспект печитать.


Вадим Венедиктов Учитель

[В]

Сосбеннно, как я поимаю, первый мой пример работает корректно. только потому, что руби правильно догадась, что нужно возвращать...

Совершенно верно. Он возвращает результат, записанный в cicle_sq (кстати, там тоже конфликт имён).

Можно заюзать эту особенность ruby и написать так:

def cicle_sq (radius)
  puts radius
  3.14159 * radius.to_r * radius.to_r
end 

Кстати, в Ruby есть модуль Math, который содержит константу число Пи.

> Math::PI
 => 3.141592653589793

То есть, можно написать так:

Math::PI * radius.to_r * radius.to_r