kaggleで勝つためにpython文法の弱いところを補強してみた

# 使用書籍　[独学プログラマー](https://www.amazon.co.jp/%E7%8B%AC%E5%AD%A6%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC-Python%E8%A8%80%E8%AA%9E%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8B%E3%82%89%E4%BB%95%E4%BA%8B%E3%81%AE%E3%82%84%E3%82%8A%E6%96%B9%E3%81%BE%E3%81%A7-%E3%82%B3%E3%83%BC%E3%83%AA%E3%83%BC%E3%83%BB%E3%82%A2%E3%83%AB%E3%82%BD%E3%83%95/dp/4822292274/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E7%8B%AC%E5%AD%A6%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC&qid=1628131932&sr=8-1)

# オブジェクトとは
- pythonにおける「オブジェクト」とは、同一性、データ型、値の３つの要素がある
- 同一性：コンピュータのメモリのどこに格納されているかで決まり、変化しない
- データ型：データがどんな性質を持っているかグループ分けしたもの。データ型が持つ性質は変化しない
- 値：それが表すデータのこと
 - "hello world"は、hello worldというstrデータ型の値を持つオブジェクト。

# 関数


```python
def f(x):
    return x + 1
z = f(5)
if z == 5:
    print('z is 5')
else:
    print('z is not 5')
```


```python
def f():
    return 1 + 1
result = f()
if result == 5:
    print('result is 5')
else:
    print('result is not 5')
```

    result is not 5



```python
def f(x, y, z):
    return x + y + z + 1
z = f(5, 4, 3)
if z == 5:
    print('z is 5')
else:
    print('z is not 5')
    print('z is ', z)
```

    z is not 5
    z is  13


# 組み込み関数 
- 最初から用意されている関数
- あらゆる種類の計算とタスクを実行できて、特別な準備なしでもすぐに使用できる


```python
print('hello')
```

    hello



```python
len('hello')
```




    5




```python
print('sum is ', str(100))
```

    sum is  100



```python
a = 100
b = int('200')
c = a + b
d = a + b + float(c)
print(c)
print(d)
```

    300
    600.0



```python
age = input('enter your age')
int_age = int(age)
if int_age <= 22:
    print('you are student')
else:
    print('you are business man')
```

    enter your age23
    you are business man


# 関数を再利用する


```python
def even_odd():
    a  = input('type a number')
    x = int(a)
    if x % 2 == 0:
        print('even!')
    else:
        print('odd!')

even_odd()

```

    type a number43
    odd!


# 必須引数とオプション引数


```python
def f(x=2):
    return x * x
print(f())       #デフォルトの値が使用された
print(f(x = 5))  #デフォルトの値が上書きされて渡した数値が使用された
```

    4
    25



```python
def add_it(x, y =  12):
    return x + y
add_it(x = 10)
# xには値を渡して、yにはデフォルト値を設定
```




    22



# スコープ


```python
a = 1
b = 2
c = 3
# グローバル変数
def f():
    print(a)
    print(b)
    print(c)
f()
```

    1
    2
    3


## globalキーワード


```python
x = 100 # global

def f():
    x = 100 # local
    x += 1
    print(x)
f()
print(x)
```

    101
    100



```python
x = 100

def f():
    global x # edit x in local env
    x += 1
    print(x)
f()
print(x)
```

    101
    101


# 例外処理


```python
a = input('type a number: ')
b = input('type a number: ')
a = int(a)
b = int(b)
print(a / b)
```

    type a number: 3
    type a number: 0



    ---------------------------------------------------------------------------

    ZeroDivisionError                         Traceback (most recent call last)

    <ipython-input-66-5e467544e423> in <module>
          3 a = int(a)
          4 b = int(b)
    ----> 5 print(a / b)
    

    ZeroDivisionError: division by zero



```python
#上記の問題をコードで解決する
a = input('type a number: ')
b = input('type a number: ')
a = int(a)
b = int(b)
try:
    print(a/b)
except ZeroDivisionError:
    print("b can not be zero.")
    # https://docs.python.org/ja/3/library/exceptions.html #ZeroDivisionError 組み込み例外処理
```

    type a number: 10
    type a number: 0
    b can not be zero.



```python
# 異なる型を受け取ってしまう場合のコード処理対策
a = input('type a number: ')
b = input('type a number: ')
a = int(a)
b = int(b)
try:
    print(a/b)
except ZeroDivisionError:
    print("b can not be zero.")
    # https://docs.python.org/ja/3/library/exceptions.html #ZeroDivisionError 組み込み例外処理
```

    type a number: 10
    type a number: akihiro



    ---------------------------------------------------------------------------

    ValueError                                Traceback (most recent call last)

    <ipython-input-3-a9d3cc335648> in <module>
          3 b = input('type a number: ')
          4 a = int(a)
    ----> 5 b = int(b)
          6 try:
          7     print(a/b)


    ValueError: invalid literal for int() with base 10: 'akihiro'



```python
# ZeroDivisionError, ValueErrorの両方のエラーが生じたときを想定してコードで解決
try:
    a = input('type a number: ')
    b = input('type a number: ')
    a = int(a)
    b = int(b)
    print(a/b)
except (ZeroDivisionError, ValueError):
    print("invalid input!")
```

    type a number: 10
    type a number: akihiro
    invalid input!



