Monthly Archives: May 2008

湯冷めして、風邪をひいた

 昨晩、気持ちよく長風呂して、身体がほてりにほてったので、そいつを冷まそうと窓を開けて涼みつつ、最近また夫婦そろってハマっている古畑任三郎のDVDを観ながらウトウトしてしまい、気づいたときには(古畑が菅原文太を追い詰めてたときには)身体が底冷えしてその時点でもう寒気がしてしまって、今朝起きたら、もうすっかり風邪の症状が出ていて、葛根湯を飲む。早くよくなれ。

 というわけで、湯冷めには注意しましょう。

A Few Things to Try on 7. Arrays and Iterators

 Rubyでプログラミング勉強中(参照)。

 Arrays(配列)とIterators(イテレータ)について学ぶ。

A Few Things to Try on 7. Arrays and Iterators

一問目

Write the program we talked about at the very beginning of this chapter.

Hint: There’s a lovely array method which will give you a sorted version of an array: sort. Use it!

7. Arrays and Iterators

『Write the program we talked about at the very beginning of this chapter』っていうのは、以下。

Let’s write a program which asks us to type in as many words as we want (one word per line, continuing until we just press Enter on an empty line), and which then repeats the words back to us in alphabetical order.

7. Arrays and Iterators

これは簡単。

word = gets.chomp
ary = []
while word != ''
ary << word
word = gets.chomp
end
puts 'Sorted by Alphabet'
puts '=================='
puts ary.sort

二問目

Try writing the above program without using the sort method. A large part of programming is solving problems, so get all the practice you can!

7. Arrays and Iterators

これは難しかった・・・。ウンウンと唸って唸ってやっとできた。

word = gets.chomp
ary = []
while word != ''
ary << word
word = gets.chomp
end
i = 0
while i < ary.length
j = i + 1
while j < ary.length
if ( ary[i].to_s > ary[j].to_s )
tmp = ary[i]
ary[i] = ary[j]
ary[j] = tmp
end
j = j + 1
end
i = i + 1
end
puts
puts 'Sorted by Alphabet'
puts '=================='
puts ary

三問目

Rewrite your Table of Contents program (from the chapter on methods). Start the program with an array holding all of the information for your Table of Contents (chapter names, page numbers, etc.). Then print out the information from the array in a beautifully formatted Table of Contents.

7. Arrays and Iterators

こんな感じでよいのかな。

toc = ['Chapter 1:  Numbers  ', '  page 1',
'Chapter 2:  Letters  ', ' page 72',
'Chapter 3:  Variables', 'page 181']
lineWidth = 50
puts 'Table of Contents'.center(lineWidth)
puts ''
i = 0
j = 1
while i < toc.length
puts (toc[i].ljust(lineWidth/2) + toc[j].rjust(lineWidth/2))
i += 2
j += 2
end

雑感

 練習問題二問目が手強かったけど、勉強になった。次チャプター以降から、さらに深く(そして難しく)なっていく。ついていけるかな・・・。

See also

魔女の一撃

欧米ではその病態から「魔女の一撃」とも呼ばれている。

ぎっくり腰 – Wikipedia

 今年のゴールデンウィーク初日に「魔女の一撃」をくらって、11連休をほとんど寝て過ごしたのは、僕です、はい。

 そして、現在はちょっと違和感が残る程度にまで回復したけど、「ぎっくり腰は再発するらしい」というのを見聞きして、いつまた「魔女の一撃」をくらうか、毎日びびりまくって過ごしているのも、僕です、はい。

地方によってはびっくり腰とも呼ばれる。

ぎっくり腰 – Wikipedia

 いやほんと、びっくりですよ。

これは悔しい

 「他行のATM(現金自動受払機)経由の取引は盲点だった。想像力が及ばず、リハーサル項目からも抜け落ちていた」。三菱東京UFJ銀の幹部は統合作業の不備を認めた。

 障害の原因は、通帳未記帳の件数が10件以上ある顧客に、記帳を促すメッセージを送る際の文字コードが、セブン銀は「カタカナ」なのに、三菱東京UFJ銀の新システムは「漢字」だったという「初歩的なプログラムミス」(業界関係者)。文字コードが漢字だった金融機関での障害発生はなかった。

 三菱東京UFJ銀は06年1月の合併以来、2年の準備期間と総額4000億円をかけて「準備には万全を尽くした」(永易克典頭取)はずだった。今年2月からは全支店でATMを休止し、新システムにつなぐリハーサルを3回繰り返した。セブン銀のATMもリハーサル対象ではあったが、障害を起こした取引はテストしていなかった。

