JavaおじさんがPythonを使えるようになるまでの全記録（その１）

#自己紹介
こんにちは、Javaおじさんです。
というか別にそこまでJavaにめっちゃ造詣が深いわけでもないけど、
今まで一番キャリアとして多く扱ってきた言語がJavaだってだけのこと。

Javascriptも使えますがAngularとかReactとかVue.jsとか知りません。
Node.jsはちょっとだけかじりました。
せいぜいjQueryとBootstrapがわかる程度。
うん、知ってますよBootstrapは厳密にはCSSのライブラリだってことはね。
でもカルーセルとかで使ってるじゃない内部では。

RDBなら論理/物理設計、実装、チューニングまでおまかせだけどNoSQLはかんべんな。

というおじさんです。
絶賛お仕事募集中です。

とはいえ、仕事としてJavaをやってくのもいい加減そろそろ限界あるよね、
でも名古屋の現場でPythonやらせてくれるとこなんて少なくともSES契約の会社じゃないよね、
なんたっていまだにVB6.0のメ（これ以上はいけない）
ということで自力でどうにかすることにしました。

#利用テキスト
個人的に字が満載された書籍を読むのは別に苦痛でも何でもないので、テキストは以下を使用。
[世界標準MIT教科書 Python言語によるプログラミングイントロダクション第2版: データサイエンスとアプリケーション](https://www.amazon.co.jp/gp/product/4764905183/ref=oh_aui_detailpage_o02_s00?ie=UTF8&psc=1)

なんといっても世界標準ですから。（おじさんらしい偏見に満ちた意見）

#目標設定
何をもって「使える」と定義するのか、これがないとやみくもにあれこれ手を出して自爆するので、目標設定大事。
何はともあれ最終目標は「Pythonのお仕事を受けられるようにする」なので、小目標としてはこんな感じでよかんべ。

1.基本的なアルゴリズム（バブルソート、バイナリサーチなど）がコーディングできる（言語の基本制御構造理解）
2.オブジェクト作成およびそのオブジェクトに対する自動テストができる（Pythonを使ったオブジェクト指向に関する機能理解）
3.機械学習とかWebアプリとか書けるようにする。
3-1.（なんかテキストの目次見ると後半はベイズ統計とか機械学習とかいろいろ書いてあるので）テキストの内容をコードを書きながら理解する。
3-2.ちょっと複雑なWebアプリ（複数のModelオブジェクトがからんでくるやつ）をDjangoを使って書けるようにする。当然DB含む。

3がグダってるけどまあ是非もないねｗ
「今さらDjangoかよ、もっとクールなフレームワークあるぜ」という方はぜひ教えてください。
当方に軌道修正の用意あり。でも仕事に使うって意味ならググったところDjangoでよくね？どうなの？

#まずはインストールから
さて、何はともあれPythonをインストールっと。
テキストではAnacondaを使ってるらしいので素直にAnacondaを導入してみよう。
だめならVisual Studio CodeにPythonモードぶち込めばいいんだろ？

当方WindowsとMacの2台持ち体制になってるんだけど、MacBook Proは2世代前のマシンなので
XCodeとXamarinとAndroid StudioとNode.jsで結構容量食っていて、とりあえずマシンとしては新しい方のWindowsで様子見。
機を見てMacにも導入しよう。

[ダウンロードページ](https://www.anaconda.com/download/)

ここからWindows用のディストリビューションをダウンロードしてくる。
む、ここに同梱されてるのはPython3.6なのか...確か現状の最新版って3.7じゃなかったっけな。いいのかなこれ。
まあいいや、だめならV（略）
インストールpathだけ容量のでかいドライブに変えてあとは全部デフォルトでインストール。
tiffとかtcl/tkとかクッソ懐かしいな。
昔のUNIXマガジンとか思い出すわ。

#基本構造の確認
インストール画面をぼんやり眺めてても仕方ないのでテキストを読み進めよう。

Noneってなんじゃろ？（おやじギャグ）
4章で出てくる...ずいぶん先だな。JavaでいうNullかな？

文末にセミコロンを入れなくていいのは楽でいいな。

演算子は...なるほど割り算に関してほかの言語とちょっと違うのか。
「//」だと整数除算になって「/」だと小数型で返ってくると。
これもわかりやすいといえばわかりやすいかな。
慣れないと若干面くらいそうではあるけど。

追記：実は掛け算もちょっと違うの書き忘れてましたな。
あとから散々出てくるんだけど、「``*``」が通常の乗算、「``m**n``」がmのn乗を計算してくれる。
Javaだとmのn乗ってMathパッケージ使わないとやってくんないので手軽に書けていい感じ。

and, or, notはそのまま書くのね。||とかではないのか。
その辺癖で書いちゃいそうだけどもｗ

変数はJavaで言うところの参照型しか存在してないという解釈でいいのかな。
確かにJavaを新人に教えるときに「プリミティブ型と参照型があってー」とか説明がクッソしんどかったのでこれはわかりやすい。

お、複数変数に同時代入ができるのか。これは便利。

```py
x, y = 2, 3
x, y = y, x
```

これだけで変数値の入れ替えのコードが書けるのはありがたい。
Javaだと1個バッファ変数使わないと書けないところだもんな。

#ちょっとびっくりしたこと
あー、AnacondaってフロントにVisual Studio Code使ってるのかｗ
![2018-07-25.png](https://qiita-image-store.s3.amazonaws.com/0/275064/e7367f1f-c510-4a5e-1e2c-9d7931928afd.png)
既に入ってる場合どうすんだろこれ。まあいいや、インストールは必要ないからスキップスキップ。
この時点ではまさかあんなことになるとは予測もしていなかったのである...（とか言っとけば後でトラブったときにカッコつくじゃろ）

#分岐に関する文法の確認
if文はこんな感じでブロックを:の後ろに書けばOK、と。

```py
if a == 0:
  a += 1
else:
  a -= 1
```

Javaだと{}の対応がちゃんと取れてないと混乱するってのあるから確かにこっちの方がいいかもしれんけど、
Pythonの場合は文法的にインデントが意味を持つのか。なるほど。
言語のシステムで強制的にインデントをつけさせる方向性なのね。

and, orも使えますと。

```py
if a == 0　and b == 0:
  a += 1
  b += 1
else:
  a -= 1
  b -= 1
```

でもってelse ifじゃなくてelifなのね。
別の言語でもこんな書き方見た気がするけど何だったかな...
追記:親切な人のコメ参照。

```py
if a > b and a > c :
  print('Max value is '+a)
elif b > c :
  print('Max value is '+b)
else:
  print('Max value is '+c)
```
追記2:これもコメ参照。a,b,cに数値が入ってるとエラーになります。
その辺JavaやJavascriptに慣れてると勘違いしやすいところよね。

switchはないのね。
まあなくてもif～elif～elseで書けるしあったらあったでフォールスルー問題あるからなくてもいいっちゃいいわな。

#文字列の扱い
+で連結できるのはJavaと同じ。
n*s（n=整数、s=文字列）で文字列の複数回繰り返しは面白いけど日本の算数、特に例のかけ算の順序がほにゃららに慣れた人にはつらい文法かもしれんね。

なるほど、文字列は配列扱いになるのか。

- len関数で文字列長がとれる
- 文字列のn文字目にアクセスしたい場合は'abc'[n]のように添字でアクセス
- 文字列の末尾からn文字目にアクセスしたい場合は'abc'[-n]のように負数の添字でアクセス
- 部分文字列がとりたい場合はスライス表記'abc'[n:m]を用いる。nのデフォルトは0、mのデフォルトはlen('abc')

添字に負数が使えるのは面白いなー。
部分文字列を取得するのにスライス表記が使えるのも楽でいい。
mの指定がちょっと要注意だけどJavaのsubstringでも同じ仕様だから無問題よね。

#入力
input関数があるのでこれを使う。
Integer.parseIntなどの代わりに型の名称を用いて以下のように型変換をすることができる。

```py
>>> n = input('Enter number : ')
Enter number : 3
>>> print(int(n)*4)
12
```

#繰り返し構文
へー、while文しかないのか。
forが予約語の中に入ってたからてっきりあるのかと思ってたけど。
whileだとループカウンタの初期値やら増分やらを別途管理しないといかんのでforほど安全じゃないような印象あるな。
似た様な文法がいくつもあるってのは混乱のもとだしこれはこれで割り切りとしてはアリなのかもしれんけどなー。

同様にbreak文はあるけどcontinueは説明ないのな。
実際にはあるのかもしれんけど。
これは繰り返しの中の分岐のブロックは注意して構成しないといかんね。

というところまでがテキスト2章の内容。

ところがこれが3章に入るとJavaの拡張for文とほぼ同じforループが登場する。
ははーん、これはあれだな、必要に応じて小出しにしていくスタイルだな？

とりあえず3章の「指練習」からまじめにコードを書いていこう。
ただ問題文にアレなところがあるので若干修正して書く。
なお、Anacondaをインストールした時点でVisual Studio CodeにはAnaconda Extentionが導入済み。

> 1つの正の整数をユーザに入力させた上、2つの整数root、pwrを表示するプログラムを作成せよ。
> ただし1<pwr<6、root**pwrは入力した整数値と等しい。
> もしこのペアがない場合はその旨をメッセージに表示せよ。

作ったコードが以下。

```3-1.py
while True:
    originText = input('正の整数を入力してください ： ')
    if int(originText) <= 0 :
        print('正の整数だって言ってんだろ')
    else:
        break
# Javaの感覚だとoriginTextはwhile内のローカル変数に見えるけどPythonではそうではない
origin = int(originText)

# 演算に使用する変数
pwr = 2
root = origin
isFound = False

print('元の数', origin)
while pwr < 6 :
    while root > 1 :
        if origin == root**pwr :
            print('root', root, 'pwr', pwr)
            isFound = True
        root -= 1
    pwr += 1
    root = origin

if not isFound :
    print('該当する組み合わせは見つかりませんでした')
```

初回実行したときに最初のループのroot = originの記述をすっかり忘れてて3乗以降が計算できてなかったの笑う。
実行させるとこんな感じ。

```
正の整数を入力してください ： 8
元の数 8
root 2 pwr 3

正の整数を入力してください ： 16
元の数 16
root 4 pwr 2
root 2 pwr 4

正の整数を入力してください ： -100
正の整数だって言ってんだろ
正の整数を入力してください ： 20
元の数 20
該当する組み合わせは見つかりませんでした
```

もっとエレガントにいけるって人は教えてください。
そんなことより変数のスコープどうなってんのこれ。
モジュール内では全部グローバルとかそんな感じなのかしら。

とりあえず腹減ったんでこの記事はここまで。