第5回【Python】2 の累乗を表示、FizzBuzz

はじめに

猫とキャンプと野球観戦と AWS が大好きな旦那、LeoSaki です。モフモフしたい。

Python をゼロから勉強してみよう、のコーナー 5 回目です。
paiza ラーニングで学習しています。

この章のテーマが「ループ」であることを意識しながら、問題に取り組みたいと思います。自分のキャラクターが定まらないまま始めたので、いつもフワフワした感じで書いていますが、問題への取り組みは真剣です!

2 の累乗を表示

整数 N が与えられます。
2 の 1 乗から 2 の N 乗までを改行区切りで出力してください。

まぁ、なんだ。Python においての累乗の書き方がわからずに右往左往した。最初に強引に書いたコードがこれ。

Python
N = int(input())
ans = 1
for _ in range(N):
    ans *= 2
    print(ans)

間違ってはいない。間違ってはいないはずなんだが、美しくない。ということで、Python の四則演算について調べることにする。

使い方説明
x + yx と y の和5 + 2 = 7
x – yx と y の差5 – 2 = 3
x * yx と y の積5 × 2 = 10
x / yx と y の商5 ÷ 2 = 2.5
x // yx と y の商の解を切り下げたもの5 ÷ 2 = 2
x % yx と y の剰余(つまりは余り)5 ÷ 2 = 2 … 1
x ** yx の y 乗5 ^2 = 5 × 5 = 25

「 x // y 」なんて使い慣れていないものが出てきた。まぁ、コンピューターを利用した演算だと誤差が生じることが多々あるので、最初から切り下げるぜ、と言われた方が助かる。嘘です。まだあまり効果を実感したことはありません。もっと学習を続けます。

今回の主題は「累乗」。なるほど。*(アスタリスク)を2個並べることで、累乗を表現できるのか。

Python
N = int(input())
for n in range(1,N+1):
    print(2**n)

とてもスッキリ書けた気がする。
ああ、また、1 行おじさんが息を切らしながら駆けつけてきた。

Python
print(*[2**n for n in range(1,int(input())+1)],sep="\n")

他の言語ではなかなかできない芸当ではあると思うが、可読性は皆無だと思うので、ただのお遊びとして見てください。

さぁ、VBA ではどうなるのか。
セル A1 に N が入力されています。

VBA
N = Cells(1, 1)
For i = 1 To N
    Debug.Print 2 ^ i
Next

いつも思うのだが、VBA の For 文の可読性は高い気がする。私みたいな素人には、という話。

FizzBuzz

1 ~ 100 の整数に対して、3 と 5 の両方で割り切れるなら FizzBuzz を、 3 でのみ割り切れるなら Fizz 、5 でのみ割り切れるなら Buzz を改行区切りで出力してください。また、どちらでも割り切れない場合は、その数字を改行区切りで出力してください。

整理してみると、1 は「どちらでも割り切れない」から 1、2 は「どちらでも割り切れない」から 2、3 は「3 でのみ割り切れる」から Fizz、4 は「どちらでも割り切れない」から 4、5 は「5 でのみ割り切れる」から Buzz、・・・15 は「3 と 5 の両方で割り切れる」から FizzBuzz を出力する。

Python
for i in range(1,101):
    if i % 3 == 0 and i % 5 == 0:
        print("FizzBuzz")
    elif i % 3 == 0:
        print("Fizz")
    elif i % 5 == 0:
        print("Buzz")
    else:
        print(i)

Python には Switch 文がないので、はっ!? いつも VBA で例えていたのに。・・・Python には Select Case 文がないので、if 文で表現するしかないようだ。

行数を減らす方法として、if 文を三項演算に変えてみるとか考えてみたけれど、ただただ横に長くなるだけで、自分で書いたコードを理解するのに時間がかかるという。ぱっと見て理解できるコードって重要だよね。

さぁ、VBA で書いてみよう。

VBA
For i = 1 To 100
    Select Case True
        Case i Mod 3 = 0 And i Mod 5 = 0
            Debug.Print "FizzBuzz"
        Case i Mod 3 = 0
            Debug.Print "Fizz"
        Case i Mod 5 = 0
            Debug.Print "Buzz"
        Case Else
            Debug.Print i
    End Select
Next

上で Select Case 文って言った手前、Select Case 文で書いてみました。このくらいならば、if 文でも可読性が悪くなるってことはないでしょうかれど。

最後に

Python での処理速度については、まだ不勉強で分かりません。

なので、VBA の処理速度のみに焦点を当てて考えてみますと、今回くらいの条件分岐であれば、if 文で十分だと思います。Select Case の方が読みやすいので、LeoSaki(旦那)は Select Case を使うことが多いですけれど、今回のような 3 つくらいの条件ならば、if 文で書く方が早い気がする。

Python の if 文ってどうなんだろう。条件が増えた場合の処理速度は。

まぁ、どんな言語であっても、条件分岐をいかにうまく処理するコードを書くか、はプログラマーの腕の見せ所な気がしているので、今後の課題として学習していこうと思います。

とある会社さんの VBA を見せてもらったときに、数百行のテーブルの中の分類ごとの小計を別のシートに表示させるのに、全部 if 文で小計のあるセルを指定してあって、それが数十行続く。これ、分類が変更になったときはどうするんですか? って聞いてみたら、if 文の条件を手動で直す、とのこと。

イメージとしてはこんな感じ。40 行目に一つ商品が増えたら、それ以降のセルの指定を全部手直しで修正。

if range("A2") = range("B30") then
    シート.range("A1") = range("F30")
else range("A2") = range("B50") then
    シート.range("A1") = range("F50")
else range("A2") = range("B80") then
    シート.range("A1") = range("F80")
・
・
・
if range("A2") = range("B30") then
    シート.range("A1") = range("F30")
else range("A2") = range("B51") then
    シート.range("A1") = range("F51")
else range("A2") = range("B81") then
    シート.range("A1") = range("F81")
・
・
・

もちろんコレはイメージで、もっと複雑ではあるんだけれど。

LeoSaki(旦那)も、以前の会社で事務作業していた頃、これに近いコードを書いていたことはあるし中小企業で専門家を置いていない事務作業ってこんなものなんじゃないかな?

だからこそ、基礎を勉強するのって大切だと思うのです。今更ながら、Python をゼロから勉強している理由を語ってみた。

引き続き、よろしくお願いいたします!

Pythonpaiza,学習,Python

Posted by LeoSaki