三菱東京UFJ銀:最大のシステム統合、単純ミスで障害 - 毎日jp(毎日新聞)

 本当に初歩的なミスだったんですね・・・。4000億円という投資の相当な部分をテストに費やしてきたらしい(参照)のにも関わらず、なぜそこをテストしなかったのか・・・。

これだけ巨大なシステムの統合となると障害が出ても不思議ではないとは思ったりもするけど、それでも障害があってはいけないというのが、銀行や金融関連システムの障害。しかし、やっぱり障害は起きる。みずほ銀行の統合のときもそうであったように。そして、障害が起きるとマスコミ・社会に袋叩きにされる。

 今回の統合には、その投資額だけをみても分かるように、銀行とシステム屋の、まさに威信とプライドをかけていたはずだ。それが、こういうちょっとした初歩的なミスで敗北してしまう。そう、これはもう敗北。マスコミはしばらくこの障害を叩き続けるだろう。「統合は失敗だった」なんて極論するところも出てくるかもしれない。

もちろん、運悪く障害に出くわした一般の方にとっては、いい迷惑な話ではある。金も威信もプライドもかけてくれて構わないが、迷惑だけはかけないでくれ、と思うのが普通の感覚であると思う。

 んん、何だか何が言いたいのか、よく分からなくなってきたが、要は悔しいんだな。全くもってプロジェクトに関わっていない、いちエンジニアの僕だけど、それでもエンジニアとして今回の障害は、悔しい。システムが動かなくなるときっていうのは、大抵こういうケアレスミスなんだな、ということを今回の件で、改めて思い知った。この教訓は忘れないようにしたい。

See also

早く読了してしまいたい – 「模倣犯(上)」

模倣犯〈上〉

宮部みゆきの代表的な長編ミステリー二冊『火車』(参照)『理由』(参照)を読み、綿密で深い宮部ミステリーの世界観にどっぷりとやられてしまっている。これら二作はものすごく濃くて深いので、読むとどっと疲れが出る。そんな宮部みゆきの長編ミステリー最長作『模倣犯』についに手をつけてしまった。文庫版だと五巻物になっているようだが、やたらと巻数を増やされてしまった文庫版を読むのが個人的には好きではないので、図書館で分厚いオリジナル版を借りてきて読んでいる。

上巻721ページ、下巻701ページ、合わせて1400ページという超長編である本作。一気読みなどとてもじゃないが出来ない。それは文量もさることながら、内容が重く厳しいからというのが大きい。ただでさえ影響を受けやすい性格の僕が、こんな話を一気読みしたら頭がおかしくなってしまうかもしれない。なので、少し読んで、現実に戻って現実を過ごして、また少し読む、という読み方をしている。

この「頭がおかしくなってしまうかもしれない」という感覚は、少し前に成田からイスタンブール経由ヨルダンへの機内で一気読みした町田康の『告白』(676ページ)を読んだときに感じた、あの何とも言えない感覚に似ている。実際に起きた大量殺人事件の犯人の心の闇・真実を町田節で書き綴ったロックな小説『告白』は、心して読まないと読者の心がそちらに持っていかれてしまう。本作『模倣犯』でも(特に第二部からは)、それと同じような危うさが伴う。

そんなわけで、やっと上巻を読み終わり、今日から下巻を読み始める。「面白いし次が気になって、どんどん読みたい」というのもあるにはあるが、それよりも、こんなに重たいミステリー小説はさっさと読み終えてしまいたい、という気持ちが強い。正直、読み始めたときはここまできつい読書になるとは思っていなかった。早く読み終わってしまいたいけど、一気読みすると心が持っていかれる。こんなミステリーを読むのは本当に疲れるが、今さら本を置くことなどできない。

今年に入ってから、ミステリー小説にはまっていたが、本作を読了したらしばらくミステリーの世界からは離れようと思っている。そんな気にさえさせてしまう程、本作は重厚で読者を体力的にも精神的にも疲弊させるのだ。

See also

