programing sisters 姉

プログラミングを学習するブログです

独学プログラマー18章読んでみた:パッケージ管理ツールpip

 

18章はパッケージ管理ツールについて書いてありました。主にpipについて。なんかわかってる様でわかっていない言葉があったので先に言葉をまとめる。

 

  • パッケージ管理ツール:プログラムのインストールや管理を行うプログラム
  • パッケージ:配布用に梱包されたソフトウェア
  • メタデータ:ソフトウェアの名前やバージョン、プログラムが動作するのに必要な他のパッケージへの依存関係といった情報

pythonのパッケージ管理ツールであるpipは最近のpythonをインストールすれば一緒にインストールされます。

 

新しいパッケージをインストールするには

$ pip install [パッケージ名]

をすれば入ります。

ただパッケージ名を書いただけの時は最新のバージョンがインストールされ、バージョンを指定したいときは[パッケージ名]==[バージョン番号]としてあげることで指定したバージョンをインストールすることができます。インストールしたパッケージを使用する時は、pyhtonのコードのはじめにimportします。

 

パッケージのインストール先としてpythonsite-packagesディレクトリというものがあり、インストールできるパッケージはPyPIに全て登録されているらしい。

 

 

$ pip

と打つとpipでできることが全て表示されるので、それを参考にして使うと良いと思います。

 

仮想環境を作るとその環境ごとに別のパッケージをインストールできるので、違う環境を作りたい時は仮想環境を利用すると良いみたい。

 

研究室でpillow(画像処理などができるパッケージ)をインストールするときもpipを使って少しは知っていたので、「おーこんなことも書いてくれてるのかー」と思いました。pipについては検索するとQiitaなどいろんなページで紹介されているので詳しく知ってなくてもその都度検索すればなんとかなると勝手に思ってます。

独学プログラマー17章読んでみた:正規表現

 

正規表現についてはそもそも意味から何も知らなかったので勉強になりました。

正規表現とは「連続した文字列の検索パターン定義」というものです。一致する文字列をgrepコマンドで検索する方法、pythonのプログラムで検索する方法が詳しく載ってありました。

はじめに

$ export GREP_OPTIONS="--color=always"

とすることで該当する文字の色を変えて出力してくれます。

 

grepコマンドの正規表現

 

grepコマンドは前回のMacでのターミナル上で使える検索するためのコマンドです。

 

$ grep [検索したい文字列]  [ファイル名]

で文字列を検索することができます。

 

$ grep -i [検索したい文字列]  [ファイル名]

-iを追加することで大文字小文字を無視して検索をかけれる。

 

$ grep -o [検索したい文字列]  [ファイル名]

-oを追加することで一致した単語だけを出力できる。

 

正規表現では特別な文字を使うことで単に文字が一致するだけでないものも検索することができるらしい。

 

$ grep ^[検索したい文字列]  [ファイル名]

^[検索したい文字列]こう書くことで検索したい文字列が先頭にきているものを検索できる。

 

$ grep [検索したい文字列].  [ファイル名]

[検索したい文字列]. ピリオドを検索したい文字列の後に書くことで[検索したい文字列]の後に何がきてもその文字列を出力できる。

 

$ grep [検索したい文字列]$  [ファイル名]

[検索したい文字列]$と書くと、[検索したい文字列]が文の終わりに来るものだけを検索できる。

 

 

前回の章のパイプを使った例が載ってました。

 

$ echo two,too,three | grep t[ow]o

[文字1 文字2]とかくとどちらかの文字が該当すれば出力されます。

f:id:yoshinon444:20181015175251p:plain

こんな感じでtwoとtooだけが赤く出力されています。

 

数値を検索するには[ [:digit:] ]という正規表現を使います。

$ echo 123,hi 345,hi | grep [ [:digit:] ]

[ [:digit:] ]を書くだけで数字が検出できます。

f:id:yoshinon444:20181015175521p:plain

こんな感じ。

 

正規表現では

  • アスタリスク * :直前のパターンが0回以上一致
  • ピリオド . :全ての文字列に一致

というルールがあります。なので .* の様に組み合わせると全ての文字列に該当します。アスタリスクは貪欲なので、ルールに当てはまる文字列の中で一番長いものに該当します。非貪欲な正規表現もありますが、それはgrepでは使えないらしい。pythonでは使えるのでその例は後で載せます。

