美文网首页Ruby入门程序员
8(1)我送你玫瑰,你给我幸福

8(1)我送你玫瑰,你给我幸福

作者: 彩虹门票 | 来源:发表于2018-03-14 09:55 被阅读4次

你们可能已经注意到有些方法当你在调用它们时会返回来一些东西。举例来说:gets会返回一个字符串(就是你所键入的内容),在5+3+方法(实际是5.+(3))会返回来8.数字间的运算方法返回的也会是数字,字符串间运算方法返回的也会是字符串。

要分辨清楚方法被调用后的返回值和程序输出到屏幕上的信息这两者间的区别是很重要的。比如方法puts 5+3中,5+3返回值是数字8,而不是字符串8。

puts的返回值会是什么?之前我们一直没考虑到过,那么现在让我们来思考一下:

This puts returned:

第一个puts看似没返回任何值,但只是在某种程度上它没有返回值,它实际上返回的是nil;尽管我们没测试第二个puts,它返回的也是puts,实际上puts总会返回nil。所有的方法必须会有一个返回值,即使返回值是nil

稍微休息一会儿,写一个小程序来测试一下sayMoo会返回什么?

是不是有些惊喜?实际上它是这样工作的:方法中的返回值只会简单返回方法中最后一行。在sayMoo的例子中就意味着它会返回的是puts 'mooooooo…'*numberOfMoos,也就是说返回值是nil(因为puts返回值是nil)。如果我们想让所有的方法得到的返回值是字符串yellow submarine,只需要在后面把我们想要的字符串加上就可以:


输出为:
mooooooo...mooooooo...
yellow submarine

那么现在我们就可以再回头看一下上一章中心理学调查的问题,但这次我们会写一个方法来帮我们问问题。在这个程序中会把想问的问题当成一个参数,如果回答是“yes”则返回true,回答是“no”则返回false(虽然我们大多数情况下是忽视答案的,但在方法中设置返回值还是很有必要的,同时我们在反馈尿床问题时也能用得上)。我会简略开头的欢迎部分和最后的收尾部分,方便大家阅读:

def ask question
  goodAnswer = false
  while (not goodAnswer)
    puts question
    reply = gets.chomp.downcase

    if (reply == 'yes' or reply == 'no')
      goodAnswer = true
      if reply == 'yes'
        answer = true
      else
        answer = false
      end
    else
      puts 'Please answer "yes" or "no".'
    end
  end

  answer  # This is what we return (true or false).
end

puts 'Hello, and thank you for...'
puts

ask 'Do you like eating tacos?'      # We ignore this return value.
ask 'Do you like eating burritos?'
wetsBed = ask 'Do you wet the bed?'  # We save this return value.
ask 'Do you like eating chimichangas?'
ask 'Do you like eating sopapillas?'
ask 'Do you like eating tamales?'
puts 'Just a few more questions...'
ask 'Do you like drinking horchata?'
ask 'Do you like eating flautas?'

puts
puts 'DEBRIEFING:'
puts 'Thank you for...'
puts
puts wetsBed

输出

程序运行得不错吧?现在我们可以更加方便得增加想问的问题了,同时我们的程序还更加短小精悍了!这的确是一个大的进步--让程序尽可能得短小精悍是每一个“懒”程序员的梦想。

摩拳擦掌

这里有个非常合适的英文数字转换的例子:输入一个数字(比如22)会输出相应的英文(这里指输出"twenty-two")。目前的话我们仅仅在0-100范围内的整数中测试。
(注意:这个例子中用另一种技巧return来返回方法值,并且会介绍分支中一种新的转折elsif。阅读代码中的前后文会清楚得理解它们的使用方法)

  # We only want numbers from 0-100.
  if number < 0
    return 'Please enter a number zero or greater.'
  end
  if number > 100
    return 'Please enter a number 100 or lesser.'
  end

  numString = ''  # This is the string we will return.

  # "left" is how much of the number we still have left to write out.
  # "write" is the part we are writing out right now.
  # write and left... get it?  :)
  left  = number
  write = left/100          # How many hundreds left to write out?
  left  = left - write*100  # Subtract off those hundreds.

  if write > 0
    return 'one hundred'
  end

  write = left/10          # How many tens left to write out?
  left  = left - write*10  # Subtract off those tens.

  if write > 0
    if write == 1  # Uh-oh...
      # Since we can't write "tenty-two" instead of "twelve",
      # we have to make a special exception for these.
      if    left == 0
        numString = numString + 'ten'
      elsif left == 1
        numString = numString + 'eleven'
      elsif left == 2
        numString = numString + 'twelve'
      elsif left == 3
        numString = numString + 'thirteen'
      elsif left == 4
        numString = numString + 'fourteen'
      elsif left == 5
        numString = numString + 'fifteen'
      elsif left == 6
        numString = numString + 'sixteen'
      elsif left == 7
        numString = numString + 'seventeen'
      elsif left == 8
        numString = numString + 'eighteen'
      elsif left == 9
        numString = numString + 'nineteen'
      end
      # Since we took care of the digit in the ones place already,
      # we have nothing left to write.
      left = 0
    elsif write == 2
      numString = numString + 'twenty'
    elsif write == 3
      numString = numString + 'thirty'
    elsif write == 4
      numString = numString + 'forty'
    elsif write == 5
      numString = numString + 'fifty'
    elsif write == 6
      numString = numString + 'sixty'
    elsif write == 7
      numString = numString + 'seventy'
    elsif write == 8
      numString = numString + 'eighty'
    elsif write == 9
      numString = numString + 'ninety'
    end

    if left > 0
      numString = numString + '-'
    end
  end

  write = left  # How many ones left to write out?
  left  = 0     # Subtract off those ones.

  if write > 0
    if    write == 1
      numString = numString + 'one'
    elsif write == 2
      numString = numString + 'two'
    elsif write == 3
      numString = numString + 'three'
    elsif write == 4
      numString = numString + 'four'
    elsif write == 5
      numString = numString + 'five'
    elsif write == 6
      numString = numString + 'six'
    elsif write == 7
      numString = numString + 'seven'
    elsif write == 8
      numString = numString + 'eight'
    elsif write == 9
      numString = numString + 'nine'
    end
  end

  if numString == ''
    # The only way "numString" could be empty is if
    # "number" is 0.
    return 'zero'
  end

  # If we got this far, then we had a number somewhere
  # in between 0 and 100, so we need to return "numString".
  numString
