IQ Bot のカスタムロジック：他の言語をやっていた人が初めてPythonを触ったとき、びっくりするかもしれない５つのポイント

こんにちは。

[IQ Bot](https://qiita.com/IQBotter/items/fab5f59230ff38a98bbd)のカスタムロジックは結局はPythonなので、Pythonが書ける人は難なく扱えるはずです。

そしてPythonはJavaやCなどのプログラミング言語に比べれば、初心者が入りやすい言語だと言われています。

JavaやCなど他のプログラミング言語をやっていた人は、
ゼロから始める人よりは早くPythonをマスターできると思いますが、

他の言語をやっていたがゆえに「えっ？　そんなのあり？」とびっくりするポイントもあるかもしれません。

この記事では、他言語を扱っていた人ならではのPythonびっくりポイントをまとめてみます。

#コンパイルがいらない

Pythonは動的言語なので、動かすにあたってコンパイルが要りません。

なのでIQ Botのカスタムロジックも、コンパイルとか気にすることなく、
書いたら即座に「Test Run」を押せばその場で動きます。

動的言語についての説明は[Wikipedia](https://ja.wikipedia.org/wiki/%E5%8B%95%E7%9A%84%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E)にまとまっていたのでそちらをご参照ください。

#型を宣言しないで変数を使える

Pythonは型付けを動的に行っているので、変数の型を宣言する必要がありません。

Javaの場合、以下のようなコードを書くと、
２行目で怒られてコンパイルエラーになります。

```java:javaの場合
int num = 3;       // ここで変数numの型を宣言！
num = "やっほー";   // こういうことすると怒られます
```

int型、つまり「整数しか入らないよ」って言ってる箱（＝numという変数）に、
`"やっほー"`などというふざけた文字列（String型）を突っ込もうとしたからですね。

あ、すみません、問題は「型が違う」という点なので、文字列の中身がまじめでも怒られます。

一方、Pythonの場合は以下のようなコードでも全然問題なく動きます。

```python:Pythonの場合
num = 3           #こうすれば変数numは勝手にint型になる  
num = "やっほー"   #ここで変数numは勝手にString型に変身する……！！
```

この特徴は、筆者のような雑な性格の人間にとっては非常にありがたいんですが、
他のプログラミング言語のお行儀のいいコーディングに慣れている人からすると、

「変数の型が途中で変わる」というのはけっこうびっくりする話かもしれません。

Pythonでも型という概念自体がなくなっているわけではなく、
あくまで型付けをプログラミング言語側で動的にやってくれる機能があるというだけです。

Pythonの型の一覧や、型の確認方法、キャスト（型変換）のしかたなどは
[こちら](https://qiita.com/yoshi0518/items/e8548afe8fc3ad1d10a6)のページに非常にわかりやすくまとまっていました。

IQ Botにカスタムロジックをかける際も、型のキャストは時々使います。


#インデントに実行上の意味がある

他の言語の場合、if文や関数の中でインデントを揃えるのはあくまでも
「人間にとっての可読性向上のためのベストプラクティス」であって、

インデントにはプログラムを実行する上での意味は持たせていないという仕様が一般的です。

つまり以下のように、インデントが汚くてもプログラムは問題なく動く、という言語がほとんどです。

```java:javaの場合①：こう書いた方がきれいだけど……
class xxx
{
  public static void main (String[] args) throws java.lang.Exception
  {
    int num = 3;
    if (num % 2 == 0) 
    {
      System.out.println(num + "は、偶数です");
    }
    else {
      System.out.println(num + "は、奇数です");
    }
  }
}
```

```java:javaの場合②：これでも動くことは動く。
class xxx
{
public static void main (String[] args) throws java.lang.Exception
{
int num = 3;
if (num % 2 == 0) 
{
System.out.println(num + "は、偶数です");
}
else {
System.out.println(num + "は、奇数です");
}
}
}
```

一方、Pythonは「すべてのプログラマーがすべからく可読性の高いコードを書くことを保証するように」という思想に基づき、
インデントを揃えないとそもそもコードが動かないようになっています。

```python:Pythonの場合①：こう書けば動くけど……
num = 3
if num % 2 == 0:
	print(str(num) + "は、偶数です")
else:
	print(str(num) + "は、奇数です")
```

```python:Pythonの場合②：これだと動かない
num = 3
if num % 2 == 0:
print(str(num) + "は、偶数です")
else:
print(str(num) + "は、奇数です")
```

インデントが正しくそろってないと、基本的には「IndentationError」というエラーが出ます。

[こちらの記事](https://qiita.com/yuto-naga/items/622d564bd0417812ca84)のように、インデントのレベルが正しくいないがゆえに、
想定と違う結果が出てしまうケースもあるので注意しましょう！

#ループが楽

PythonとJavaのループ処理をわかりやすくまとめた記事があったので、
そちらを紹介しておきます。

[JavaとPythonの基礎文法比較](https://qiita.com/imuimu/items/1e1581bd0749a871c213#5for%E6%96%87)

ループ処理以外の文法も色々まとまっているので参考にしてみてください。

#文字列を配列みたいに扱える

Javaなどの言語をもともとやっていた人からすると、
上記のリンクにあった以下のコードを見ると、けっこうびっくりするかもしれません。

```python:Pythonではわりと一般的なループ
for char in 'Hello':
    print(char)
```

上記の処理をやると、以下の結果が返ってくるんですが……

```python:上記ループの処理結果
>>>H
>>>e
>>>l
>>>l
>>>o
```

なぜこんなことができるのかというと、Pythonでは文字列を、
**ひとつひとつの文字を要素として持つシーケンスとして扱う**という発想があるからです。

なので、Javaみたいにまず配列に分けて、それからループを回して、みたいなことをする必要がなくて、
文字列をそのままループやスライス（文字列の何番目から何番目を取得するような処理）にかけることができます。

スライスはIQ Botのカスタムロジックでも意外と（？）使うので、
わかりやすかった記事をリンクしておきます。

[【Python】スライス操作についてまとめ](https://qiita.com/tanuk1647/items/276d2be36f5abb8ea52e)

#まとめ

いかがでしたか？

他言語をやっていた人ならびっくりするかもしれないPythonのポイントは、まとめると以下のとおりです。

- Pythonは動的言語なのでコンパイルが要らないよ
- Pythonは動的型付けができるので変数の型を宣言する必要がないよ（型という概念はあるのでキャストはできるよ）
- インデントを揃えないと怒られて実行できないよ
- ループの書き方がJavaとはけっこう違うかも
- 文字列を配列みたいに扱って直接ループにかけたりスライスしたりできるよ

他にも発見したら追記します。

それでは！