```python
try:
    a = input('type a number: ')
    b = input('type a number: ')
    a = int(a)
    b = int(b)
    print(a/b)
except (ZeroDivisionError, ValueError):
    print("invalid input!")
```

    type a number: 10
    type a number: 0
    invalid input!



```python
try:
    10/0
    c = 'i will never get defined'
except ZeroDivisionError:
    print(c)
```


    ---------------------------------------------------------------------------

    ZeroDivisionError                         Traceback (most recent call last)

    <ipython-input-15-3b707af06240> in <module>
          1 try:
    ----> 2     10/0
          3     c = 'i will never get defined'


    ZeroDivisionError: division by zero

    
    During handling of the above exception, another exception occurred:


    NameError                                 Traceback (most recent call last)

    <ipython-input-15-3b707af06240> in <module>
          3     c = 'i will never get defined'
          4 except ZeroDivisionError:
    ----> 5     print(c)
    

    NameError: name 'c' is not defined


# コンテナ
- リスト
- タプル
- 辞書

## メソッド
- 特定のデータ型に密接に関連付けられている関数
- 通常の関数と同じような性質を持ち、引数を渡すことができ、また、コードを実行して値を返す
- 違う点は、オブジェクトにつけて呼び出すという点


```python
"hello".upper()
```




    'HELLO'




```python
"HELLO".lower()
```




    'hello'



# リスト
- 好きな順番でオブジェクトを保存しておけるコンテナ
- どんな種類のオブジェクトでも追加できる


```python
fruit = ["apple", "orange", "grape"]
fruit.append('banana') #appned(追加)メソッド
fruit[3]
# for s in fruit:
#     print(s)
fruit
# （回りくどい説明をすれば）appendメソッドを使って渡したオブジェクトがリストの末尾に追加された
```




    ['apple', 'orange', 'grape', 'banana']




```python
rnd = []
rnd.append('banana')
rnd.append(100)
rnd.append(True)
rnd
```




    ['banana', 100, True]




```python
#上書き、削除(末尾)
colors = ['red', 'blue', 'yelllow', 'pink']
colors[1] = 'light-blue'
colors
colors.pop()
colors
```




    ['red', 'light-blue', 'yelllow']




```python
colors[1:3]
```




    ['light-blue', 'yelllow']




```python
colors[ : ]
```




    ['red', 'light-blue', 'yelllow']




```python
# 要素が含まれているかを調べる
'green' in colors
```




    False




```python
'green' not in colors
```




    True




```python
# リストのサイズ
print(colors)
len(colors)
```

    ['red', 'light-blue', 'yelllow']





    3




```python
# 小さなプログラムを作ってみる
items = ['red', 'blue', 'yelllow', 'pink']
guess = input('色を指定してください:')
if guess in items:
    print('あたり！')
else:
    print('はずれ')
```

    色を指定してください:red
    あたり！


# タプル　
- 好きな順番でオブジェクトを保存しておけるコンテナ
- リストと異なり、タプルはイミュータブル（変更不可能）な性質をもつため、一度タプルを作ると、要素の削除、追加ができない
 - 変わってほしくない値を格納しておくことに強み
 - 地図上の座標など
 - 逆にリストに入れるとプログラムの中で編集される危険性がある
- タプルは()を使用する


```python
#作り方は２つ
my_tuple = tuple()
my_tuple
```




    ()




```python
my_tuple2 = ()
my_tuple2
#空の状態のtupleにオブジェクトを追加するときは後者の構文を使用する
```




    ()




```python
rndm = ("akihiro", 1995, True)
rndm
```




    ('akihiro', 1995, True)




```python
#タプルの要素が一つのときは、末端に,をつけること

('self_taught', )#これはタプル
```




    ('self_taught',)




```python
(10)#これは数値計算に使うカッコ
```




    10




```python
#タプルに値を追加してみる
my_introduce = ('akihiro', 1995, 'self_taught of python', 'osaka')
my_introduce[1] = 1996
```


    ----------------------------------------------------------------------

    TypeError                            Traceback (most recent call last)

    <ipython-input-46-f4c942b21623> in <module>
          1 #タプルに値を追加してみる
          2 my_introduce = ('akihiro', 1995, 'self_taught of python', 'osaka')
    ----> 3 my_introduce[1] = 1996
    

    TypeError: 'tuple' object does not support item assignment



```python
#あとはリストと同じ操作ができる
my_introduce[1]
```




    1995




```python
1995 in my_introduce
```




    True




```python
1995 not in my_introduce
```




    False



# 辞書
- ２つのオブジェクトを関連付けて保持できるコンテナ
- 片方のオブジェクトを**格納時や取得時のキー**に使い、もう片方のオブジェクトを**バリューとしてキーにマッピングして（関連付けて）保持**する
- キーバリューペアと呼ぶ
- 辞書からは、**キーを使ってバリューを取り出すことができる**。その逆はできない。
- 辞書はミュータブル（変更可能）
- リストやタプルと違い、辞書に格納するオブジェクトの順番は指定できない
- 辞書は、{}を使用して作る


```python
#作り方は二通り

my_dict = dict()
my_dict
```




    {}




```python
my_dict2 = {}
my_dict2
```




    {}




```python
fruits = {'apple':'red', 'banana':'yellow'} #要素が一つでも末尾に,は不要
fruits
```




    {'apple': 'red', 'banana': 'yellow'}




```python
fruits['apple']
```




    'red'




```python
fruits['banana']
```




    'yellow'