f:id:yoshinon444:20181015180658p:plain

こんな感じで__[文字列]__の一番長いものに該当します。

 

また、特別な文字を普通の文字として使いたい場合は、バックスラッシュを二つかけばokです。

f:id:yoshinon444:20181015180936p:plain

こんな感じ!お金大好きですね!

ちなみにMacでバックスラッシュはoptionキー+¥です。検索すればすぐ出て来るけれども一応書いておく。

 

 

python正規表現

 

python正規表現を使う場合、標準ライブラリのre(regular expression:正規表現)をimportする必要があります。reモジュールの中にあるfindall関数正規表現パターンと検索対象のテキストを渡すと、一致した全ての部分をリストで返します。

f:id:yoshinon444:20181018121234p:plain

一番上にimport reの記述が必要です。この出力は['Beautiful']です。

 

大文字小文字を無視して検索をかけるには、re.IGNORECASEをfindall関数の引数として与えます。

f:id:yoshinon444:20181018115252p:plain

この出力も上と同じです。

 

また数値との一致を検索するには、"\d"を引数として与えます。

f:id:yoshinon444:20181018115540p:plain

この出力は['1','2','3','4','5','6'] です。

 

pythonで使える非貪欲なアスタリスクは*?という記号で表されます。貪欲なアスタリスクでは、ルール内での一番長い文字列に一致すると説明しましたが、非貪欲なアスタリスクはできるだけ文字数が少ない文字列に一致します。

f:id:yoshinon444:20181018120629p:plain

ここで.*?は全ての文字列に一致します。この出力は、['_i_','_love_','_you_']です。

 

正規表現のこと何も知らなかったけど、詳しく書いてあってありがたい。使いこなせるようになりたいな〜。

独学プログラマー16章読んでみた:Bash,コマンド

 

この章は自分にとってすごい有益でした。

今までいまいちわからずに使っていたコマンドラインのことについて詳しく書いてありました。

 

Bashとはコマンドラインインターフェースと呼ばれるもので、キーボードで命令(コマンド)を入力すると様々なことができます。BashMacならターミナルというものをひらけば使うことができます。

 

 

基本的なコマンド

 

  • echoコマンド:printの様に表示させる
  • historyコマンド:最近使ったコマンドを表示
  • pwdコマンド:カレントディレクトリを表示
  • cdコマンド:カレントディレクトリの変更
  • lsコマンド:カレントディレクトリ内にあるものを表示
  • mkdirコマンド:新しいディレクトリを作成
  • rmdirコマンド:ディレクトリを削除
  • touchコマンド:新しいファイルを作成
  • lessコマンド:テキスト・ファイルの内容を観覧,  qでlessを終了
  • whoamiコマンド:OSでのユーザ名を表示

基本的なコマンドでもこんなにたくさんあります。

explainshell.com

 ここにBashのコマンドを入力するとそのコマンドの意味を教えてくれるらしいです。こんな便利なサイトがあったなんて。。

 

 

絶対パス相対パス

 

上で書いたカレントディレクトリを表示させるpwdコマンドは"print working directory"の略らしい。これをターミナルで命令すると( $ pwd )

/Users/名前/Desktop/python/独学プログラマー

と表示されました。私が今独学プログラマーを勉強する用に作った”独学プログラマー”というディレクトリにいるからです。このパスの始まりが" / "で始まっているのは、このパスが絶対パスであることを表していて、ディレクトリの木構造の一番上の親であるルートディレクトリから始まっているということです。

 

cdを命令する場合、移動先のパスを引数として与える必要があります。絶対パスで与えてもいいですが、相対パスで与える場合、今いるディレクトリからのパスを与えます。

例えば私がDesktopにいる時、$ cd python/独学プログラマーと書きます。

この様に相対パスの時は、" / "をはじめに書かないため、コンピュータはそのパスが絶対パスなのか相対パスなのか見分けることができます。

 

私はカレントディレクトリを移動する際は、cd を手で書いて、移動先のファイルを掴んでターミナルの上で離すと、勝手にその絶対パスが表示されるので、そうして移動しています。

 

 

隠しファイル

 

知らなかったんですけど、OSや多くのプログラムはたくさんの隠しファイルなるものを持っているらしい。これは普通のファイルと同じですがデフォルトでは見えない様になっているらしいです。これは、ユーザが間違えてそのファイルを変更・削除してしまい、そのファイルを参照するプログラムが正しく動作しなくなることを防ぐためです。優しいですね。

 

