社内システムをPHPからPythonに切り替えるために、Pythonを1から勉強した

[社内](https://www.miraidenshi-tech.jp/intern-content/program/)のシステムをPHPのフレームワークのPhalconから急にPythonに切り替えることになりました。
社内で使ってる言語を統一したほうが良いし、Pythonのほうが将来的に良さそうだしね。
Phalconでやってきたことも役に立つはず！
ってなわけでPythonを全くの初心者から勉強していきます。

＊勉強メモなので、長ったるいです。
ご自分に必要な部分だけ見てください。
勉強中なので、随時更新していきます。

#Pythonって何ぞや
[このサイト](https://www.tiobe.com/tiobe-index/)によると、プログラミング言語の中で3番目に多く使われているらしい(2019年3月現在)。
しかも徐々に伸びてるところから、将来性を感じますね。
PHPは2010年からどんどん落ちてる、、、
2018年には「Language of the year」にも選ばれています。すごい！

###Pythonの特徴
<参考サイト>
[Tech Academy magazine](https://techacademy.jp/magazine/15507)

分かりやすい文法が特徴で、超一流のプログラマーと同じようなコードを初心者でも真似して書ける。
他の人気のある言語のC++やJavaに比べると簡単な構文でコンパイル不要、そして読みやすく書きやすい、コードも短い。

＊コンパイルとは
プログラムの翻訳機能のこと。
例えばJavaでは、機械が分かるように翻訳しないと、コンピュータが実行してくれないんです。

また、様々な分野で利用可能です。
・組み込みアプリ開発
・Webサイト構築
・AI(人工知能、機械学習)←数値解析に強い
・ディープランニング(深層学習)

GoogleやYoutube,NASAの内部でも利用されています。

Webサービスを作成する際によく利用されるのはDjangoというフレームワークです。聞いたことがあーる。

###Pythonを使うメリット・デメリット
○メリット
・Linuxに標準でPythonが動作するようになっているので、追加インストールせずに簡単に動作できる。
・誰が書いても同じようなコードになるので、他の人が書いたコードを元に勉強しやすい。

○デメリット
・「日本では」Pythonを使用した開発案件はまだ少ない。これからどんどん増えていくでしょう(アメリカで増えつつあるしね)。

#Pythonを使ってみる
[Pythonチュートリアル(日本語版)](https://docs.python.org/ja/3/tutorial/index.html)で、早速Pythonを勉強していきます。

###インタプリタを起動する

```python
python3
```
と打つと、

```python
>>>
```
こんなんが出てくる。

そもそもインタプリタとは、プログラミング言語で書かれたソースコード（＝プログラム）を読み込んで、それを機械語に変換してコンピュータに命令を与えてくれるもの。プログラム実行時にその都度変換します。
Javaはコンパイラで、事前に一括変換してから実行するんでしたね。

インタプリタは、

```python
quit()
```
で終了できます。
ちなみに、Pythonのコメントは#です。

###Pythonで計算してみる

```python
>>> 2+2
4
>>> 8/5
1.6
>>> 17/3
5.666666666666667
>>> 17//3
5   #floor division discards the fractional part
>>> 2**7
128   #2 to the power of 7
>>> 16%3
1
>>> width=175
>>> height=190
>>> washi=width*height
>>> print(washi)
33250
```
「//」と「**」知らんかった。。。

また、最後に表示された結果は変数```_```に代入される。
これを利用すれば、連続して計算できて便利！

```python
>>> tax=8/100
>>> price=2452929
>>> price*tax
196234.32
>>> round(_,1)
196234.3
```
しかも、虚数の計算もしてくれるぞぉ！(工学の研究者には助かる。)

```python
>>> i=3+5j
>>> a=8+2j
>>> i+a
(11+7j)
```

###文字列を操作する
文字列は```""```か```''```で囲みます。
**トリプルクォートも使えるそうです。しかも途中で改行を含めてOK!**
**コメントありがとうございます。**
引用符は```\```でエスケープできます。

```python
>>> print('don\'t')
don't
```

演算子で連結させることもできます。

```python
>>> print('bun'*3+'hachigatobu')
bunbunbunhachigatobu
```

連続して並んでいる複数の引用符に囲われた文字列は自動的に連結されます。長い文字列を改行したいときにはめちゃ役立つ。

```python
>>> text=('I am a student,'
... 'but I want to reform my office system.')
>>> text
'I am a student,but I want to reform my office system.'
```

文字列はインデックス(添字)を指定して文字を取得できる。
負の値も指定できるだと!?
負の値を指定すれば、右から数えて取得できます。

```python
>>> word='buntech'
>>> word[0]
'b'
>>> word[2:5]
'nte'
>>> word[-1]
'h'
>>> word[:2]
'bu'
>>> word[3:]
'tech'
>>> word[-3:]
'ech'
```

ちょっとややこしいですが、左から読むときは0スタート、右から読むときは-1スタートです。
-0と0を区別できないかららしい。
イメージするとこんな感じ。

```python
 +---+---+---+---+---+---+---+
 | b | u | n | t | e | c | h |
 +---+---+---+---+---+---+---+
 0   1   2   3   4   5   6   7
-7  -6  -5  -4  -3  -2  -1
```

文字列の長さを返すには、組み込み関数```len()```を使います。

```python
>>> s='fnaeorujapvjab;@efpbaerivrghanrpkivfha;pa'
>>> len(s)
41
```

###複合データ型で複数の値をまとめる
Pythonは多くの複合(compound)データ型を備えていて、複数の値をまとめるのに便利です。
その中で最も便利で汎用性が高いのが、```list```です。

```python
>>> squares=[2,3,5,7,11,13]
>>> squares
[2, 3, 5, 7, 11, 13]
>>> len(squares)
6
>>> squares[2]
5
>>> squares[-4:]
[5, 7, 11, 13]
```

ちなみに、変数の連結や入れ替えも可能。

```python
>>> squares+[17,19,23,29]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

>>> cubes = [1, 8, 27, 65, 125]  # something's wrong here
>>> 4 ** 3  # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64  # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]
>>> cubes.append(216)  # add the cube of 6
>>> cubes.append(7 ** 3)  # and the cube of 7
>>> cubes
[1, 8, 27, 64, 125, 216, 343]
```

こんな操作も可能。

```python
>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # replace some values
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
>>> # now remove them
>>> letters[2:5] = []
>>> letters
['a', 'b', 'f', 'g']
>>> # clear the list by replacing all the elements with an empty list
>>> letters[:] = []
>>> letters
[]
```

文字列のリストを入れ子(他のリストを含むリスト)にもできます。
どんどんややこしくなっていく、、、

```python
>>> a=['s','e','k','a','i']
>>> b=['h','e','i','w','a']
>>> c=[a,b]
>>> c
[['s', 'e', 'k', 'a', 'i'], ['h', 'e', 'i', 'w', 'a']]
>>> print('c-0-2 is',c[0][2])
c-0-2 is k
```

最後に、キーワード引数```end```を使うと、出力の末尾に改行文字を出力しないようにしたり、別の文字列を末尾に出力したりできます。

```python
>>> # Fibonacci series:
... # the sum of two elements defines the next
>>> a, b = 0, 1
>>> while a < 1000:
...     print(a, end=',')
...     a, b = b, a+b
...
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
```

#よく使う制御関数
###if文
```python
#書き方
if 条件式1:
    `条件式1がTrueのときに行う処理`
elif 条件式2:
    `条件式1がFalseで条件式2がTrueのときに行う処理`
...
else:
    `すべての条件式がFalseのときに行う処理`
```

他の言語と少し書き方が違いますね。
```else if```は```elif```と省略して書かれます。

また、ほとんどのプログラミング言語ではインデントはソースコードの見た目の問題なので、プログラムの意味には影響を及ぼしません。
しかし、Pythonではインデントによってプログラムの構造を記述します。
:とインデントで、C言語の{}の役目を果たします。
そのため、if文などではインデントに気をつけましょう。
インデントはスペース1回で書きます。

```python
>>> x = int(input("Please enter an integer: "))
Please enter an integer: 6
>>> if x<0:
...  x=0
...  print("Negative changed to zero")
... elif x==0:
...  print("Zero")
... elif x==1:
...  print("Single")
... else:
...  print("More")
... 
More
```

###for文
```python
#書き方
for 変数 in データの集まり:
    処理
```

for文の流れは「データの集まり」から、「データを一つずつ取り出す」という流れです。

```python
>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12

>>> for char in "Hello":
...  print(char)
... 
H
e
l
l
o
>>> 
```

文字列は1つ1つ取り出すから、縦長に表示されるわけですね。
その他の例はこちら。

```python

>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)  #長さが6より大きいなら、wordsの1番目に挿入する
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
```

###range()関数
数列にわたって反復を行う組み込み関数です。

```python
>>> for i in range(-10,-100,-30):  #-10~-100までの数字を30飛ばしで```i```に代入
...  print(i)
... 
-10
-40
-70
```

ちなみに、range()はリストではないので、注意が必要です。
どういうことかと言うと、

```python
>>> range(5)
range(0, 5)
>>> print(range(5))
range(0, 5)
>>> list(range(5))
[0, 1, 2, 3, 4]
```

rangeを出力しようとすると、おかしくなります。
range()は連番や等差数列を生成したり、リストを取得したりする「関数」です。
そのため、注意が必要です。

```python
>>> a=['January','February','May','April','March']
>>> for i in range(len(a)):  #len(a)=4
...  print(i,a[i])
... 
0 January
1 February
2 May
3 April
4 March
```

ただ、このような出力をするなら、*enumerate*関数の方が便利らしい。
＊enumerate：列挙する,数えあげる

```python
>>> seasons=['Spring','Summer','Fall','Winter']
>>> list(enumerate(seasons,start=1))
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
```

こっちの方がシンプルですね！

###break文とcontinue文とループのelse節

```python
>>> for n in range(2,10):
...  for x in range(2,n):
...   if n%x==0:
...    print(n,'equals',x,'*',n//x)
...    break
...  else:
...   print(n,'is a prime number')
... 
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
```

素数を出力するコードはこんな風にかけます。
elseはif文ではなく、for文に属しているんですね！
そのため、elseのインデントは2個目のfor文に合わしています。

```python
>>> for n in range(2,11):
...  if n%2==0:
...   print("Found an even number",n)
...   continue
...  print("Found an odd number",n)
... 
Found an even number 2
Found an odd number 3
Found an even number 4
Found an odd number 5
Found an even number 6
Found an odd number 7
Found an even number 8
Found an odd number 9
Found an even number 10
```