```python
fruits['red'] #これはできない
```


    ----------------------------------------------------------------------

    KeyError                             Traceback (most recent call last)

    <ipython-input-62-c5c2297ac982> in <module>
    ----> 1 fruits['red'] #これはできない
    

    KeyError: 'red'



```python
my_family = {'Akihiro':1995, 'my_cat':2012} # バリューはどんなオブジェクトも格納可能、ここでは整数オブジェクトを格納している
```

- 辞書のバリューには、どんなオブジェクトも格納可能
- 辞書のキーは、イミュータブルなため、**文字列かタプルなら辞書のキーに使用できる**が、**リストや辞書は辞書のキーに使用できない**


```python
'Akihiro' in my_family #キーを使って検索は可能
```




    True




```python
#削除するとき
del my_family['Akihiro']
my_family
```




    {'my_cat': 2012}



### 辞書を使って小さなプログラムを書いてみる
#### テーマ：カラオケの音楽プログラム



```python
Fukuyama_songs = {
    '1': 'sakurazaka',
    '2': 'hello',
    '3': 'gunjou',
    '4': 'niji'
}
num = input('please type a number')
if num in Fukuyama_songs:
    print(Fukuyama_songs[num])
else:
    print('can not find the music')
```

    please type a number2
    hello


# コンテナ中のコンテナ


```python
#リストの中のリストを作ってみる（リストにタプルを持たせたりもできる）

lists = []

rap = ['Tom', 'Mary', 'Jane']
rock = ['Ken', 'Max', 'Kate']
djs = ['Ted', 'Jane', 'Rick']

lists.append(rap)
lists.append(rock)
lists.append(djs)

print(lists)

#要素へのアクセス方法と追加方法
rap = lists[0]
rap.append('Hiroshi')
print(rap)

lists
```

    [['Tom', 'Mary', 'Jane'], ['Ken', 'Max', 'Kate'], ['Ted', 'Jane', 'Rick']]
    ['Tom', 'Mary', 'Jane', 'Hiroshi']





    [['Tom', 'Mary', 'Jane', 'Hiroshi'],
     ['Ken', 'Max', 'Kate'],
     ['Ted', 'Jane', 'Rick']]



# for文


```python
name = 'Ted'
for c in name:
    print(c)
# name: 文字列　→　イテラブル（繰り返し可能）：文字列やリストやタプルのように、繰り返し処理で要素を取り出せるオブジェクト
# for val in iterable:
#     code
```

    T
    e
    d



```python
#文字列
name = 'akihiro'
for c in name:
    print(c)
```

    a
    k
    i
    h
    i
    r
    o



```python
#リスト
name = ['Sebastian', 'Vettel'] # ※好きなF1ドライバー
for s in name:
    print(s)
```

    Sebastian
    Vettel



```python
#タプル
name = ('Sebastian', 'Vettel')
for s in name:
    print(s)
```

    Sebastian
    Vettel



```python
#辞書
name = {'first_name':'Sebastian', 'last_name':'Vettel'}
for s in name:
    print(s)
#     辞書型ではキーが要素として出力された
```

    first_name
    last_name



```python

country = ['japan', 'america', 'korea']
i = 0
for name in country:
    new = country[i]
    new = new.upper() #new上書き
    country[i] = new #coutry要素上書き
    i += 1
    
print(country)

#大文字へ変換させるために、newという一時的な変数を使って、coutrynの各要素を上書きする
```

    ['JAPAN', 'AMERICA', 'KOREA']



```python
#保留　→　質問

country = ['japan', 'america', 'korea']
# initial = ['J', 'A', 'K']
country[0][0] = 'J'
# country[0][0] = initial[0]
country

# i = 0
# for name in country:
#     country[i][0].upper()
#     i += 1
# print(country)


# i = 0
# initial = []
# for name in country:
#     initial.append(country[i][0]) 
#     new = initial[i]
#     new = new.upper() #new上書き
#     initial[i] = new
#     print(initial[i])
#     print(country[i][0])
# #     country[i][0] = initial[i]
#     i += 1
    
# print(country)

#大文字へ変換させるために、newという一時的な変数を使って、countryの各要素を上書きする
```


    ---------------------------------------------------------------------------

    TypeError                                 Traceback (most recent call last)

    <ipython-input-145-5f44837de411> in <module>
          3 country = ['japan', 'america', 'korea']
          4 # initial = ['J', 'A', 'K']
    ----> 5 country[0][0] = 'J'
          6 # country[0][0] = initial[0]
          7 country


    TypeError: 'str' object does not support item assignment



```python
country = ['japan', 'america', 'korea']
i = 0

for name in country:
    
    tmp = country[i]
    tmp = tmp.upper() #new上書き
    country[i] = tmp #coutry要素上書き
    i += 1

    
print(country)

#大文字へ変換させるために、newという一時的な変数を使って、coutrynの各要素を上書きする
```

    ['JAPAN', 'AMERICA', 'KOREA']



```python
country = ['japan', 'america', 'korea']
i = 0

for i, tmp in enumerate(country):
    
    tmp = country[i]
    tmp = tmp.upper() #new上書き
    country[i] = tmp #coutry要素上書き
#     i += 1
    print(i, country)# enumerate()でインデックスを取得できる
    
    
print(country)

#大文字へ変換させるために、newという一時的な変数を使って、coutrynの各要素を上書きする
```

    0 ['JAPAN', 'america', 'korea']
    1 ['JAPAN', 'AMERICA', 'korea']
    2 ['JAPAN', 'AMERICA', 'KOREA']
    ['JAPAN', 'AMERICA', 'KOREA']