隠しファイルの名前は" .hidden "の様に、" . "で始まります。なので隠しファイルを作る時は、touchコマンドの引数に" . "から始まる名前を与えてあげれば作れます。けど、隠しファイルなので、それを見るときには" $ ls "だけでは見れず、" $ ls -a "と入力しなれけば見れません。

 

 

パイプ

 

Unix系のOSではパイプ( | )と呼ばれるものがあり、これを使うとあるコマンドの実行結果を別のコマンドへの入力として渡せるらしい。

$ ls | less

とするとlsコマンドの実行結果をlessコマンドに渡しているということになります。感覚的にはいつも引数を後ろに書くから変な感じがします。私だけかな。。

 

 

環境変数

 

環境変数とはOSに値を記録しておくための変数です。

$ export [変数名]=[値]

で定義できます。=の前後にスペースを入れるとダメなので気をつけてください。

これはBashのウィンドウ内だけで使えて、ウィンドウを一回閉じるとなくなる変数です。変数の値を出力させるときには、

$ echo $[変数名]

という様に変数名の前に$マークをつける必要があります。

 

 

ユーザー

 

ここでのユーザーはOSを使う人という定義です。複数のユーザーで一つのOSを使えるらしい。ユーザーにはそれぞれどんな操作を許可するのかといった権限(パーミッション)があります。

OSで自分のユーザーが何か知りたいときwhoamiコマンドを命令すると自分のユーザー名を教えてくれます。

 

OS内で一番強力なユーザーはディレクトリの一番上のrootユーザーです。rootユーザーはもっとも多くの権限を持っています。rootユーザーは色々なことができるため、セキュリティー上、普段はrootユーザーとしてログインしてはいけないとありました。rootユーザーとしてコマンドを実行しなければいけないときに、sudo(superuser do)を実行したいコマンドの前に書くことで実行することができます。

前に調べ物をしてたときQiitaでsudoって出てきて「すどう」ってなんだと思ってたけど、この権限のことだったんですね。調べてもいまいちわからなかったけど、今やっと解決しました。sudoを使うとOSに損害を与える様なコマンドも実行できてしまうので、コマンドがOSに損害を与えない確信がある時だけにするべきらしい。

Qiitaに書いてあるからといってそのままやるのはよくないな〜と思いました。気をつけようっと。

 

コマンドよく使うのしか知らなかったからすごいありがたい章だった!!

終わり!!

 

 

独学プログラマー14章読んでみた:オブジェクト指向プログラミング

 

こんにちは。

お久しぶりすぎです。

 

14章は13章の続きって感じでした。

 

クラス変数とインスタンス変数

 

オブジェクト指向プログラミングはクラス変数とインスタンス変数という2種類の変数が存在します。今までにコードで書いてきた"self.[変数名]=[値]"というように書くものはインスタンス変数です。クラス変数はクラス内で通常の変数と同じ様に定義します。

 

f:id:yoshinon444:20181010171115p:plain

 

上の例では、

という感じです。

 

クラス変数が便利なのは、クラスから作られたインスタンスオブジェクトのどこからでも利用できるデータとして使えることで、クラス変数があればグローバル変数を使わずに、クラスのインスタンス間でデータを共有できます。

 

なので、上のコードを実行すると3つ作ったRectangleクラスのインスタンスのwidthとlengthが、作られるときにrecsのリストに追加していくので、Rectangle.recsを表示させると

[ ( 10,20 ),( 20,30 ),( 30,40 ) ]

と表示されます。

 

クラス変数に定数を持たせるのは一般的に行われますが、クラス変数を更新するのはグローバル変数を使う場合と同じ問題に遭遇するのでできるだけ避けるべきらしい。

 

 

特殊メソッド

 

インスタンスを作り、そのインスタンスを表示させようとすると( print("インスタンス名") )pythonはobjectクラスから継承している__rapr__という特殊メソッドを呼び出します。

 

上のrec1を表示させると

<__main__.Rectangle object at 0x1014a0ef0>

という様な文字が出力されます。

 

その__repr__をオーバーライドすることでこの出力を変更することができます。

 

f:id:yoshinon444:20181010173331p:plain

 

