Pythonこれだけ押さえとけ!!

## はじめに
インターンでPythonを使うことになったので、5月1日からPython学習を始めました
2週間弱たったので書き溜めたものを備忘録的に残したいと思います。

## Python1

## 変数
```python
sample = 1
```

## 定数
```python
OOMOJI = "pyに定数はないが慣習で大文字"
```

## リスト(配列)
```python
# listを変数名にするとlist()が使えなくなる
li = [1, 2, 3, 4, 5]

# 要素を追加
li.append(6)

# 指定したindex番号に挿入
li.insert(0, 'hoge')

## 指定した値と同じ要素を削除
li.remove('python')
```

## 辞書型(オブジェクト)
```rb
obj = {
"hoge": "ホゲ",
"sample": "サンプル"
}

# 追加 2通り
obj["add"] = "追加"  # 処理が高速
obj.update({"add": "追加"})

# 辞書のkeyを全て取得する
obj.keys()
```



## 条件分岐
```python
if name == "tee":
  print("teeです")
elif name == "baru":
  print("baruです")
else:
  print("どちらでもありません")
```
## 繰り返し処理
```python
# range(1, 5) スタート地点を変更可能
for index in range(3): # 回数を指定
    print(index) # 回数
    print("tee") # 処理
else: # loop終了後に走る 無くても可
  print('done')
```
```python
# イテレーターみたいに使える
fruits_list = ["applie", "banana", "orange"]

for item in fruits_list:
  print(item)
  
# iにindex番号が入る
for i, fruit in enumerate(fruits_list)
  print(i, fruit)
```

```python
li = [1,2,3,4,5]
# 0から10まで2つ置きに
for i in range(0, 10, 2):
```

```python
# 一度に複数ループできる
d1 = {1,2,3}
d2 = {4,5,6}
for d in [d1, d2]
```

## 論理演算子
```python
int = 1
num == 1 and print("起動しました") # 起動しました

num == 2 or print("起動しました") # 起動しました
```

## テンプレートリテラル
(フォーマット済み文字列リテラル)
```python
# 先頭にfをつける # 変数を{}で囲む
name = '田中'
age = 22
print(f'我輩の名は{name}。{age}歳だ')
```

## 三項演算子
```python
turuの時の値 if 条件 else false時の値

age = 20
result = "成人" if age >= 20 else 'こども'
```


## 関数
rubyと違って参照するべき変数が関数内になかった場合
例外を発生させずelseに飛ばす
```python
# name = "tee" ここは参照できない

def name():
  name = "tee"
  
  if name == "tee":
    print("teeです")
  elif name == "baru":
    print("baruです")
  else:
    print("どちらでもありません")

name()
```

## リスト・辞書書のコピー
```python
l = [1,2,3]
x = l
x.append(4)
print(x) # 1,2,3,4 # 参照渡しに気をつける

# 辞書も同様
```

## 例外処理
例外が発生しても処理を止めないようにできる
Exceptionで全てのエラーを取得するのはよくない
```python
l = [1,2,3]

try: # 例外が発生する可能性のある処理
  l[5]
except IndexError as ex: # 例外を指定
  print(ex) # 例外の内容を表示
except Exception as ex: # 全て取得
  print(ex)
else: # 例外が発生したかった時のみ
  print('done')
finally: # 必ず実行する処理
  print('clean up')
```

## 例外を自作する
```python
# 例外を意図的に発生させる
# 引数に表示したい文言を入れる
raise IndexError('test error')
```
例外を自作することで、python自体のエラーなのか自分たちのが決めたルール上でのエラーなのか判断できる
```python
# Exceptionを継承する
class UppercaseError(Exception):
  pass

def check():
  words = ['APPLE', 'orange']
  for word in words:
    if word.isupper():
      raise UppercaseError(word)

# 例外処理
try:
  check()
except UppercaseError as ex:
  print('This is my fault. Go next')

```

## module
自分でファイルを分ける時の読み込ませ方
標準module+外部moduleは別途記載

**階層構造**
`package > __init__.py + utils.py`
`__init__.py`はまとめて読み込む時に使う
```python
# dir毎に__init__.pyが必要
# 3.3以降は無くても動くが、処理が遅くなる
# など問題があるため省略しない

# 実行時にfull_path
import package.utils
r = package.utils.say_twice('hello')

# 実行時に少し楽(推奨)
from package import utils
r = utils.say_twice('hello')

# 関数を直接import (非推奨)
# どこから来たのかわからない
# conflictにも繋がる
from package.utils import say_twice
r = say_twice('hello')

print(r)
```