```python
pref_east = ['kanagawa', 'saitama', 'tokyo' , 'chiba']
pref_west = ['osaka', 'kyoto', 'hyogo', 'hiroshima']
pref = []


for tmp in pref_east:
    pref.append(tmp.upper())

    
for tmp in pref_west:
    pref.append(tmp.upper())


print(pref)

```

    ['KANAGAWA', 'SAITAMA', 'TOKYO', 'CHIBA', 'OSAKA', 'KYOTO', 'HYOGO', 'HIROSHIMA']


# while文


```python
x = 10
while x > 0:
    if x == 1:
        print('{}'.format(x), end='')
    else:
        print('{},'.format(x), end='')
    
#     print('{}'.format(x))
    x -= 1

```

    10,9,8,7,6,5,4,3,2,1

# モジュール
## 組込みモジュール
- python本体に含まれていて重要な機能を提供するモジュール
- import [モジュール名]


```python
import math
math.pow(math.sqrt(2), 2)
math.pow(2,3)
```




    8.0




```python
import random 

count = 0
for i in range(100):
    
    if random.random() < 0.1:
#         print('あたり！')
        count += 1
    else:
        pass
#         print('はずれ！')
        
print('あたりの回数は,{}回/100回'.format(count))
```

    あたりの回数は,11回/100回


# オブジェクト指向プログラミング
- 用語理解
 - 数値123というオブジェクトは、intクラスのインスタンス
 - 'abc'という文字列オブジェクトは、strクラスのインスタンス
 - pythonではすべてのオブジェクトは何らかのインスタンスである
 - 故に、数値を単純に並べれば、intクラスのインスタンスとなり、' 'で囲えばstrクラスのインスタンスとなる


```python
#クラスを作成してみる

class Orange:
    def __init__(self, w, c):
        #インスタンス変数は__init__メソッドの中で定義する
        #__init__メソッドは特殊メソッドであり、pythonがオブジェクトの作成など特別な目的で使用するメソッド
        #以下のように書くと,weightとcolorというインスタンス変数が作成される
        #クラス内のどのメソッドでもこれらのインスタンス変数を通常の変数のように扱うことができる
        self.weight = w
        self.color = c
        
        print('created!')
        
        
#オブジェクトを作成
#クラス名(引数), 引数部分には__init__メソッドが受け取れる引数を渡す、selfを明示的に渡す必要なし、pythonが自動的に渡してくれる
orl = Orange(10, 'dark')
#作成に成功したら、created!が表示される
print(orl)
#このように新しいオブジェクトを作ることを、クラスのインスタンス化という

#オブジェクト作成後にインスタンス変数の値へのアクセス方法↓
print(orl.weight)
print(orl.color)

#インスタンス変数の値の変更
orl.weight = 100
print(orl.weight)


#オブジェクトを更に作成
orl2 = Orange(50, 'light')
orl3 = Orange(70, 'dark')




#以上のように、オブジェクトを作成するまでに、__init__メソッドを作成して、インスタンス変数を定義し、最後にオブジェクトを作成した

```

    created!
    <__main__.Orange object at 0x7fee9ae1f1c0>
    10
    dark
    100
    created!
    created!



```python
#次に上のコードを一部利用して、メソッドの追加とインスタンス変数の追加をしてみる


class Orange:
    def __init__(self, w, c):
        self.weight = w
        self.color = c
        self.mold = 0 #クラス内で使用する変数を定義する、クラス内のローカル変数
        print('created!')
    
    def rot(self, days, temp):
        self.mold = days * temp
        
orange1 = Orange(200, 'dark')
print(orange1.mold)
orange1.rot(10, 38)
print(orange1.mold)


```

    created!
    0
    380



```python
#もう少し練習

class Rectangle:
    def __init__(self, w, l):
        self.width = w
        self.len = l
        
    def area(self):
        return self.width * self.len
    
    def change_size(self, w, l):
        self.width = w #インスタンス変数の値を上書き
        self.len = l

rectangle = Rectangle(10, 30)
print(rectangle.area()) #クラス内メソッドの使用方法
rectangle.change_size(5, 10)
print(rectangle.area())
```

    300
    50


# データ分析のためのpython文法基礎
- Numpy ： 数値計算、行列演算
- Pandas：データの操作、演算
- Matplotlib : グラフの描画

