Pythonでプログラミング！ ~入門編 パート1~

# Python入門編 その1

今回扱うプログラムは[こちら](https://github.com/victor-von-pooh/Python_Learn/blob/main/Python%E5%85%A5%E9%96%80%E7%B7%A8/Python_1_1.ipynb)にあるので、是非ダウンロードしてみてください！
中身はここにあるものと一緒です。

## イントロダクション

こんにちは、東京理科大学所属の秋田と申します！

今回は、Pythonを使ったプログラミングをしてみようと思っている民に向けて、「ゼロから始める」をモットーにチュートリアルを作ってみたので、是非楽しんで学んでくだされ〜。

## Section 0. 「Pythonの実行環境の構築」

キーワード :
*   Pythonの環境構築

Pythonを扱う上で、パソコン1台あれば誰でもすぐにプログラミングができるというわけではありません！！！
実は、Pythonでプログラミングをする方法はいくつかあるんです。
このセクションでは、それを少し紹介したいと思います(基本Macを前提にやってます)。

### 方法1. 手元(ローカル)で行う

Macでは**ターミナル**というプログラムの実行をする**シェル**があります。
まずはそこでPythonをインストールするところから始めましょう。
ここでまた、分岐点がございます。
Pythonを使う目的というか、私的な利用なのか商用的な利用なのかで変わってくるんです！
まあ、商用的な利用の方法でやれば安全ではあるので、基本そちらを参考にしたいと思います。
まずは商用利用の場合のインストール方法から、

1. まずは [Homebrew](https://brew.sh/index_ja) のインストールをする(ターミナルで以下のコマンドを実行)
        /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
2. 次にターミナルでPython3のインストールをする(以下のコマンドを実行)
        brew install python3
3. シェル上で `python` と入力して >>> が出てきたら成功、そこに `exit()` と入力して終了する
4. 最後に `pip -V` と入力してエラー等が出なかったらOK

と、こんな感じです。
なぜこれが商用利用の場合として分けられているかというと、そうです、次に紹介する[Anaconda](https://www.anaconda.com/)というパッケージは便利な一方で、ライセンスが規制されているものがあり、原則私的利用のみ可能となっています。
商用に使う予定はないよという方は、問題ないのでこちらからインストールしましょう。
こちらの作業は非常に簡単で、

1. [Anaconda](https://www.anaconda.com/) からダウンロードし、流れに沿ってインストール
2. シェル上で `python` と入力して >>> が出てきたら成功、そこに `exit()` と入力して終了する
3. 最後に `pip -V` と入力してエラー等が出なかったらOK

です。
以上が、Mac(ローカル)でのPython環境の構築です。

### 方法2. Colabで行う

なんとPythonは面倒な環境整備をせずとも、Googleアカウントさえあれば簡単にプログラミング出来ちゃうんです！

1. Googleアカウントを作成し、Chromeから [Colab](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja) を開く
2. 「ファイル」を押して「ノートブックを新規作成」を選択

これでもうPythonでプログラムが組めるんです！
これは拡張子が「.ipynb(通常のPythonファイルの拡張子は.py)」のファイルになります。
それぞれのセルごとに実行が可能で、お試しに動くか実験したいときなどに非常に便利です。
そして、ローカルのものにはないGPUマシンへの無料アクセスができるので、機械学習などをするのにも向いています！

## Section 1. 「Pythonの文法の基礎」

キーワード :
*   入出力
*   変数の型
*   for文
*   if文

では早速プログラムを組んでみましょう。
まずは出力をするところから始めましょう。
Pythonでの出力は他言語に比べ非常に簡単で、試しに「単位落とした！」と出力してみましょうか。

```python
print('単位落とした！')
```

はい、これだけです。
たった1行からプログラムが出来ちゃうんです！

ではこのまま入力もやってみましょう。

```python
input_something = input()
```

`input_something` という変数に入力したものを格納します。
= の右側の `input()` は入力を受け取ってくれる関数となっています。
この入力は文字列(string)となっています。
なので、例えば入力に '1' と '2' を入れて足すということをしても '3' にはなりません。
試しにどうなるか出力してみましょうか。

```python
"""
1
2
"""

input_something_1 = input()
input_something_2 = input()

output = input_something_1 + input_something_2
print(output)
```

はい、 '12' と出力されました。
これは、入力が文字列なので出力も文字列になってしまうからです。
例を挙げると、入力を 'りんご', 'みかん' にして同じプログラムを動かすと 'りんごみかん' と返ってくるということです。

では、数値として受け取るにはどうしたらいいでしょうか。
次のようにしてみます。

```python
"""
1
2
"""

input_something_1 = int(input())
input_something_2 = int(input())

output = input_something_1 + input_something_2
print(output)
```

先ほどのものとの違いは、 `input()` を `int()` の()で囲っているということです。
int とは、 integer(整数) のことで、入力したものを整数として認識するということです。
よって、数値入力に対しては有効である一方、 'りんご' などの文字列入力などにはエラーを起こしてしまいますね。

では、整数を返すのであれば、少数を入力したらどうなるでしょうか。
試しに '1.2' と入力してみましょう。

```python
"""
1.2
"""

input_something = int(input())
print(input_something)
```

あ、怒られましたね(笑)
そういう場合はどうするかということですが、基本的に少数は 'float()' を使います。

```python
"""
1.2
"""

input_something = float(input())
print(input_something)
```

と、このようにちゃんと認識してくれますね。
また、一度プログラムが少数と認識してくれたものに関しては、先ほどの 'int()' で整数値だけ引っ張り出すことができます。

では同じように '1.2' とすると何が返ってくるでしょうか？

```python
"""
1.2
"""

input_something = float(input())
input_something = int(input_something)
print(input_something)
```

'1' と返ってきますね。

では、 '1.8' ではどうでしょうか？
切り捨て？切り上げ？四捨五入？

```python
"""
1.8
"""

input_something = float(input())
input_something = int(input_something)
print(input_something)
```

'1' と返ってきますね。
切り捨てだとわかりました。
逆に、整数型で受け取った変数を 'float()' で囲ってみると、ただの '.0' が付与されるだけです。
このように、扱う変数は型を持っていて、場合によっては行き来できるようになっています。
文字列の形にしたければ、 'str()' で囲えば大丈夫です。

続いて、for文についてです。
似たようなものにwhile文がありますが、それは必要であれば後で出しましょう。
for文は、指定した回数だけ、その中のプログラムを繰り返し回すものです。
次のような使い方をします。
ここでは先ほどの「単位落とした！」という文章を10回出力するものになります。

```python
for i in range(10):
    print('単位落とした！')
```

forの後の 'i' は今回特に意味を成しませんが、この後しっかり出てきます。

`for 'something' in range('args'):`

と書き、 'something' のところは好きに名前をつけても大丈夫ですが、一般的に数を扱ってくる場合は 'i' や 'j' を優先的に使うことが多いです。
そして、 range() の中の 'args' はこの range() という関数の引数を入れます。
引数が1つの場合は、ここに整数を入れ、その回数だけfor文の中の処理を行います。
2つの場合は、 range(5, 10) というように書き、1つ目の5は 'i' を5から始めて、 'i' が9(10 - 1)になるまで処理を行うという意味になります。
これが少し直感に反するもので、コンピュータというのは基本的に0から数え始めます。
3つの場合はそんなに使わないので省略します。

さて、気づいた方もいると思いますが、1回ごとに改行がなされていますね。
Pythonでは 'print()' をするごとに改行が行われます。
これを改行せずに出力する方法はありますが、それは一旦置いておきましょうか(笑)

では実際に 'i' を使ったプログラムを組んでみましょう。

```python
for i in range(10):
    print(f'{i}単位落とした！')
```

このように、 'i' が1ずつ大きくなって出力されていますね。
そして範囲が0〜9なのも確認できました。
もうちょっと見てみましょう、 range() の引数を2つにしてみるとこのようになります。

```python
for i in range(5, 10):
    print(f'{i}単位落とした！')
```

続いて、if文という条件分岐をしてくれる処理について学びましょう。
先ほどのfor文を使って、 'i' が偶数のときだけ出力するプログラムを立ててみましょう！

```python
for i in range(10):
    if i % 2 == 0:
        print(i)
```

ここで、 '%' は 'i' を2で割った余りを出すという意味で、 '==' と '=' を2つ並べるのは、1つだと「代入」の意味になってしまい、「等号」の意味にするために2つ並べる必要があるからです。
このif文の中では、この条件のもとでのみ処理を行なうことになります。
if文には他にセットで覚えておくことがあり、それは他の条件を設定する 'elif' と、その他の場合という意味の 'else' です。
まずは 'elif' から見てみましょう。
0〜9の中で3で割った余りが0, 1, 2それぞれの場合で文章が変わるようなプログラムを立ててみましょう！

```python
for i in range(10):
    if i % 3 == 0:
        print('単位落とした！')
    elif i % 3 == 1:
        print('単位取った！')
    elif i % 3 == 2:
        print('単位没収された！？')
```

'elif' を2回使って条件を3つに分けることが出来ましたが、3で割ったときの余りは0か1か2しかなく、0と1の条件を書いた後は残り2になる場合しかないので、わざわざもう一度 'elif' の条件文を使う必要はなく、 'else' を使って簡単に書くことが出来ます。

```python
for i in range(10):
    if i % 3 == 0:
        print('単位落とした！')
    elif i % 3 == 1:
        print('単位取った！')
    else:
        print('単位没収された！？')
```

簡単になりますね！

## Section 2. 「配列」

キーワード :
*   ベクトル
*   行列
*   テンソル
*   要素の追加

プログラムを組む上で、算出した値を保存するものが必要になってきますね。
他にもデータとしてすぐに引き出せるようにしないといけない場面はたくさんあります。
そのような場合に役に立つのが配列です。

```python
words = ['りんご', 'みかん', 'バナナ', 'いちご']
```

配列を作るときは、 '[]' の中に要素を入れます。
',' で区切って考えるので、上で作った 'words' という配列の中には4つの果物の名前が格納されています。
今考えている配列は、1次元なのでこれを「ベクトル」という風に呼ぶこともあります。
この 'words' の中から 'バナナ' だけを抜き取り、それを出力させてみます。

```python
words = ['りんご', 'みかん', 'バナナ', 'いちご']
banana = words[2]

print(banana)
```

'words' という配列の中で、 'バナナ' は3番目にいるので、インデックス番号は2となります(0から数えるため)。
よって、 'words[2]' と 'words' の後ろに '[2]' と付けてあげることによって 'words' ベクトルの3番目の要素を指すことになります。
ということは、for文を用いて、全ての要素を順番に抜き出すことも出来ますね。

```python
for i in range(4):
    print(words[i])
```

配列には、長さというものがあります。
今回の場合、4つの要素があるので長さも4となります。
しかし、場合によっては長さがわからない配列が与えられることがあったり、こちらが忘れてしまうこともよくあります。
そんなときには、その配列の長さを教えてくれる 'len()' という関数があります。
やってみましょう！

```python
words = ['りんご', 'みかん', 'バナナ', 'いちご']
length = len(words)

print(length)
```

'len()' の中に配列の名前を入れてあげることで確認が出来ました！
for文と組み合わせるときにはこの 'len()' を使って範囲を指定することが多いです。

```python
for i in range(len(words)):
    print(words[i])
```

世の中のデータというものを全て1次元で管理しようとするのは難しい話です。
例えば、中学校の同学年の人数が120人で、1クラスあたり40人とすれば3クラスできるように、要素数40個のベクトルを3つ並べるということをします。
つまり、ベクトルのベクトルを作るということです。
これは1次元管理が難しい場合に2次元拡張することで、データの取得を簡単に出来ちゃいます。
この2次元の配列を「行列」と言うことがあります。

```python
matrix = [
    ['りんご', 'みかん', 'バナナ' , 'いちご'],
    ['人参', 'キャベツ', '玉ねぎ', 'ピーマン'],
    ['マグロ', '鮭', 'カツオ', 'イワシ']
]
```

さて、この行列の長さはどうなるでしょうか？

```python
print(len(matrix))
```

はい、これは構造として3つのベクトルで構成されているので長さは3となりますね。
試しに要素を出力してみましょうか。

```python
for i in range(len(matrix)):
    print(matrix[i])
```

今、各iにおいて 'matrix[i]' はベクトルとなっているので、このベクトルの中の要素を取り出したいときは、 'matrix[i][j]' のようにしなければいけません。

```python
matrix = [
    ['りんご', 'みかん', 'バナナ' , 'いちご'],
    ['人参', 'キャベツ', '玉ねぎ', 'ピーマン'],
    ['マグロ', '鮭', 'カツオ', 'イワシ']
]
salmon = matrix[2][1]

print(salmon)
```

ここで、 'i' と 'j' は範囲が(一般的に)異なるのでそれぞれで変数を定義する必要があります。
よって同一のfor文の中で 'matrix[i][j]' とすると 'j' とはなんぞやと怒られたり、 'matrix[i][i]' とすると対角成分しか抜き出されなかったりとなるわけです。
こんなときのためにfor文を2重にするということをします。

```python
for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        print(matrix[i][j])
```

ここで勘の良い方は気づいたかもしれないですが、2次元止まりではないかもしれないということですね。
つまり、行列を要素とするベクトルを作ることもできるだろうと。
例えば、先ほどの例で言うと、1クラス40人で3クラスで1学年、3学年あるのでそれが3つとなりますね。
また、個人の科目別の成績を考え、 '['国語', '数学', '社会', '理科', '英語']' の定期テストの点数を一番小さい単位とすると4次元にまで拡張されます。
このように2次元以上の配列を考える場合もあり、3次元から先を「テンソル」と言うことがあります。
そのような場合も同様に考えれば大丈夫です。

では、今度は配列の要素を追加することを考えましょう。
先ほどの 'words' の中に 'ぶどう' を追加してみましょう。

```python
words = ['りんご', 'みかん', 'バナナ', 'いちご']
print(words)

words.append('ぶどう')
print(words)
```

このように、 `.append()` とすることで要素を追加することが出来ます。
逆に要素を削除する方法はいくつかあるのですが、使わないことの方が多いので今回は省略します。

## Exercises

### Exercise 1.

0〜86399までの整数を入力して、 H:M:S (Hは時間、Mは分、Sは秒) となるように変換しましょう。
例えば、入力が 46979 のとき、 13:2:59 と出力されるようにしましょう。
このとき、 ':' の前後に空白は入れてはいけません。
また、ライブラリのインポート(すなわち `import ~~~` というもの)は禁止とします。

```python
# 入力する整数一覧
nums = [4198, 6313, 349, 85131, 73240]
ans = []

for index in range(len(nums)):
    input_num = nums[index]

    # コードを書いてください↓↓↓
    
    # コードを書いてください↑↑↑

    ans.append(answer) # 答えを answer という変数名で保存する
```

ヒント1.

> 整数 m を 整数 n で割ったときの商を求める演算子は '//'
> つまり `x = 100 // 5` で x は20となる

ヒント2.

> y = f'xは{x}' とすると yは「xは20」という文字列になる

```python
# 答え合わせ

correct_ans = ['1:9:58', '1:45:13', '0:5:49', '23:38:51', '20:20:40']
for i in range(len(ans)):
    if ans[i] == correct_ans[i]:
        print('正解')
    else:
        print('不正解')
```

### Exercise 2.

縦H個、横W個の長方形を描くプログラムを作成しましょう。
ただし、 '#' を周上だけにし、中は '+' になるように出力します。
例えば、 H = 4, W = 5 の場合、

```
#####
#+++#
#+++#
#####
```

のように出力しましょう。
また、ライブラリのインポート(すなわち `import ~~~` というもの)は禁止とします。

```python
# 入力するH, W一覧
H = [3, 7, 5]
W = [4, 6, 5]

for inputs in range(len(H)):
    h = H[inputs]
    w = W[inputs]

    # コードを書いてください↓↓↓
    
    # コードを書いてください↑↑↑
```

ヒント1.

> h, wそれぞれでfor文(つまり2重for文)

ヒント2.

> `print('#', end='')` と2つ目の引数を入れると print() での改行がなくなる

### Exercise 3.

[この問題](https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_11_A&lang=ja)をPythonで解きましょう。
また、ライブラリのインポート(すなわち `import ~~~` というもの)は禁止とします。

```python
# 入力一覧
inputs = [
    [[1, 2, 4, 8, 16, 32], 'SE'],
    [[1, 2, 4, 8, 16, 32], 'EESWN'],
    [[7, 8, 9, 10, 11, 12], 'W'],
    [[1, 2, 3, 4, 5, 6], 'SSSSSEEEWWWNNNSSSNEENNNWWWWEEEENNNNNNNSSNNSNSNSNSWEWEWENNN'],
    [[32, 59, 68, 1, 2, 12], 'SSNWNNSESSNWNWNNSEWWSSWWNWWNSESSWNNWNNSESSSSNWNNSESSSSNWNNSESSWWNWNNSESSSSNWNNSESSEWNWSSSESSWWNWSNSE']
]

# 正解出力
outputs = [8, 32, 9, 6, 1]

for index in range(len(inputs)):
    dice = inputs[index][0]
    order = inputs[index][1]

    answer = outputs[index]

    # コードを書いてください↓↓↓
    
    # コードを書いてください↑↑↑

    if my_ans == answer: # 答えを my_ans という変数名で保存する
        print('正解')
    else:
        print('不正解')
```

ヒント1.

> 普通のサイコロは出た目とその裏の合計は必ず7になる

ヒント2.

> E, W, N, Sそれぞれの場合に条件分岐させる

## 終わりに

お疲れ様でした！
今回はここまでとなります。

次回は、Pythonライブラリを活用したプログラミングについて一緒に学んでいきましょう！