クラスやグラフの作図について

#　クラス
クラスに関する定義は難解の為、繰り返しコードを読み返して、理解を深めていく必要があうと思います。

以下に参考となるコードがありましたので、まずは、読み進めてください。
参考: https://github.com/toksan/python3_study/blob/master/class/example_basic_1.py


クラスを使用したコードは、このような記述をします。

```
class MyClass():
    total_name_num = 0
    total_age = 0
    def __init__(self, name, age) :
        self.name = name
        self.age = age
        MyClass.total_name_num += 1
        MyClass.total_age += self.age    
    def show(self) :
            print("{}は{}歳です。".format(self.name, self.age))        
   @classmethod
    def show_total(cls):
        print("人数は{}人、年齢の合計は{}歳です。".format(cls.total_name_num, cls.total_age))

cls1 = MyClass("Test1", 10)
cls2 = MyClass("Test2", 20)
cls1.show()
cls2.show()
cls1.show_total()
cls2.show_total()

出力結果
Test1は10歳です。
Test2は20歳です。
人数は2人、年齢の合計は30歳です。
人数は2人、年齢の合計は30歳です。
```


上のクラスを継承したExMyClassを定義し、showメソッドを新しくname_suffixという引数を受け取れるようにオーバーライドせよ
・name_suffixを受け取った場合、showメソッドは、"namename_suffixはage歳です。"と表示するようにせよ
例 name="test", age=10, name_suffix="さん" → testさんは10歳です。
・name_suffixはデフォルト値=Noneとしておいて、name_suffixがNoneまたは与えられない場合、親クラスのshowメソッドが動くようにせよ

```
class MyClass():
    def __init__(self, name, age) :
        self.name = name
        self.age = age
    def show(self) :
        print('{}は{}歳です。'.format(self.name, self.age))
       
class ExMyClass(MyClass):
     def show(self, name_suffix = None) :
        if name_suffix :
            print('{}{}は{}歳です。'.format(self.name,name_suffix, self.age))
        else :
            super().show()

cls1 = ExMyClass("Test1", 10)
cls2 = ExMyClass("Test2", 20)
cls1.show("さん")
cls2.show()

出力結果
Test1さんは10歳です。
Test2は20歳です。
```


11.2で作ったクラスのnameを非公開にし、getterとsetterを設定せよ

```
class MyClass():
    def __init__(self, name, age) :
        self.__name = name
        self.age = age
        
    # nameプロパティのゲッター
    @property
    def name(self) :
        return self.__name
    
    # nameプロパティのセッター
    @name.setter
    def name(self, name) :
        self.__name = name
        
    def show(self) :
        print('{}は{}歳です。'.format(self.name, self.age))

cls1 = MyClass("Test1", 10)
print(cls1.name)
cls1.name = "NewTest1"
print(cls1.name)
cls1.show()
```


#　テキストデータの開き方

簡単な方法をまとめました。

```
file = "./book.txt"　#ファイルを指定
with open(file, "w", encoding="utf-8") as f :　#エンコードなど指定
    f.write(text)　#最後記述
```

ファイルを一行ずつ読み込み、その際にenumerateで行番号をつけよ

```
file = "./book.txt"
with open(file, "r", encoding="utf-8") as f:
    for i, line in enumerate(f, 1) :
        print("{}: {}".format(i, line))

file = "./srcs/hello.txt"
fin = open(file)    # 1. ファイルを開く
text = fin.read()  # 2. ファイルを読み込む
fin.close()            # 3. ファイルを閉じる

print(text)
```

また置き換えは以下のような記述で行います。

```
file = "./srcs/hello.txt"
with open(file) as fin :# 1. ファイルを開く
    text = fin.read() # 2. ファイルを読込む
    newtext = text.replace(".", "").strip()
    wordlist = newtext.replace("\n", " ").split(" ")
    print(wordlist)
```

テキストファイルの書き出しは下記の通りです。

```
file = "./srcs/sample.txt"
fin = open(file, "w", encoding="utf-8")#    # 1. ファイルを開く
fin.write("こんにちは\n")#　　　　　　　　　　 　　　　           　　# 2. ファイルに書き込む
fin.write("Pythonを始めよう\n")#                 # 3. 続きを書き込む
fin.close()#                                                    # 4. ファイルを閉じる

with open(file) as text:
    print(text.read())
```

#　グラフ作成
Pythonでは様々なグラフを描くことができます。この項では非常に基礎的ですが、使用頻度の高いものを幾つか紹介します。

```
%matplotlib inline
import matplotlib.pyplot as plt # グラフを描くためのモジュール
data = [1,1.3,5,0.2,-1,4]# グラフ化するデータ（リスト）
plt.plot(data) # グラフを描く
plt.show() # 表示する
```

下記のグラフは、x軸、Y軸の両方を指定します。

```
X = [6,8,12,20,23]
Y = [752, 654,343,102,78]
import matplotlib.pyplot as plt # グラフを描くためのモジュール
plt.plot(X,Y) # グラフを描く
plt.xlabel("temperature")
plt.ylabel("sales")
plt.title("oden")
plt.show() # 表示する
```