Simon Saysはキラーアクティビティだ

 今日のレッスンでは、Body Parts(head, ears, eyes, nose, mouth, arm, elbow, hand, leg, foot)を導入。そして、こういったBody Parts関連やAction関連の言語材料を導入する際に非常に効果のあるアクティビティ「Simon Says」を初めてやってみた。効果は絶大。ゲームを楽しむ子ども達の集中力はただごとではないくらい。今日初めて導入したBody Parts関連単語もゲームに勝ちたい一心で、どんどん覚えていく。大分慣れてきた頃に、「Simon says, touch your nose!」と言いつつ僕は耳を触る、というひっかけ問題もやってみたが、ひっかからない子どももいた。鼻=noseというのを今回初めて学習したのに、もう定着している。

 正直、ここまでとは思っていなかった。Simon Saysは子ども英語教室におけるキラーアクティビティであると体感・実感した。これからも折に触れて使っていきたいと思う。

あの件、あれからどうなった?

 最近、会社の上司と話していると、イライラして疲れてしまうことがままある。イライラしてしまう度に反省するのだけど、どうしてもいかん。

 その上司は、その話の背景を説明せずに、いきなり自分の知りたいことを聞いてくる。本人のなかでは整理がついているので、その質問がいかに相手を混乱させているかというのが分からないのだと思う。

例えば、僕の参加していない会議を終えたあとに、その会議の内容について他の参加者と執務室でも話をしていて、僕は他の仕事に没頭していてその話は耳に入っていなかったのに、いきなり「前のお客さんの場合、どうだった?」などど聞いてくる。何のことを聞いているのか、さっぱり分からないのである。自分が今している話の内容について、僕も分かっていることを前提にして聞いてくる。たまには、何の話をしているか何とか読めるときもあるが、大抵は意味不明で「それ、何の話ですか?」とか「何の話してます?」とか、ちょっと(いや相当)トゲのある聞き方をしてしまい、それに毎回反省するのだ。

 そんな上司から、今日は今までで最高に意味不明な質問を、僕が自分の仕事に集中しているときに、いきなり後ろから聞かれた。

「あの件、あれからどうなった?」

「あの件」がどの件か、分からない。「あれから」がいつのことからのことなのか、分からない。何回か聞き返すうちに、やっと「あの件」が何の件で、「あれから」がいつのことなのか分かったけども。いや、参った。

 まあ、こういうことでイライラばかりしていても仕方ないので、反面教師として捉えて、自分はそうなっていないか、見直している次第である・・・。

閏年(Leap Year)判別コード

 というわけで(id:heydays:20080508:1210235785)、模範解答を参考に閏年(Leap Year)判別コードを見直してみる。こうして見直してみると、プログラム初心者丸出しで恥ずかしいことこの上ないけど、そこら辺は気にしない気にしない。

Leap Years. Write a program which will ask for a starting year and an ending year, and then puts all of the leap years between them (and including them, if they are also leap years). Leap years are years divisible by four (like 1984 and 2004). However, years divisible by 100 are not leap years (such as 1800 and 1900) unless they are divisible by 400 (like 1600 and 2000, which were in fact leap years). (Yes, it’s all pretty confusing, but not as confusing has having July in the middle of the winter, which is what would eventually happen.)

6. Flow Control

 この練習問題の僕の解答は以下だった。

puts 'Enter a start year.'
sYear = gets.chomp
puts ''
puts 'Enter an end year.'
eYear = gets.chomp
puts ''
if sYear > eYear
puts 'An end year must be equal to or greater than a start year.'
else
puts 'The leap years between ' + sYear.to_s + ' and ' + eYear.to_s + ' are listed below.'
puts ''
while sYear.to_i != (eYear.to_i + 1)
aYear = sYear.to_i % 4
bYear = sYear.to_i % 100
cYear = sYear.to_i % 400
if aYear == 0
if bYear != 0
puts sYear.to_s
else
if cYear == 0
puts sYear.to_s
end
end
end
sYear = sYear.to_i + 1
end
end

 そして、id:Kiskeさんの模範解答(id:Kiske:20070705:1183627478)は以下。

puts '開始年を入力.'
from = gets.chomp.to_i
puts '終了年を入力.'
to = gets.chomp.to_i
puts "#{from}年~#{to}年のうるう年一覧"
while from <= to
if (from % 4 == 0 and from % 100 != 0 or from % 400 == 0)
puts from.to_s + ''
end from = from + 1
end

rubyチュートリアルを試してみる その2 – note-phper

なるほどー。

こうして見ると、もう全然だめですな、僕のコードは。この練習問題のキーである閏年をいかに判別するか、っていうところが僕の書いたコードだと何かしつこい。