end

puts englishNumber(  0)
puts englishNumber(  9)
puts englishNumber( 10)
puts englishNumber( 11)
puts englishNumber( 17)
puts englishNumber( 32)
puts englishNumber( 88)
puts englishNumber( 99)
puts englishNumber(100)

输出为:

zero
nine
ten
eleven
seventeen
thirty-two
eighty-eight
ninety-nine
one hundred

程序先考虑100,后10-19,然后20、30、40~~90,再然后考虑中间数据,最终考虑数字0 --译者注
上面程序中有几点令人不太满意的:首先有太多重复部分,其次是没法解决100以上的大数,最后是程序里有太多特殊情况和返回值。其实我们可以用阵列方法来精简一下程序:

def englishNumber number
  if number < 0  # No negative numbers.
    return 'Please enter a number that isn\'t negative.'
  end
  if number == 0
    return 'zero'
  end

  # No more special cases! No more returns!

  numString = ''  # This is the string we will return.

  onesPlace = ['one',     'two',       'three',    'four',     'five',
               'six',     'seven',     'eight',    'nine']
  tensPlace = ['ten',     'twenty',    'thirty',   'forty',    'fifty',
               'sixty',   'seventy',   'eighty',   'ninety']
  teenagers = ['eleven',  'twelve',    'thirteen', 'fourteen', 'fifteen',
               'sixteen', 'seventeen', 'eighteen', 'nineteen']

  # "left" is how much of the number we still have left to write out.
  # "write" is the part we are writing out right now.
  # write and left... get it?  :)
  left  = number
  write = left/100          # How many hundreds left to write out?
  left  = left - write*100  # Subtract off those hundreds.

  if write > 0
    # Now here's a really sly trick:
    hundreds  = englishNumber write
    numString = numString + hundreds + ' hundred'
    # That's called "recursion". So what did I just do?
    # I told this method to call itself, but with "write" instead of
    # "number". Remember that "write" is (at the moment) the number of
    # hundreds we have to write out. After we add "hundreds" to
    # "numString", we add the string ' hundred' after it.
    # So, for example, if we originally called englishNumber with
    # 1999 (so "number" = 1999), then at this point "write" would
    # be 19, and "left" would be 99. The laziest thing to do at this
    # point is to have englishNumber write out the 'nineteen' for us,
    # then we write out ' hundred', and then the rest of
    # englishNumber writes out 'ninety-nine'.

    if left > 0
      # So we don't write 'two hundredfifty-one'...
      numString = numString + ' '
    end
  end

  write = left/10          # How many tens left to write out?
  left  = left - write*10  # Subtract off those tens.

  if write > 0
    if ((write == 1) and (left > 0))
      # Since we can't write "tenty-two" instead of "twelve",
      # we have to make a special exception for these.
      numString = numString + teenagers[left-1]
      # The "-1" is because teenagers[3] is 'fourteen', not 'thirteen'.

      # Since we took care of the digit in the ones place already,
      # we have nothing left to write.
      left = 0
    else
      numString = numString + tensPlace[write-1]
      # The "-1" is because tensPlace[3] is 'forty', not 'thirty'.
    end

    if left > 0
      # So we don't write 'sixtyfour'...
      numString = numString + '-'
    end
  end

  write = left  # How many ones left to write out?
  left  = 0     # Subtract off those ones.

  if write > 0
    numString = numString + onesPlace[write-1]
    # The "-1" is because onesPlace[3] is 'four', not 'three'.
  end

  # Now we just return "numString"...
  numString
end