```python
# from dir import module
# asが使えるがあまり好ましくない
from package import utils as u

# 相対pathでmoduleを読む混むことも可能
# あまり良い読み込み方ではない
from ..tools import utils
```
**`__init__で読み込む`**
**階層構造**
`package > __init__.py + animal.py + human.py`
```python:__init__
# 配列で読み込むmoduleを一度に指定可能
__all__ = ['animal, human']
```
```python:読み込み側
# * はinitファイルを使って読み込む指定
from package import *
```
**例外処理を用いた読み込み方**
```python
# 古いversionでも新しいversionでも
# どちらか読み込めたら良いという場合に使用
try:
  from package import utils
except ImportError:
  from package.tools import utils
  
utils.hello()
```

---
---
---

## python2

## 未分類
```python
round(pie, 2) # 小数点以下を丸める

print(help(math)) # helpを表示する

print(7 // 3) # 余りを切り捨てる
print(7 ** 2) # 2乗値

# dirで使用可能なメソッドを確認できる
dir(list)
```

## break
処理を終了する
```python
for i in range(10):
  i += 1
  if i == 5:
    break
```

## continue
ある条件に当てはまった時処理をスキップする
```python
for i in range(5):
  if i == 3:
    continue
  print(i)
```

## for 文
```python
## rang (レンジ)
for _ in range(2, 10, 3):
  print(i) # 2から10 3個飛ばす
  
## enumerate
# リストを回す際、indexも回せる
for i, fruit in enumerate['appe', 'banana', 'orange']):
  print(i, fruit)
  
## zip 複数のリストを一緒に回す
days = ['Mon', 'Tue', 'Wed']
fruits = ['apple', 'banana', 'orange']
drinks = ['coffee', 'tea', 'beer'] 
for day, fruit, drink in zip(days, fruits, drinks):
  print(day, fruit, drink)
  
## 辞書を回す
d  = {'x': 100, 'y': 200}
for k, v in d.items() # アンパッキングしてる
  print(k, ':', v)
```

## while文
```python
count = 0
while count < 5:
  print(count)
  count += 1
else:
  print('done')# breakしなければ最後に実行
```


## ジェネレーター
```python
# ループの間に処理を挟むことができる
  def greeting():
    yield 'Good morning'
    yield 'Good afternoon'
    yield 'Good night'

g = greeting()
print(next(g))
print('@@@@@@@@@@')
print(next(g))
print('@@@@@@@@@@')
print(next(g))
```



## 型
```python
## 型変換
x = '1'
int(x) # 1
float(x) # 1.0
str(x) # 文字列に変換
tuple([1,2,3]) # tuple型に変換

## 型を調べる
if type(o) == int # oがint型の時
if isinstance(o, int) # oがint型の時
```

## 負号を逆転させる
```python
# -を+にする
x = -5
x = -x

# 普通に計算でやる方法
a = -5
a = a * -1 # -1をかければよき
```

## input
```python
woed = input('入力値') # strに来る

# 期待した値と違ったらloop
while True
  word = input('Enter;'):
  if word == 'ok':
    break
  print('okと入力してください')
```

## リスト内包表記
短いコードでリストを作成する
既存のリストを処理したものを作る
```python
## (基本) forの繰り返し処理だけ
x = [i for i in range(6)]

## 偶数のみの条件付き (後置if文)
x = [i for i in range(6) if i % 2 == 0]

## 偶数時「偶数」奇数はそのまま (三項演算子)
x = ['偶数' if i % 2 == 0 else i for i in range(11)]

## 東京には「都」 それ以外は「県」をつける
kant = ['千葉', '栃木', '東京', '埼玉', '茨城', '群馬', '神奈川']
x = [i + '都' if i== '東京' else i + '県' for i in kant]

## 一度に2つ同時に回す zip()
x = [1,2,3]
y = [4,5,6]

d = [i + m for i, m in zip(x, y)]
```

## 辞書内包表記
```python
## 辞書内包表記 key:value と zip()がポイント
keys = ['A', 'B', 'C']
values = [111, 222 ,333]
d = {key:value for key, value in zip(keys, values)}

## 辞書のkeyとvalueを回す .items()
d = {'A': 111, 'B': 222, 'C': 333}
r = {k:v for k, v in d.items() if v > 150}
```

## ジェネレーター内包表記
```python
# 下記の書き方はtupleではなくジェネになる
# g = tuple(i for.. だとtuple)
g = (i for i in range(10))
print(next(g))
```