マーカーを付ける

```
plt.plot(X,Y, marker = "o") # グラフを描く
```

グリッドを付ける

```
plt.grid(True)
```

このように数式のグラフもキレイに描くことができます。

```
X = range(-10,10)
Y = [i**3 -3*i**2 + i + 4 for i in X]

import matplotlib.pyplot as plt # グラフを描くためのモジュール
plt.plot(X,Y, marker = "o") # グラフを描く
plt.grid(True)
plt.savefig("./graph.png")
plt.show() # 表示する
```

グラフを重ねてみましょう。

```
X = range(-10,10)
Y = [i**3 -3*i**2 + i + 4 for i in X]
X1 = range(-10,10)
Y1 = [-10*i for i in X1]

import matplotlib.pyplot as plt # グラフを描くためのモジュール
plt.plot(X,Y, marker = "o") # グラフを描く
plt.plot(X1,Y1, marker = "o")
plt.grid(True)
plt.savefig("./graph.png")
plt.show() # 表示する
```

こちらも、同様に、２つのグラフを重ねて書いてみます。

```
Y1 = [30, 20, 15, 8, 4]
Y2 = [40, 24, 13, 5, 2]
# answer
plt.plot(Y1, marker="v", color="black", linestyle="--", label="control")
plt.plot(Y2, marker="^", color="red", label="target")
plt.legend(loc="upper right")
plt.show()
```

棒グラフを縦横で書いてみます。

```
label = ["x{}".format(x) for x in range(10)]
Y = [32,34,53,63,4,99,34,55,67,51]
import matplotlib.pyplot as plt
plt.bar(range(len(Y)), Y, tick_label = label)
plt.show()
plt.barh(range(len(Y)), Y, tick_label = label)
plt.show()
```


３つの積み上げグラフを書きましょう。

```
labels = ["a","b","c","d","e"]
Y1 = [10,20,30,40,50]
Y2 = [70 - y for y in Y1]
Y3 = [y / 2 + 10 * i for i, y in enumerate(Y1)]
legend = ("y1","y2","y3")

import matplotlib.pyplot as plt
X = range(len(Y1))
bar1 = plt.bar(X, Y1)
bar2 = plt.bar(X, Y2, color="g", bottom = Y1)
bar3 = plt.bar(X, Y3, color="r", bottom = [y1+y2 for y1, y2 in zip(Y1, Y2)])
plt.xticks(X, labels) 
plt.legend((bar1, bar2, bar3), legend, loc="best")
plt.show()
```

散布図を書いてみましょう。

```
import numpy as np
X1 = list(np.random.rand(10))
X2 = list(np.random.rand(10) + 0.5)
Y1 = list(np.random.rand(10))
Y2 = list(np.random.rand(10) + 0.5)

import matplotlib.pyplot as plt
plt.scatter(X1,Y1, marker="o", color="b")
plt.scatter(X2,Y2, marker="x", color="g")
```

散布図の要素のサイズをx軸の値とy軸の値が大きくなるにつれて大きくせよ

```
import matplotlib.pyplot as plt
plt.scatter(X1,Y1, s=[(x1+y1)*100 for x1, y1 in zip(X1, Y1)], marker="o", color="b")
plt.scatter(X2,Y2, s=[(x2+y2)*100 for x2, y2 in zip(X2, Y2)], marker="x", color="g")
plt.show()
```

円グラフを描け。ラベルと内訳の％も付属せよ

```
data = [x ** 2 for x in range(1,6)]
labels = ["x1","x2","x3","x4","x5"]

import matplotlib.pyplot as plt
plt.pie(data, labels=labels, autopct="%1.1f%%")
plt.show()
```

2×2で4つ棒グラフを描け

```
def minmax(li):
    min_ = min(li)
    max_ = max(li)
    return [(x - min_) / (max_ -  min_) for x in li]
X1, Y1, title1 = range(5), [10,30,20,40,50], "X1"
X2, Y2, title2 = range(5), [20,44,32,10,15], "X2"
X3, Y3, title3 = range(5), minmax(Y1), "X1_minmax"
X4, Y4, title4 = range(5), minmax(Y2), "X2_minmax"
labels = range(5)

import matplotlib.pyplot as plt
fig = plt.figure()
for i, z in enumerate(zip([Y1,Y2,Y3,Y4], [title1,title2,title3,title4])):
    ax = fig.add_subplot(2, 2, i+1)
    ax.bar(X1, z[0], tick_label = labels)
    ax.set_title(z[1])
plt.tight_layout()
plt.show()
```


12のグラフのY2の縦軸をY1に揃えて表示せよ

```
import matplotlib.pyplot as plt
fig = plt.figure()
for i, z in enumerate(zip([Y1,Y2,Y3,Y4], [title1,title2,title3,title4])):
    ax = fig.add_subplot(2, 2, i+1)
    ax.bar(X1, z[0], tick_label = labels)
    ax.set_title(z[1])
    if i == 0:
        last_ylim = plt.ylim()[1]    
    elif i == 1:
        plt.ylim(0, last_ylim)    

plt.tight_layout()
plt.show()
```

とりあえず今日はここまで！