さっきの上で書いたコードに__repr__メソッドを追加してrec1を表示させるときちんと

width=10,length=20

と表示させることができました。

 

いつも特殊メソッドのオーバーライドはreturnの形にするというのを私は忘れがち。。

 

特殊メソッドは他にも__add__とか色々あるみたい。

 

 

isキーワード

 

isキーワードは前後のオブジェクトが同一のオブジェクトならTrue、違うオブジェクトならFalseを返すものです。やってみたほうが早い!

 

f:id:yoshinon444:20181011133918p:plain

 

これは上のRectangleクラスのインスタンスを3つ作り、一つ目のrec1をrec_1という別の変数に代入したものです。

  • print( rec1 is rec_1 )は同一のオブジェクトなのでTrue
  • print( rec2 is rec_1 )は違うオブジェクトなのでFalse

と出力されます。長いコードを書くときに確認するために使ったりするのかな。if文の中に使ったりもするみたい。( if x is None : )など。

 

次の章は”知識をまとめる”だから何かゲームを作るのかな!多分!

明日研究室で発表なので何も発表できることないけど頑張って資料作ります〜。。病み。。

独学プログラマー13章読んでみた:オブジェクト指向プログラミング

 

13章は12章の続きのような感じでした。

 

オブジェクト指向プログラミングには大切な概念である4大要素というものがあるそうで、、

それぞれどのようなものなのかを説明してくれてました。

 

カプセル化

 

カプセル化は2つの概念で成り立っていて、1つ目は「オブジェクトによって複数の変数とメソッドをまとめること」です。2つ目は「データをクラス内に隠蔽して外から見えないようにすること」です。本を読んでいる感じでは2つ目がより重要なのかなと思いました。クラスの外からオブジェクトを利用するコードをclientと呼びます。

 

一般的にclientから内部のデータを直接操作されることを防ぐものはプライベート変数やプライベートメソッドを使ってコードを書き、clientから直接操作できるようにする時はパブリック変数を使用します。

 

しかし、pythonにはプライベート変数がありません。そこで、clientからアクセスして欲しくない変数やメソッドには名前の前にアンダースコア( _ )をつけます。これはpythonを書く人の中では暗黙の了解的な感じなのかなと思いました。アンダースコアから名前が始まっているものは、使うべきではないですが、自己責任で直接操作することができます。誤解を恐れてもう一度言いますが、基本的にはアンダースコアから始まっている名前の変数や関数は使うべきではないです!!

 

自分がコードを書くときに気をつけないとですね。。

 

 

抽象化

 

抽象化とは「対象から小さな特徴を除いて、本質的な特徴だけを集めた状態」にする手順のことです。これはクラスのメソッドを作るときに不必要な詳細を省略し、必要な特徴だけを変数として与えるということなのかな。。多分。。例えば、人間には身長とか性別、年齢、目の色など色々な情報が個人個人であるけれど、作りたいものに応じて必要な変数を選び出すということが抽象化ということ。と私は認識しました。

 

 

ポリモーフィズム

 

これは私には聞き覚えのない言葉でした。ポリモーフィズムとは「同じインターフェースでありながらデータ型に合わせて異なる動作をする機能」とありました。んー、どういうことだ、、と思いましたが

f:id:yoshinon444:20180925172803p:plain

というように、同じprint( )でも上は文字列に対応していて、下は整数に対応しています。データ型に依存せず、同じ動作をするということでした。

 

ダック・タイピングというプログラミングの作法があるらしく、あるオブジェクトが使いたいデータ型に期待する動作をしてくれるなら、そのオブジェクトがなんのクラスのインスタンス化は気にしないというものです。実行してみてうまくいったらそれでOKという、授業の課題をやっている私みたいな考え方ですね!!この考え方をダック・タイピングというらしいです。名前の由来が可愛い〜と思ったのですが「それがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルだ」という比喩からきているらしい。数学の証明みたいですね!なんの動物でも同じことが言える気がするけど、そこは気にしないことにしましょう。。

 

 

継承

 

プログラミングの継承は、遺伝的継承に似ていて、クラスのメソッドや変数を受け継ぎます。継承元となるクラスを親クラスと言い、継承先のクラスを子クラスというらしい。日本語のボキャブラリーが私は乏しいのですが、継承というのは受け継ぐということなのかな。継承する時は親クラスの名前を、子クラスの引数として与えてあげれば変数やメソッドなどが引き継がれるらしい。子クラスで親クラスの中にあるメソッド名と同じ名前のメソッドを作ると上書きされて、子クラスのメソッドに置きかわります。これをメソッドオーバーライドというらしいです。

 

 