## with構文
開く・読み書き・閉じる を全て自動で行える
```python
# 第1引数： ファイルのpath
# 第2引数： モード
with open('./sample.txt', 'r') as file:
    print(file.read())
    
    # file.name
    # file.mode
    # file.read() 中身取得
```

## 関数
```python
# キーワード引数が柔軟に使える
def menu(entree='beef', drink, sessert):
  print('beef', dessert='ice', drink='beer')
```

デフォルトの引数にリストを渡すと、次回以降参照先が保持されてしまうのでよくない
```python
# 下記のようにプログラム内で初期化すると良い
def test_func(x, l=None):
  if l is None:
    l = []
    return l
```

```python
# tupleを一気に渡せる
def test_func(word, *args):
  print('word =', word)
  for arg in args:
    print(arg)
  
test_func('Hi', 'Mike', 'Nance')
```
```python
def menu(**kwards): # key word args
  for k, v in kwards.items():
    print(k, v)
    
d = {
  'entree': 'beef',
  'drink': 'ice coffee',
  'dessert': 'ice'
}

menu(**d) # kwy word引数のように展開する
```


## 標準ライブラリ(module)
処理や変数などをまとめたpythonのファイル読み込める
1つ1つはただのファイル
もともと用意されているのもある
```python

# 外部moduleを使う場合
googleでpypiを検索
欲しいモジュールを検索して下記で取得
$ pip install module名

## random
import random
options = [1,2,3]
r = random.choice(options)

## json
import json
# 文字列の中に辞書が格納されている場合下記の方法で辞書に変換可能
s = '{"A": 111, "B": 222, "C": 333}'
d = json.loads(s)
print(d)

import math # 数学関数をimportする
math.sqrt(25) # 平方根

# defaultdict
from collections import defaultdict
```

**読み込み方**
```python
# 各ライブラリ a-z順に並べる 1行あける
# 1つずつ読み込む

# 標準ライブラリ
import aaa
import bbb

# 外部ライブラリ
import ccc

# 独自ライブラリ(ローカル)
import ddd
```

**`__name__`**
```python
# modueに処理を記述していた場合
# 読み込まれた際実行されてしまう。
# テスト用に処理を記載する際は下記
if __name__ == '__main__':
  print('メインで実行した時のみ走る')
  print('読み込まれた時は走らない')
```


## Docstring
Documentは関数内に書く
```python
def sample(param1, param2):
  """
    docを書く
  """
  
print(example_func.__doc__)
help(sample)
```

---
---
---

# python3

## 文字列操作
```python
## 文字列にもindex番号がある
s[-1] # 後ろの文字を取得

## 大文字小文字の操作
str.upper()
str.lower()
str.capitalize() # 先頭を大文字 他小文字
str.title() # 単語先頭を大文字 他小文字
str.swapcase() # 大文字と小文字を逆転

## 判断
str.isupper() # 大文字か
str.islower() # 小文字か
str.istitle() # タイトルケースか
s.startswith('My') # Myで始まっているか
s.find('Mike') # 何番目にあるか
s.count('Mike') # 何個あるのか
if 'ばる' in s: # 文字列に含まれるか
s.isdigit() ## str型の数字のみか

## 特定の文字列を変更
str.replace('a', 'b')

## 空白区切りでリストにする
s = 'python is hard'
s.split()


```

## リスト(配列)
```python
## 配列を操作
n = [1,2,3]
n.append(4) # 最後に追加
n.insert(0, 100) # 指定の場所に追加
n.pop() # 最後を取得 + 取り除く
del n[0] # 削除 del n で全消し
n.remove(2) # 削除

## 取得・変換
li(x) # リストに変換
li = s.split(' ') # スペース区切りの配列に
print(r.index(3)) # 3のあるindex番号
li.find('-') ## 特定の値のindex番号を取得
", ".join(li)　# 任意の文字列で結合して文字列を生成

## 配列を結合
x = [1,2,3]
y = [4,5,6]
x += y # xにyを結合
x.extend(y) # xにyを結合

## 並び替え
x = [1,2,3]
x.sort() # 並び替え
x.sort(reverse=True) # 逆に並び替え
x.reverse() # 逆に並び替え
y = sorted(li, key=len)# 文字数で並び替え

## 判断
li = [1,2,3,'4'] # any() １つ以上がtrue
if any(instance(i, str) for i in li)

## 和・最大値・最小値
li = [1,2,3]
sum(li)
max(li)
min(li)

## コピーの挙動(参照渡し)
i = [1,2,3,4,5]
j = i # 参照先がコピーされる (メモリのアドレス)
x = [1,2,3,4,5]
y = x.copy() # 値自体をコピー
y = x[:] # 値自体をコピー
```


