Fizz Buzzしてみよう!

Avatar
dstn

はじめに


みなさまこんにちは。アプレッソ開発部の東です。

私の所属するQAチーム(品質保証部門)では、定期的に勉強会を行っていますが、先日のテーマは以下の4つの条件をすべて満たすJavaのプログラムを書く、というものでした。

    • 1から100までの数を出力する。
    • 3の倍数のときは数の代わりに「Fizz」と出力する。
    • 5の倍数のときは数の代わりに「Buzz」と出力する。
    • 3と5両方の倍数の場合には数の代わりに「FizzBuzz」と出力する。



ご存知の方も多いかと思いますが、これはいわゆる「Fizz Buzz問題」と呼ばれるものです。

QAのメンバーの中にはdo while文のみを使用するという縛りを自らに課す者もいましたが、一番シンプルで綺麗だったのは以下のプログラムという結果でした。

001

しかしッ!我々DataSpider開発者はこの程度では満足しませんッ!

DataSpider Servistaのスクリプトで実装してこそ、DataSpider開発者の矜持が満たされるというもの!

・・・というわけで、実際にFizz BuzzをDataSpider Servistaで実装してみました。

とりあえず作ってみた (文字列連結編)



002

何も考えずに作ってみたところ、Mapperが4個数珠つなぎという、見るからに非効率な作りになってしまいました…。

簡単に中身を見てみます。

最初のMapperではループ回数(100回)分インクリメントして数値型のスクリプト変数に代入します。

003

次のMapperでは、インクリメントした値を、「余り」ロジックでそれぞれ「3」と「5」で割り、余りを別々の数値型スクリプト変数に代入します。

004

続いてのMapperでは、余りの値を文字列連結(!)するために「数値フォーマッティング」ロジックでいったん文字列に変換して、「連結」ロジックで連結させます。

005

この文字列に変換して連結するという発想が剛毅さを演出していて素晴らしい!自画自賛です!

そして最後のMapperでは連結させた値を「スイッチ判定による出力の切り替え」ロジックで判定します。

006

値が「00」と同じだったら「FizzBuzz」と出力、「0」で始まれば「Fizz」と出力し「0」で終われば「Buzz」と出力、いずれにも合致しない場合はカウントの値を出力させます。

作りは非常に冗長ですが、これで何とか要件は満たせました。

プログラムも同様ですが、DataSpiderも「あること」を実現させるのには何通りもの方法があります。そのため、何も考えないで作るとこのように効率の悪いスクリプトになってしまったりするので、何かテーマを決めて作るとよいでしょう。
(メンテナンスしやすさを優先する、最小のアイコン構成で作る、機能ごとに部品化(子スクリプト)する、見た目の美しさを重視する…など。)

次は、条件判定にMapperではなく「条件分岐処理」を使用して作ってみます。

再チャレンジ (条件分岐編)



007

冒頭で紹介したプログラムをDataSpider Servistaに置き替えた感じになりました。

Mapperの「スイッチ判定による出力の切り替え」ロジックの処理を条件分岐処理と変数Mapperで担っているので、見た目には分かりやすいですが、その分コンポーネントアイコンは多くなります。

アイコンの数を重視するか、それとも見易さ・分かり易さを重視するか、意見が分かれるところかと思います。

それでは簡単に中身を見てみます。

最初の変数Mapperでループごとにインクリメントするのは前回のスクリプトと同様です。

次のMapperで、余りの演算をおこないます。

008

続いて、演算結果を基に条件分岐処理で処理を分岐させます。

分岐処理は3つあります。それぞれの条件式は以下の通りです。

009
condition

010
condition(1)

011
condition(2)

それぞれの分岐処理の後で、何の文字を出力するかを制御し、最終的にCSVファイル書き込み処理でその結果を出力します。

若干スクリプトのアイコン数は多いですが、中身はすっきりしているかと思います。

まとめ



というわけで、DataSpider Servistaのスクリプトで「Fizz Buzz問題」を解いてみました。

他にも色んな実装方法、たとえば一番目のスクリプトをもっとスマートにするといった方法や、「スイッチ判定による出力の切り替え」ロジックの替わりに「条件判定による出力の切り替え」ロジックを使用するといった方法も考えられます。

ご意見やこれぞ!という案があれば、ぜひ本エントリにコメントをお寄せください!お待ちしています!!

追記



…というところまでがブログに掲載した内容です。その後、なんとエントリにコメントをいただきました!

せっかくいただいたので、ここに全文引用させていただきます。

こんにちは。丁度社内でデータスパイダーの研修を受けているところで、講師の人から紹介されて、楽しく読ませてもらいました。
講師の人に、折角だからお前もチャレンジしてみろ、と言われたので、自分でも作ってみました。
最初に紹介されたパターンで、マッパーを3つが1つになるように作って見ました。
3か5で割って、0と等しいかを判定して、さらに両方とも0かどうかを判定して、最後にSWITHロジックで処理を分岐させてCSVに出すようにしました。
そうすれば、1つのマッパーでできました。
時間があれば、他のやり方も試してみようと思います。


おお…実際に試していただいたのですね…。感動です!!

私が文字列連結で強引に作ったパターンを、本来あるべき姿に作り変えていただいた内容ですね。素晴らしすぎます。

というわけで、コメントにいただいた内容を実際に作ってみることにします。

dstn_cookbook_fizzbuzz_01

…作ってみました。

ドキュメントMapperが1つだけなので、とてもすっきりしています!

では「演算と出力判定」の中身を見てみましょう。

dstn_cookbook_fizzbuzz_02

ちょっと画像が小さいですね。マッピングキャンバスだけにしてみましょう。

dstn_cookbook_fizzbuzz_03

こんな感じです。

ロジックアイコンの数が多くなりましたが、コメントを付与して配置に気を付ければ十分分かり易いのではないかと思いました。

いやぁ素晴らしいですね。スクリプト変数も1つしか使わずに済んだので、これが一番シンプルでよさそうです。Mapperロジックは汎用性が高いものが多いので、可読性にさえ気を使えばこれだけで済んでしまいそうです。

というわけで、他にもあればぜひぜひコメントください!

コメント

ログインしてコメントを残してください。

Powered by Zendesk