参考資料：
[【最短で理解する】データ分析のためのPython基礎](https://qiita.com/Yupine/items/7d8f5354dac814ec3c6a#23-pandas%E3%81%A7%E3%83%87%E3%83%BC%E3%82%BF%E6%93%8D%E4%BD%9C)

## numpy


```python
import numpy as np
array1 = np.array([1,2,3,4,5])
array1
```




    array([1, 2, 3, 4, 5])




```python
array1.shape
```




    (5,)




```python
array1[2]
```




    3




```python
array1[1:5]
```




    array([2, 3, 4, 5])




```python
array1[ : ]
```




    array([1, 2, 3, 4, 5])




```python
array2 = np.array([[1,2,3], [4,5,6]])
array2
```




    array([[1, 2, 3],
           [4, 5, 6]])




```python
array2[1, 1]
```




    5




```python
array2[1, 2]
```




    6




```python
array2.shape
```




    (2, 3)




```python
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
```


```python
a
```




    array([[1, 2],
           [3, 4]])




```python
b
```




    array([[5, 6],
           [7, 8]])




```python
np.dot(a,b)#行列の積の計算
```




    array([[19, 22],
           [43, 50]])



## matplotlib


```python
import matplotlib.pyplot as plt # Matplotlibパッケージのpyplotモジュールをインポート
# from matplotlib import pyplot as plt # こんなふうに書いてもいい   
import numpy as np
```


```python
x = np.linspace(0, 10, 100) # 変数xにNumPyの関数linspaceを使用し0から10までの数字を100分割したものを代入
y = x
```


```python
plt.plot(x, y) #xとyをプロット
plt.show() #グラフを表示
```


    
![png](output_106_0.png)
    



```python

```


```python

```


```python
import matplotlib.pyplot as plt   
import numpy as np
import sys
print(sys.path)
import japanize_matplotlib
```

    ['/home/akihiro/anaconda3/envs/python_practice', '/home/akihiro/anaconda3/envs/python_practice/lib/python38.zip', '/home/akihiro/anaconda3/envs/python_practice/lib/python3.8', '/home/akihiro/anaconda3/envs/python_practice/lib/python3.8/lib-dynload', '', '/home/akihiro/.local/lib/python3.8/site-packages', '/home/akihiro/anaconda3/envs/python_practice/lib/python3.8/site-packages', '/home/akihiro/anaconda3/envs/python_practice/lib/python3.8/site-packages/IPython/extensions', '/home/akihiro/.ipython']



```python
x = np.linspace(-5, 5, 10)
y = x**2

plt.plot(x, y, color = 'b')
plt.xlabel("y=x^2のグラフ")
plt.show()
```


    
![png](output_110_0.png)
    



```python
import math

x = np.linspace(-np.pi, np.pi)
plt.plot(x, np.cos(x), color = 'b', ls = '-', label = 'cos')
plt.plot(x, np.sin(x), color = 'r', ls = '-', label = 'sin')
plt.plot(x, np.tan(x), color = 'y', ls = '-', label = 'tan')

plt.xlim(-math.pi, math.pi)
plt.ylim(-1, 1)


plt.legend()
plt.xlabel('x軸')
plt.ylabel('y軸')
plt.title('三角関数のグラフ')

# plt.plot(x, y) #xとyをプロット
3 plt.show() #グラフを表示
```


    
![png](output_111_0.png)
    


## pandas
- pandasのDataFrameでは列ごとに異なるデータ型であっても構わない
- Numpy配列はすべて同じデータ型である必要がある


```python
import pandas as pd
```


```python
df1 = pd.DataFrame({
          '名前':['sato','ito','kato','endo','naito'],
          '学生番号':[1,2,3,4,5],
          '体重':[92,43,58,62,54],
          '身長':[178,172,155,174,168]
          })
df1
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>名前</th>
      <th>学生番号</th>
      <th>体重</th>
      <th>身長</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>sato</td>
      <td>1</td>
      <td>92</td>
      <td>178</td>
    </tr>
    <tr>
      <th>1</th>
      <td>ito</td>
      <td>2</td>
      <td>43</td>
      <td>172</td>
    </tr>
    <tr>
      <th>2</th>
      <td>kato</td>
      <td>3</td>
      <td>58</td>
      <td>155</td>
    </tr>
    <tr>
      <th>3</th>
      <td>endo</td>
      <td>4</td>
      <td>62</td>
      <td>174</td>
    </tr>
    <tr>
      <th>4</th>
      <td>naito</td>
      <td>5</td>
      <td>54</td>
      <td>168</td>
    </tr>
  </tbody>
</table>
</div>




```python
df2 = pd.DataFrame({
          '学生番号':[1,2,3,5,6,9],
          '数学':[50,60,70,80,90,100],
          '英語':[95,85,80,75,70,65],
          '理科':[40,55,60,65,50,75],
          'クラス':['A組','B組','A組','C組','B組','C組']
          })
df2
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>学生番号</th>
      <th>数学</th>
      <th>英語</th>
      <th>理科</th>
      <th>クラス</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>1</td>
      <td>50</td>
      <td>95</td>
      <td>40</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2</td>
      <td>60</td>
      <td>85</td>
      <td>55</td>
      <td>B組</td>
    </tr>
    <tr>
      <th>2</th>
      <td>3</td>
      <td>70</td>
      <td>80</td>
      <td>60</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>3</th>
      <td>5</td>
      <td>80</td>
      <td>75</td>
      <td>65</td>
      <td>C組</td>
    </tr>
    <tr>
      <th>4</th>
      <td>6</td>
      <td>90</td>
      <td>70</td>
      <td>50</td>
      <td>B組</td>
    </tr>
    <tr>
      <th>5</th>
      <td>9</td>
      <td>100</td>
      <td>65</td>
      <td>75</td>
      <td>C組</td>
    </tr>
  </tbody>
</table>
</div>



### データの抽出


```python
df2['数学']
```




    0     50
    1     60
    2     70
    3     80
    4     90
    5    100
    Name: 数学, dtype: int64




```python
df2['クラス']
```




    0    A組
    1    B組
    2    A組
    3    C組
    4    B組
    5    C組
    Name: クラス, dtype: object




```python
df2[['数学', 'クラス']] #複数列を抽出する際は[ ]を二重にして呼び出します。 
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>数学</th>
      <th>クラス</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>50</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>1</th>
      <td>60</td>
      <td>B組</td>
    </tr>
    <tr>
      <th>2</th>
      <td>70</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>3</th>
      <td>80</td>
      <td>C組</td>
    </tr>
    <tr>
      <th>4</th>
      <td>90</td>
      <td>B組</td>
    </tr>
    <tr>
      <th>5</th>
      <td>100</td>
      <td>C組</td>
    </tr>
  </tbody>
</table>
</div>




```python
df2[['学生番号', '数学']] 
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>学生番号</th>
      <th>数学</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>1</td>
      <td>50</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2</td>
      <td>60</td>
    </tr>
    <tr>
      <th>2</th>
      <td>3</td>
      <td>70</td>
    </tr>
    <tr>
      <th>3</th>
      <td>5</td>
      <td>80</td>
    </tr>
    <tr>
      <th>4</th>
      <td>6</td>
      <td>90</td>
    </tr>
    <tr>
      <th>5</th>
      <td>9</td>
      <td>100</td>
    </tr>
  </tbody>
</table>
</div>




```python

```


```python
df2[ '英語'].sort_values()
```




    5    65
    4    70
    3    75
    2    80
    1    85
    0    95
    Name: 英語, dtype: int64




```python
df1['身長'].sort_values() #一部をソート
```




    2    155
    4    168
    1    172
    3    174
    0    178
    Name: 身長, dtype: int64




```python
df1.sort_values(by=['身長'], ascending = False) #一部をソートして全体を表示, False:降順
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>名前</th>
      <th>学生番号</th>
      <th>体重</th>
      <th>身長</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>sato</td>
      <td>1</td>
      <td>92</td>
      <td>178</td>
    </tr>
    <tr>
      <th>3</th>
      <td>endo</td>
      <td>4</td>
      <td>62</td>
      <td>174</td>
    </tr>
    <tr>
      <th>1</th>
      <td>ito</td>
      <td>2</td>
      <td>43</td>
      <td>172</td>
    </tr>
    <tr>
      <th>4</th>
      <td>naito</td>
      <td>5</td>
      <td>54</td>
      <td>168</td>
    </tr>
    <tr>
      <th>2</th>
      <td>kato</td>
      <td>3</td>
      <td>58</td>
      <td>155</td>
    </tr>
  </tbody>
</table>
</div>



### データの結合
- 内部結合
- 外部結合
- 左外部結合
- 右外部結合

#### 内部結合→共通する部分のみを結合


```python
data_inner = pd.merge(df1, df2, on='学生番号', how='inner')# on='学生番号'：共通部分を指定
data_inner
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>名前</th>
      <th>学生番号</th>
      <th>体重</th>
      <th>身長</th>
      <th>数学</th>
      <th>英語</th>
      <th>理科</th>
      <th>クラス</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>sato</td>
      <td>1</td>
      <td>92</td>
      <td>178</td>
      <td>50</td>
      <td>95</td>
      <td>40</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>1</th>
      <td>ito</td>
      <td>2</td>
      <td>43</td>
      <td>172</td>
      <td>60</td>
      <td>85</td>
      <td>55</td>
      <td>B組</td>
    </tr>
    <tr>
      <th>2</th>
      <td>kato</td>
      <td>3</td>
      <td>58</td>
      <td>155</td>
      <td>70</td>
      <td>80</td>
      <td>60</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>3</th>
      <td>naito</td>
      <td>5</td>
      <td>54</td>
      <td>168</td>
      <td>80</td>
      <td>75</td>
      <td>65</td>
      <td>C組</td>
    </tr>
  </tbody>
</table>
</div>



#### 外部結合→全部を無理やり結合


```python
data_outer = pd.merge(df1, df2, how = 'outer')
data_outer
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>名前</th>
      <th>学生番号</th>
      <th>体重</th>
      <th>身長</th>
      <th>数学</th>
      <th>英語</th>
      <th>理科</th>
      <th>クラス</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>sato</td>
      <td>1</td>
      <td>92.0</td>
      <td>178.0</td>
      <td>50.0</td>
      <td>95.0</td>
      <td>40.0</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>1</th>
      <td>ito</td>
      <td>2</td>
      <td>43.0</td>
      <td>172.0</td>
      <td>60.0</td>
      <td>85.0</td>
      <td>55.0</td>
      <td>B組</td>
    </tr>
    <tr>
      <th>2</th>
      <td>kato</td>
      <td>3</td>
      <td>58.0</td>
      <td>155.0</td>
      <td>70.0</td>
      <td>80.0</td>
      <td>60.0</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>3</th>
      <td>endo</td>
      <td>4</td>
      <td>62.0</td>
      <td>174.0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>4</th>
      <td>naito</td>
      <td>5</td>
      <td>54.0</td>
      <td>168.0</td>
      <td>80.0</td>
      <td>75.0</td>
      <td>65.0</td>
      <td>C組</td>
    </tr>
    <tr>
      <th>5</th>
      <td>NaN</td>
      <td>6</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>90.0</td>
      <td>70.0</td>
      <td>50.0</td>
      <td>B組</td>
    </tr>
    <tr>
      <th>6</th>
      <td>NaN</td>
      <td>9</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>100.0</td>
      <td>65.0</td>
      <td>75.0</td>
      <td>C組</td>
    </tr>
  </tbody>
</table>
</div>



#### 左外部結合


```python
data_left = pd.merge(df1, df2, how='left')
data_left
# left joinでは結合先(df1)に存在するものは残ります。inner joinの時とは違い、欠損値を含めてendoさんのデータが表示されています。left joinでは結合先(df1)に存在するものは残ります。
#inner joinの時とは違い、欠損値を含めてendoさんのデータが表示されています。
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>名前</th>
      <th>学生番号</th>
      <th>体重</th>
      <th>身長</th>
      <th>数学</th>
      <th>英語</th>
      <th>理科</th>
      <th>クラス</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>sato</td>
      <td>1</td>
      <td>92</td>
      <td>178</td>
      <td>50.0</td>
      <td>95.0</td>
      <td>40.0</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>1</th>
      <td>ito</td>
      <td>2</td>
      <td>43</td>
      <td>172</td>
      <td>60.0</td>
      <td>85.0</td>
      <td>55.0</td>
      <td>B組</td>
    </tr>
    <tr>
      <th>2</th>
      <td>kato</td>
      <td>3</td>
      <td>58</td>
      <td>155</td>
      <td>70.0</td>
      <td>80.0</td>
      <td>60.0</td>
      <td>A組</td>
    </tr>
    <tr>
      <th>3</th>
      <td>endo</td>
      <td>4</td>
      <td>62</td>
      <td>174</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>4</th>
      <td>naito</td>
      <td>5</td>
      <td>54</td>
      <td>168</td>
      <td>80.0</td>
      <td>75.0</td>
      <td>65.0</td>
      <td>C組</td>
    </tr>
  </tbody>
</table>
</div>



#### カラムの追加


```python
df2['理系科目'] = df2['数学'] + df2['理科']
df2
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>学生番号</th>
      <th>数学</th>
      <th>英語</th>
      <th>理科</th>
      <th>クラス</th>
      <th>理系科目</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>1</td>
      <td>50</td>
      <td>95</td>
      <td>40</td>
      <td>A組</td>
      <td>90</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2</td>
      <td>60</td>
      <td>85</td>
      <td>55</td>
      <td>B組</td>
      <td>115</td>
    </tr>
    <tr>
      <th>2</th>
      <td>3</td>
      <td>70</td>
      <td>80</td>
      <td>60</td>
      <td>A組</td>
      <td>130</td>
    </tr>
    <tr>
      <th>3</th>
      <td>5</td>
      <td>80</td>
      <td>75</td>
      <td>65</td>
      <td>C組</td>
      <td>145</td>
    </tr>
    <tr>
      <th>4</th>
      <td>6</td>
      <td>90</td>
      <td>70</td>
      <td>50</td>
      <td>B組</td>
      <td>140</td>
    </tr>
    <tr>
      <th>5</th>
      <td>9</td>
      <td>100</td>
      <td>65</td>
      <td>75</td>
      <td>C組</td>
      <td>175</td>
    </tr>
  </tbody>
</table>
</div>




```python
df2.drop('合計得点' ,axis = 1)
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>学生番号</th>
      <th>数学</th>
      <th>英語</th>
      <th>理科</th>
      <th>クラス</th>
      <th>理系科目</th>
      <th>Sum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>1</td>
      <td>50</td>
      <td>95</td>
      <td>40</td>
      <td>A組</td>
      <td>90</td>
      <td>185</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2</td>
      <td>60</td>
      <td>85</td>
      <td>55</td>
      <td>B組</td>
      <td>115</td>
      <td>200</td>
    </tr>
    <tr>
      <th>2</th>
      <td>3</td>
      <td>70</td>
      <td>80</td>
      <td>60</td>
      <td>A組</td>
      <td>130</td>
      <td>210</td>
    </tr>
    <tr>
      <th>3</th>
      <td>5</td>
      <td>80</td>
      <td>75</td>
      <td>65</td>
      <td>C組</td>
      <td>145</td>
      <td>220</td>
    </tr>
    <tr>
      <th>4</th>
      <td>6</td>
      <td>90</td>
      <td>70</td>
      <td>50</td>
      <td>B組</td>
      <td>140</td>
      <td>210</td>
    </tr>
    <tr>
      <th>5</th>
      <td>9</td>
      <td>100</td>
      <td>65</td>
      <td>75</td>
      <td>C組</td>
      <td>175</td>
      <td>240</td>
    </tr>
  </tbody>
</table>
</div>




```python
df2.drop('合計得点' ,axis = 1)
df2.sort_values(by=['Sum'], ascending = False) #一部をソートして全体を表示, False:降順
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>学生番号</th>
      <th>数学</th>
      <th>英語</th>
      <th>理科</th>
      <th>クラス</th>
      <th>理系科目</th>
      <th>合計得点</th>
      <th>Sum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>5</th>
      <td>9</td>
      <td>100</td>
      <td>65</td>
      <td>75</td>
      <td>C組</td>
      <td>175</td>
      <td>240</td>
      <td>240</td>
    </tr>
    <tr>
      <th>3</th>
      <td>5</td>
      <td>80</td>
      <td>75</td>
      <td>65</td>
      <td>C組</td>
      <td>145</td>
      <td>220</td>
      <td>220</td>
    </tr>
    <tr>
      <th>2</th>
      <td>3</td>
      <td>70</td>
      <td>80</td>
      <td>60</td>
      <td>A組</td>
      <td>130</td>
      <td>210</td>
      <td>210</td>
    </tr>
    <tr>
      <th>4</th>
      <td>6</td>
      <td>90</td>
      <td>70</td>
      <td>50</td>
      <td>B組</td>
      <td>140</td>
      <td>210</td>
      <td>210</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2</td>
      <td>60</td>
      <td>85</td>
      <td>55</td>
      <td>B組</td>
      <td>115</td>
      <td>200</td>
      <td>200</td>
    </tr>
    <tr>
      <th>0</th>
      <td>1</td>
      <td>50</td>
      <td>95</td>
      <td>40</td>
      <td>A組</td>
      <td>90</td>
      <td>185</td>
      <td>185</td>
    </tr>
  </tbody>
</table>
</div>




```python
display(df2[df2.Sum > 210]) #　条件をつけてデータを抽出することもできる
```


<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>学生番号</th>
      <th>数学</th>
      <th>英語</th>
      <th>理科</th>
      <th>クラス</th>
      <th>理系科目</th>
      <th>合計得点</th>
      <th>Sum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>3</th>
      <td>5</td>
      <td>80</td>
      <td>75</td>
      <td>65</td>
      <td>C組</td>
      <td>145</td>
      <td>220</td>
      <td>220</td>
    </tr>
    <tr>
      <th>5</th>
      <td>9</td>
      <td>100</td>
      <td>65</td>
      <td>75</td>
      <td>C組</td>
      <td>175</td>
      <td>240</td>
      <td>240</td>
    </tr>
  </tbody>
</table>
</div>



```python

```


```python

```


```python

```


```python

```


```python

```


```python

```

# 作って学ぶPython入門 #002 (youtubeで学習)
## 参考資料：
[作って学ぶPython入門 #002 「間違い探しクイズをつくろう」Pythonのできることの例: 文字列置換、ファイル書き込み。
](https://www.youtube.com/watch?v=MDk8C6ffDYU&list=WL&index=3&t=212s&ab_channel=%E7%9B%B4%E4%B9%9F%E3%83%86%E3%83%83%E3%82%AF)

[formatメソッドを使った文字列の書式設定](https://www.javadrive.jp/python/string/index24.html)

[Pythonでランダムな小数・整数を生成するrandom, randrange, randintなど](https://note.nkmk.me/python-random-randrange-randint/)



```python
import random 


#main関数を定義
def main():
    # rnd = random.randint(50, 100)
    # rnd = random.random()
    count = 0
    positions = []
    problem = ""
    A = 'ぬ'
    B = 'め'
    
   #ポイント：行列計算で二重ループはよく使う
    for x in range(1, 11):
        for y in range(1, 11):
        
            if y % 10 == 0:
                print(A)
                #ポイント：文字列の足し算
                problem += A + '\n'
            else: 
                #ポイント：ランダム関数
                if random.random() < 0.1:
                    print(B, end = '')
                    count += 1
                    problem += B
                    
                    #ポイント：リストに要素を追加
                    p = [x, y]
                    positions.append(p)
                else:
                    print(A, end = '')
                    problem += A
    
    
    # print(count)
    # print(positions)
    print('========================')
    print(problem)


    #ポイント：formatメソッド、print関数とともに使用する。print関数は簡単に値を確認する（デバッグ）ために使うことが多い
    print("「め」の数は{}個\n".format(count))

    for a in positions:
        print("「め」は{}行, {}列目\n".format(a[0], a[1]))


    #ポイント：ファイルへ結果を書き込み ,withを使用すると自動でcloseしてくれる
    with open('result.txt', 'w') as f:
        f.write('間違い探しクイズ！\n')
        f.write(problem)
        f.write('答え:\n')
        f.write("「め」の数は{}個\n".format(count))

        for a in positions:
            f.write("「め」は{}行, {}列目\n".format(a[0], a[1]))


            
            
            
            
if __name__ == '__main__':
    main()
```

    ぬぬぬぬぬぬぬぬぬぬ
    ぬぬぬぬぬめぬぬぬぬ
    ぬめぬぬぬぬぬぬぬぬ
    ぬぬぬぬぬぬぬぬぬぬ
    ぬぬぬぬぬぬめぬぬぬ
    ぬぬぬぬぬぬぬぬめぬ
    ぬぬぬぬぬぬぬぬぬぬ
    ぬぬめぬぬぬぬぬぬぬ
    ぬぬぬめぬぬめぬぬぬ
    ぬぬぬぬめぬぬぬぬぬ
    ========================
    ぬぬぬぬぬぬぬぬぬぬ
    ぬぬぬぬぬめぬぬぬぬ
    ぬめぬぬぬぬぬぬぬぬ
    ぬぬぬぬぬぬぬぬぬぬ
    ぬぬぬぬぬぬめぬぬぬ
    ぬぬぬぬぬぬぬぬめぬ
    ぬぬぬぬぬぬぬぬぬぬ
    ぬぬめぬぬぬぬぬぬぬ
    ぬぬぬめぬぬめぬぬぬ
    ぬぬぬぬめぬぬぬぬぬ
    
    「め」の数は8個
    
    「め」は2行, 6列目
    
    「め」は3行, 2列目
    
    「め」は5行, 7列目
    
    「め」は6行, 9列目
    
    「め」は8行, 3列目
    
    「め」は9行, 4列目
    
    「め」は9行, 7列目
    
    「め」は10行, 5列目