終わりに

 

チャレンジ問題は次回に回します〜。

今日先輩の中間発表があって聞いてきたんですけど、みんなすごい上手に大人っぽい難しい言葉を使っていて、1歳しか私と変わらない先輩たちなのに、どんな育ち方をしたらナチュラルに難しい感じのかっこいい言葉を使えるんだろうと思いました。。

 

誰か教えてください。

私、本読むの好きな子だったはずなのにおかしい。

 

 

 

 

独学プログラマー12章読んでみた:プログラミングパラダイム

 

第2部に突入です〜!!

 

お父さんが言うにはここからがやっと本題みたいです笑。

 

ちょっと難しい言葉がたくさん書いてあって上手にまとめられるかわからないけど頑張って書いていきます〜

 

プログラミングパラダイム

 

プログラミングパラダイムとはプログラミングのスタイル・手法のことです。

 

たくさんある中でも

が紹介されていました。

 

手続き型プログラミングとは今まで書いてきたようなコードを書く手法のことで、順番に処理を書いていって欲しい答えに少しずつ近づいていく手法です。

 

短いコードを書くのに適していますが状態を全てグローバル変数に持たせているので長いコードを書く場合、グローバル変数の数がどんどん増えてしまって、間違えて変数を上書きしてしまったりという問題が出てきます。

 

これを解決したものが関数型プログラミングです。関数型プログラミングはグローバルステートを排除したため、関数の引数によってのみ動作が変わるので上記の問題を解決できました。欠点としては、グローバルステートを持たせた方が簡単な問題を扱いずらいと言う点です。

 

オブジェクト指向プログラミングもグローバルステートを排除し上記の問題を解決したものですが、関数型とは違い関数の引数に状態を渡すのではなくオブジェクトに状態を持たせるものです。

 

クラスというものが出てきて、クラスとは表現したいオブジェクトを定義・分類したものです。オブジェクト指向プログラミングは複数のクラスで相互に作用するオブジェクトの集合を定義する、とありました。

 

うーん、なんとなくよくわからない、、と思ったけどこの例のおかげで多分理解できました。

 

オレンジがたくさんあって、その一つひとつがオブジェクトで、それぞれに共通の属性( 色・重さなど )があり、クラスでその属性を定義して個々のオブジェクトをそれぞれの属性値を与えて作成するというイメージです。

 

全てのオブジェクトはクラスのインスタンスで、例えばOrangeというクラスから2つのOrangeオブジェクトを作ると、それぞれはOrengeクラスのインスタンスです。

 

 

クラスの扱い方

 

class クラス名:

    スイート

という形で定義するらしい。

クラス名は常に大文字で始まるキャラメルケースと呼ばれるやり方で定義するのが慣習みたいです。(Orange, LikeThis, etc)

スイートには主にメソッドと呼ばれる複合文を書きます。メソッドは関数に似ていますが、クラスの内部で定義し、そのクラスから生成したオブジェクトを通してしか呼び出せないという特徴と、少なくともひとつは引数を定義しなければいけないという特徴があります。

 

あるオブジェクトに属する変数をインスタンス変数と呼び、その定義にself変数というものを使います。

self . [ 変数名 ] = [ 値 ]

インスタンス変数を定義できます。

インスタンス変数はdef __init__という特殊なメソッド内で定義し、ここに書くことでオブジェクトを作るときに 定義されます。( initはinitialize( 初期化 )の略です )

いっぱい私なりにまとめて書いて見たけど言葉にするの難しい。多分見た方が早い!!

 

チャレンジ問題2:円の面積を求める

 

チャレンジ問題のひとつに円の面積を求めるクラスを作ろうというものがあったのでそれを使って説明してみます。

 

f:id:yoshinon444:20180922144720p:plain

 

# ( 1 )

円の面積を求めるためにpiを使いたかったのでmathをインポートしmath.piとしてpiを使えるようにします。

 

# ( 2 )

ここでクラスの定義です。

一つ目のメソッドでインスタンス変数を定義しています。こう書くことで引数で与えられた円の半径をself.rとして使えることができます。