## 辞書型
```python
## 作成
d = {"a": 1, "b": 2}
d = dict(a=1, b=2) # こちらでも作れる

## 配列を操作(取得)
d.kyes() # keyを配列で取得
d.values() # valueを配列で取得
d['z'] # 取得できずエラー
d.get('z') # 取得できずNoneを返す
d.pop('x') # 破壊的な取り出し
del d['y'] # 削除
d.clear() # 中身を空に]
d.setdefault(i, 0) # iがなければiに0をセット
d.items() # 変数を２つ取る あんパッキングする

## 判断
'a' in d # keyにaがあるか .key()を省略可能
444 in d.values() # valueに444があるか

## dをd2でオーバーライド
d = {'x': 10, 'y': 20}
d2 = {'x': 1000, 'j': 500}
d.update(d2)

## 辞書の連結
x = {'A': 111, 'B': 222}
y = {'C': 333, 'D': 444}
r = {**x, **y} ## 連結できる
r = x | y # python 3.9以降

## lに対応するdのkeyを出力 該当なしはNone
d = {'A': 111, 'B': 222, 'C': 333}
l = ['B', 'C', 'D', 'A']
for key in l:
    print(d.get(key)) # .get()
    
### 該当なしでエラーを出す
d.get(key)ではなく d[key]を使う
#####

## 並び替え
d = {'B': 222, 'A': 111, 'D': 444, 'C': 333}

sorted(d.items()) # (key)でソートする
sorted(d.items(), key = lambda x: x[1])  # (value)でソートする

# 一度に複数同時に回す
for day, fruit, drink in zip(days, fruits, drinks):
  print(day, fruit, drink)

## 最大値・最小値
max(d.values()) # valueの最大値を取得
min(d.values()) # valueの最小値を取得
min(d.keys(), key=lambda k: d[k])# valueの最小値を持つkey

```


## タプル
object_idを変更せずに値の変更ができない
メモリの消費量を抑えた配列を作成できる
```python
## tupleを生成
t = (1, 2)
t = 1, 2
t = 1, # これだけでタプルになる

## アンパック
t = (1, 2) # tupple
t = 1, 2 # tupple
a, b = t # アンパッキング

## アンパッキングで逆転させる
x = 1
y = 2
x, y = y, x # 中身を逆転

## 反転させる
tuple(reversed(t))

# 新しいタプルを生成している
# object_idが変わっている
t = ('ruby', 'python')
t += ('js')
```

## 集合
```python
# 基本
x  = {1,1,2,3} # 自動で重複がなくなる

# 空の集合  
s2 = set() # {}では辞書(obj)になってしまう

## 集合の操作
s = {1,2,3}
s.add(4) # 追加
s.remove(4) #削除
s.clear() #空になる

## 四則演算で集合を取得
x = {1,2,3}
y = {3}
x - y # {1,2} xのみに格納されている値
x & y # {3} 両方にある
x | y # {1,2,3} どちらかにある
x ^ y # {1,2} 一方にある

## l1はl2に含まれている (返り値はbool)
r = set(l1).issubset(set(l2))
## 配列から重複をなくす (集合を作る)
set(li)
```

## bool
```python
## falseの数を数える  暗黙の型変換を利用
c = len(l) - sum(l)

## ドモルガンの法則 (反転させることができる)
a != 3 and a != b
not (a != 3 or a != b)
```

## none
```python
# Noneか判定
if is_empty is not None: # 1 is Trueはx
```

## スライス
```python
word = python

print(word[-1])
print(word[0:2]) # 0から2
print(word[2:5]) # 2から5
print(word[:2]) # 0から2
print(word[2:]) # 2から最後まで
print(word[:]) # 全て
print(x[::2]) # 1つ飛ばしでスライス

word = 'j' + word[1:] # json
```

## 終わりに
完全に自分の備忘録用・・・
割と学習できているような気がします。
youtubeで環境構築+基礎学習+スクレイピングを体験
Udemyでpython100本ノックでpythonに慣れて
Udemyのpython講座38時間でじっくりコトコト知識を蓄えています。
暗記するつもりはないですが、Notion等にまとめながら学習すると理解度も深まりますし、
わからなくなったらサラッと見れば良いのでいいですね!!

Python楽しい!!