閏年は以下のルールから判別する。

  • 4で割り切れる
  • かつ、100で割り切れない
  • 100で割り切れる場合、400で割り切れれば、閏年

これを、if文一行で書けるってことに気付かなかった。勉強になりました。

あと、『gets.chomp』を『gets.chomp.to_i』とすることで、変数に入力した文字列を数(Integer)として扱うことができる、っていうのも気付かなかったなあ。なるほど。

 というわけで、僕の書いたコードを上記模範解答を参考にして、書き換えてみる。

puts 'Enter a start year.'
sYear = gets.chomp.to_i
puts ''
puts 'Enter an end year.'
eYear = gets.chomp.to_i
puts ''
if sYear > eYear
puts 'An end year must be equal to or greater than a start year.'
else
puts 'The leap years between ' + sYear.to_s + ' and ' + eYear.to_s + ' are listed below.'
puts ''
while sYear <= eYear
if (sYear % 4 == 0 and sYear % 100 != 0 or sYear % 400 == 0)
puts sYear.to_s
end
sYear = sYear + 1
end
end

んー、シンプル。

Many thanks to id:Kiske

See also

模範解答発見!

 id:Kiskeさんという方が、僕と同じようにダイアリーに練習問題の解答を記録しているのを見つけました。

 コードがシンプルで素敵です。特に、閏年(Leap Year)判別コードを見たときは、自分の書いたコード(id:heydays:20080508:1210225720)が随分と鼻タレだったということに気付き、泣き笑いしました。自分の頭で悶々と考えるのも大事だけど、ちゃんとしたコードを参考にするっていうのも同じくらい大事なんだなと、思い知る次第です。

僕は今、7. Arrays and Iteratorsに取り掛かっているところ。これからどんどん練習問題が複雑化していくなあと感じていたので、模範解答を見つけることができて、ラッキーです。とはいえ、自分の頭で練習問題コードを書ききってから、模範解答を参考にしていかねば、です。

 id:Kiskeさん、勝手に模範解答として参考にさせていただきますので、宜しくお願いします。

See also

A Few Things to Try on 6. Flow Control

 Rubyでプログラミング勉強中(参照)。

 本当は毎日ちょっとずつでもプログラムを書いて勉強していこうなんて意気込んでいたんだけど、日々のアレコレに紛れて、なかなか・・・。ま、いっか。のんびりいきましょ。

 というわけで、今日は、Chapter 6. Flow Control(参照)。BRANCHING(if文)やらLOOPING(while)が登場。これまでのChapterに比べると、ぐっと難しく、そんでもって楽しくなってきた。

A Few Things to Try on 6. Flow Control

一問目

“99 bottles of beer on the wall…” Write a program which prints out the lyrics to that beloved classic, that field-trip favorite: “99 Bottles of Beer on the Wall.”

6. Flow Control

※”99 bottles of beer on the wall”っていうのは、マザーグースの歌らしい。日本語訳(参照)に出力例が出ている。

ちょっと考えたけど、以下な感じで落ち着いた。出力例通りに出力されたので、OKかな。

beer = 99
while beer != 0
puts beer.to_s + ' Bottles of beer on the wall'
puts beer.to_s + ' Bottles of beer'
puts 'Take on down and pass it around'
beer = beer - 1
puts beer.to_s + ' Bottles of beer on the wall'
puts ''
end

二問目

Write a Deaf Grandma program. Whatever you say to grandma (whatever you type in), she should respond with HUH?! SPEAK UP, SONNY!, unless you shout it (type in all capitals). If you shout, she can hear you (or at least she thinks so) and yells back, NO, NOT SINCE 1938! To make your program really believable, have grandma shout a different year each time; maybe any year at random between 1930 and 1950. (This part is optional, and would be much easier if you read the section on Ruby’s random number generator at the end of the methods chapter.) You can’t stop talking to grandma until you shout BYE.

  • Hint: Don’t forget about chomp! ‘BYE’with an Enter is not the same as ‘BYE’ without one!
  • Hint 2: Try to think about what parts of your program should happen over and over again. All of those should be in your while loop.

    6. Flow Control

耳が遠いおばあちゃんとの会話プログラム。Hintにもあるとおり、while loopがKeyですな。『any year at random between 1930 and 1950』っていうのをどう書いたらいいのか迷ったけど、結局ここでもwhile文を使った。他に書き方あるのかな・・・。