二つ目のareaという名前のメソッドでpiを使って円の面積を計算して、その値を戻り値として返しています。

 

# ( 3 )

C言語でいうmain関数のような場所で、circleという名前のCircleクラスのオブジェクトを半径を10として生成し( インスタンス化 )、Circleクラスのareaメソッドを表示させることで円の面積を得ることができます。

 

終わりに

 

自分の言葉でまとめるってこんなにも難しいか〜と思いました。毎回言ってる気がするけどコードをひたすら書いて慣れるのが一番の近道かもしれない。。受験勉強でも数学とか物理とかひたすら解いて勉強してたからそんな感じでプログラミングも頑張りたい。。

 

あ、おそらく今年最初で最後になるであろう海外旅行に一緒に留年してる友達と行ってきました〜!!人生初めてのバリ!!最高でした!!来年も行こうって約束するくらい最高でした!!

 

f:id:yoshinon444:20180922150104j:plain

 

 みんなにも少し気分をおすそ分け。昨日帰ってきたら日本は急に秋で、、、私の季節がやってきた感がすごい。(私は秋生まれなので秋大好き)

 

現実に戻って日々、勉強筋トレ掃除洗濯その他諸々できるだけ頑張ります〜〜

 

 

独学プログラマー10章読んでみた:ハングマン

 

こんにちは〜〜!

この章は今までの知識を一つに

まとめる目的でハングマンという

文字列を使った古くからある

ゲームを作ろうという章でした。

 

ハングマンってなに?って思ったのですが

ある文字列( 例えば"beer"など )を正解とし

それを当てるゲームです。

間違える度にある絵がどんどん出来ていって

吊るされた人の絵が完成してしまうと

負けです。。こわ笑。。

 

コードはすでに書かれていてそのコードの

説明が丁寧にしてくれていました。

 

 

はじめのコード

 

f:id:yoshinon444:20180910162854p:plain

 

はじめのコードです。

hungmanという関数内で行なっていること

  • wrong( 間違えた回数 )に0を代入
  • stagesにリストで吊るされている人の絵を代入
  • rlettersに正解文字列をリストとして代入
  • boardに正解文字列の長さだけ"_"を代入
  • winにFalseを代入
  • ”Welcome to hangman !!”と出力

このstagesの絵が全部出てきたら負けです。

 

 

ゲーム中のコード

 

f:id:yoshinon444:20180913161421p:plain

 

これはゲーム中に行うこと書いたコードで

絵の行数( len(stages) )-1より間違えた回数( wrong )が

少ない間while文で中の処理を回しています。

 

#( 1 )

まず見やすいように改行し、"guess a word :"で

ゲームしている人に文字を入力してもらいます。

 

 #( 2 )

if文でその文字がrlettersの中にある時にindexメソッドで

その初めに出てくる場所をcindに代入し

boardには正解の文字をその場所に表示するため

入力文字をboardの正しい場所に代入します。

( "_ _ _ _" , "b _ _ _" , "_ e e _" etc...)

そして同じ文字が2回以上ある文字列を正解に

している時のためにその文字を"$"に変えます。

( indexメソッドは" 初めに "出てくる場所を教えてくれる )

else文でその文字がrlettersの中にない場合

wrongを+1します。

 

#( 3 )

broardを出力し、stagesを0からwrong+1まで

改行しながら出力します。

 

#( 4 )

broardの中に"_"が無くなったら"You Win !!"と

出力し正解の文字列を出力しwinをTrueにし

breakでwhile文を抜けます。

 

 

最後のコード 

 

f:id:yoshinon444:20180913161447p:plain

 

while文を抜けた時に、winがTrue出なければ

(Falseのままだったら)、stagesを全て出力し

"You Lose !!"と出力します。

 

 

 終わり

 

コードを見てなるほどなるほど〜と書いてたら

できるけど、何もなしで作ってと言われたら

多分まだ書けないだろうなぁと思いました。

まだまだ道のりは長そうです。

 

 コードブルーを今日見てきて

頑張ってる人ってかっこいいなぁと

思ったので私も頑張ってかっこいい感じに

なりたいなぁ。。

 

こうやって自分で流れをまとめて書くことで

ブログ書くの時間かかるけど

自分の理解にも繋がるはず。。

 

次からは第2部です。。