puts englishNumber(  0)
puts englishNumber(  9)
puts englishNumber( 10)
puts englishNumber( 11)
puts englishNumber( 17)
puts englishNumber( 32)
puts englishNumber( 88)
puts englishNumber( 99)
puts englishNumber(100)
puts englishNumber(101)
puts englishNumber(234)
puts englishNumber(3211)
puts englishNumber(999999)
puts englishNumber(1000000000000)

程序在输出大于等于100的数据时使用了递归,调用自身方法 ----译者注
输出为:

zero
nine
ten
eleven
seventeen
thirty-two
eighty-eight
ninety-nine
one hundred
one hundred one
two hundred thirty-four
thirty-two hundred eleven
ninety-nine hundred ninety-nine hundred ninety-nine
one hundred hundred hundred hundred hundred hundred

嗯,程序显得好多了,代码相当紧凑,所以我在里面写了许多注释。程序可以用于更大的数……尽管不像我们希望的那样。例如我认为最后的数的输出是'one trrllion'更合适,或是'one million million'(当然三种都对),你现在就可以试着改一下……

牛刀小试

  • 扩展一下上面的englishNumber程序:扩大到千位数字,使程序可以返回'one thousand'、'ten thousand'来替代'ten thousand'、'one hundred hundred'。
  • 再扩展上面的程序:扩大到百万数字,使程序可以返回'one million'来替代'one thousand thousand',也可以试着增加到亿万和万亿。你最多能增加多少?
  • 能不能将数字连接起来?与上面englishNumber程序类似,只是在数字中间加入‘and’,返回的是'nineteen hundred and seventy and two',或者是婚礼请柬上那样的数字。我本想多举几个例子,但我自己也不是太懂得这些。你可能需要联系婚礼人员来帮一下忙。
  • "Ninety-nine bottles of beer..."现在你可以用上englishNumber和你之前的程序,重写一下输出这首歌的歌词的正确方法。惩罚一下你的电脑:让它从9999开始(虽然不要选一个太大的数字,因为让电脑在屏幕上输出如此多的内容需要挺多时间的)。输出十万个瓶子需要一点时间,如果你选择输出一百万个瓶子,你同时也是在惩罚你自己哦!

恭喜你!到现在为止,你就成为一个真正的程序员了!你已经学到了从头构建一个大程序的所有知识。如果你有想编写某个程序的想法,你就可以自己去写了,统统把它们解决掉吧!

当然从头构建所有的程序确实有点缓慢。有必要花费时间写别人已经写过的代码吗?你考虑过让程序发一封邮件吗?有没有想过让程序把网上的东西保存并下载到你的电脑上?或者是生成一个代码能够自动测试的网页教程?Ruby有多种多样的对象来帮助我们更加快速得写程序。

相关文章

  • 8(1)我送你玫瑰,你给我幸福

    你们可能已经注意到有些方法当你在调用它们时会返回来一些东西。举例来说:gets会返回一个字符串(就是你所键入的内容...

  • 最美

    送你一朵红玫瑰 你在我心中 比玫瑰还要红 比玫瑰还要美 你没有刺 你没有泪 送你一朵红玫瑰 你在我心中 比玫瑰更温...

  • 泡水的玫瑰

    每次送你的玫瑰,你都丢弃了。 我悄悄的捡回来,用来泡水喝。 久而久之,玫瑰泡的水也喝的无味了。 我却任就送你玫瑰,...

  • [醒恋:初识他]六

    时刻幸福着 “梅儿,你等一下,我去买玫瑰花送你~!” “不要,今天玫瑰花一定会很贵。” 应该不会吧,现在已是晚上了...

  • 一次无心理负担的考试

    #幸福是需要修出来的~每天进步1%# 20170521(8/99) 【幸福三朵玫瑰】 昨日2朵玫瑰 早起写日记✅ ...

  • 你送我玫瑰,我送你一本书(修改稿)

    4月23日是“世界读书日”徐老师给我们办了个开幕会。 徐老师还给我们讲了个故事,书名叫《你送我玫瑰,我送你...

  • 送你一枝玫瑰

    送你一支玫瑰[玫瑰] 送你一枝玫瑰 夜风遣来遐想 情话大胆说 你的嘴唇,你的衣袂 情话多少遍吻就有多甜 你听那月亮...

  • 8天

    焦点日记分享第8天 2019年3月25日 幸福三问[玫瑰][玫瑰][玫瑰] 1今天我做了什么让自己觉得满意 工作中...

  • 一支玫瑰的心理哲学——互惠原理1

    走在街上,如果有人送你一支玫瑰花,你会接受吗? 我想很少女生能抗拒美丽的玫瑰花的诱惑,如果恰巧送你玫瑰花...

  • 李小姐

    李小姐,你折断了我送你的玫瑰 玫瑰是红的,鲜亮得像我滚烫的血液 你害怕玫瑰的刺,我用刻刀剥除了它 玫瑰在向我哭诉,...

网友评论

    本文标题:8(1)我送你玫瑰,你给我幸福

    本文链接:https://www.haomeiwen.com/subject/klhbixtx.html