puts 'Hi, Granma.'
iSay = gets.chomp
while iSay != iSay.upcase
puts 'HUH? SPEAK UP, SUNNY!'
iSay = gets.chomp
end
while iSay != 'BYE'
rYear = 1
while rYear <= 1930
rYear = (rand(1951))
end
puts 'NO, NOT SINCE ' + rYear.to_s + '!'
iSay = gets.chomp
end
puts 'Okay.... bye for now...'

三問目

Extend your Deaf Grandma program: What if grandma doesn’t want you to leave? When you shout BYE, she could pretend not to hear you. Change your previous program so that you have to shout BYE three times in a row. Make sure to test your program: if you shout BYE three times, but not in a row, you should still be talking to grandma.

6. Flow Control

BYEを三回連続で叫ばないと耳の遠いおばあちゃんとの会話が終わらないように二問目のコードを変更する。この『三回連続』っていうとこで、ちょっとはまった。二回連続で言った後に、BYE以外の言葉を言ったら、カウントがリセットされるっていうのが漏れてて、悩んだ。で、結局以下のようなコードに。

puts 'Hi, Granma.'
iSay = gets.chomp
while iSay != iSay.upcase
puts 'HUH? SPEAK UP, SUNNY!'
iSay = gets.chomp
end
while iSay != 'BYE'
rYear = 1
while (rYear <= 1930)
rYear = (rand(1951))
end
puts 'NO, NOT SINCE ' + rYear.to_s + '!'
iSay = gets.chomp
end
iBye = 1
while iBye != 3
puts 'HUH? WHAT DID YOU SAY?'
iSay = gets.chomp
if iSay == 'BYE'
iBye = iBye + 1
else
iBye = 0
end
end
puts 'Okay.... bye for now...'

四問目

Leap Years. Write a program which will ask for a starting year and an ending year, and then puts all of the leap years between them (and including them, if they are also leap years). Leap years are years divisible by four (like 1984 and 2004). However, years divisible by 100 are not leap years (such as 1800 and 1900) unless they are divisible by 400 (like 1600 and 2000, which were in fact leap years). (Yes, it’s all pretty confusing, but not as confusing has having July in the middle of the winter, which is what would eventually happen.)

6. Flow Control

入力した年と年の間の閏年を一覧出力するプログラム。閏年の算出って結構ややこしいってことは知ってたけど、これをプログラムに落とすっていうのはなかなか頭を使った。まずは、『入力した年と年の間のう閏年を一覧出力』を考える前に、閏年判別プログラムを書いてみる。

(注: 以下の回答はかなりへタレ。模範解答を参考に書き直した ⇒ id:heydays:20080508:1210237624)

puts 'Enter a year.'
iYear = gets.chomp
aYear = iYear.to_i % 4
bYear = iYear.to_i % 100
cYear = iYear.to_i % 400
if aYear == 0
if bYear != 0
puts iYear.to_s + ' is the leap year.'
else
if cYear == 0
puts iYear.to_s + ' is the leap year.'
else
puts iYear.to_s + ' is NOT the leap year.'
end
end
else
puts iYear.to_s + ' is NOT the leap year.'
end

うむ、いい感じ。で、『入力した年と年の間のう閏年を一覧出力』するプログラムは、以下な感じで。一応、『start year <= end year』チェックを入れてみた。

puts 'Enter a start year.'
sYear = gets.chomp
puts ''
puts 'Enter an end year.'
eYear = gets.chomp
puts ''
if sYear > eYear
puts 'An end year must be equal to or greater than a start year.'
else
puts 'The leap years between ' + sYear.to_s + ' and ' + eYear.to_s + ' are listed below.'
puts ''
while sYear.to_i != (eYear.to_i + 1)
aYear = sYear.to_i % 4
bYear = sYear.to_i % 100
cYear = sYear.to_i % 400
if aYear == 0
if bYear != 0
puts sYear.to_s
else
if cYear == 0
puts sYear.to_s
end
end
end
sYear = sYear.to_i + 1
end
end

雑感

 ふー。今回は、前回までのそれと比べて、随分と頭を使った。おかげで随分と理解が深まった。四問目で書いた『閏年判定プログラム』は、実際に意外と役立つプログラムだったりするので、何だか小さな達成感。けど、もっと上手に書くことが出来るような気がしないでもない。慣れてきてから振り返ってみるか。

See also