OmniAICreator/Qiita-1.07M huggingface dataset:
ESLintのカスタムルールでin+配列を禁止しよう

# なぜin+配列を禁止するのか？

Pythonで

```python:Python
>>> 0 in [1,2]
False
>>> 1 in [1,2]
True
```

となり、JavaScriptで

```javascript:JavaScript
> 0 in [1,2]
true
> 1 in [1,2]
true
```

となるので、間違いやすい。

このルールの正しいコードの例は

```javascript:JavaScript
> [1,2].includes(0)
false
> [1,2].includes(1)
true
```

となる。

ESLintにin+配列を禁止するルールがない。

ESLintのカスタムルールを作ってin+配列を禁止しよう。

# 禁止する方法

.eslintrc.js の rules に "no-in-array": "error" を追加。

rules フォルダーに [no-in-array.js](https://github.com/querykuma/snippets/blob/master/eslint-rules/no-in-array.js) を作成。

# 動作確認

```javascript:test.js
const k = [1, 2];

console.log(1 in [3, 4]); // エラー

for (const i in [5, 6]) // エラーなし
    for (const j in [7, 8]) // エラーなし
        console.log(i in k, j); // エラー
```

```shell
> eslint --rulesdir rules test.js

  4:13  error  in + array is a troublemaker                 no-in-array
  8:21  error  in + array is a troublemaker(variable init)  no-in-array
```

--fix にも対応した。

```shell
> eslint --rulesdir rules test.js --fix
```

```javascript:test.js
const k = [1, 2];

console.log([3, 4].includes(1)); // エラーなし

for (const i in [5, 6]) // エラーなし
    for (const j in [7, 8]) // エラーなし
        console.log(k.includes(i), j); // エラーなし
```

`for (const i in [5, 6])`が文字列型で"0", "1"を返し`[1, 2].includes("1")`がfalseになることも間違いやすい。

# 参考にしたサイト

[ESLint のカスタムルールを作ろう! (その1) - Qiita](https://qiita.com/mysticatea/items/cc3f648e11368799e66c)
[書いて覚える ESLint ルールの作り方：キマリは通さない - Qiita](https://qiita.com/kik4/items/ef30d5e0e24dabb81463)
[Working with Rules - ESLint - Pluggable JavaScript linter](https://eslint.org/docs/developer-guide/working-with-rules)

# おわりに

ESLintに追加されたら嬉しい。
MATLABの複数subplotで共通するcolorbarの追加方法

二次元プロットの場合、表現できるデータの種類はx軸、y軸と色を使った最大三種類。
三次元プロットならz軸も併せ四種類。兎に角、MATLABのplot内でcolorbarの追加についてメモ。

単一プロットの場合
----------
例えば、複数の軌道をひとつのプロットにまとめて表したいとする。

```matlab
colorSet = cool(length(family));

for i = 1:100:length(family)
    [~, ~, ~, X_out] = integrate_er3bp_ode45_stm(family(i,1).state, family(i,1).period, mu, 0);
    figure(5)
    plot3(X_out(1,:), X_out(2,:), X_out(3,:),'-', 'linewidth', 0.7, 'Color', colorSet(i,:));
end
set(gcf, 'Colormap', colorSet);
caxis([family(1,1).period, family(end,1).period]);
colorbar('eastoutside');
```
上記のcolorbar()関数内でバーの場所を指定。オプションはdocsを参照：
https://uk.mathworks.com/help/matlab/ref/colorbar.html

![halo_color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656299/4f7291f3-684c-6705-4074-4ea47341595f.png)



Subplotのスタック方向にcolorbarを追加する
----------
これはどうも苦戦中… これから脱却したい…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656299/36428223-a2fb-0773-e197-7248236d90fa.png)


Subplotのスタックの隣にcolorbarを追加する
----------


https://stackoverflow.com/questions/10649286/how-to-keep-the-subplot-sizes-unchanged-after-putting-a-colorbar
より

```matlab
f1=figure(1);clf;
s1=subplot(1,2,1);
surf(peaks(20));

s2=subplot(1,2,2);
surf(peaks(20));
hb = colorbar('location','eastoutside');

%% # Solution:
s1Pos = get(s1,'position');
s2Pos = get(s2,'position');
s2Pos(3:4) = [s1Pos(3:4)];
set(s2,'position',s2Pos);
```

https://stackoverflow.com/questions/10649286/how-to-keep-the-subplot-sizes-unchanged-after-putting-a-colorbar
https://stackoverflow.com/questions/16064451/reposition-colorbar-or-subplots
[名称]何かの名称に悩んだ時に見る色々。

##名称に悩んだ時に見る色々

私が楽になるリンク集です。
色とか　　[和色大辞典](https://www.colordic.org/w)
数字とか　　[漢字数字（大字）](http://www.natubunko.net/kotoba02.html)
数字の桁数　[漢数字での位の名称・漢数詞](https://www.benricho.org/kanji/kansushi.html)

日本人の名前とか　[名前ランキング](https://www.meijiyasuda.co.jp/sp/enjoy/ranking/index.html#/year/2019n/1)

妖怪とか　[怪異・妖怪画像データベース](https://www.nichibun.ac.jp/YoukaiGazou/)
西洋の怪物とか　[モンスター辞典](http://burugariya.php.xdomain.jp/dictionary/monster.html)

武器とか　[武器防具一覧](http://www.jiten.info/dic/buki.html)

何か一覧を見つけたら追加していきます。
Python手遊び(CSVファイルから列名を取得)

#この記事、何?
表題の通り。10分で書いたような記事。
CSVファイルの1行目をとってsplit(',')して返す。それだけ。

伏線・・・かも?

#コード
```py


def get_lines_from_textfile(filepath):
    with open(filepath, 'r', encoding='utf-8') as f:
        lines = f.readlines()
    return lines


def get_columns_list(csvpath):
    line_1st = get_lines_from_textfile(csvpath)[0]
    return line_1st.split(',')


def main():
    csvpath = 'solubility.test.csv'
    columns = get_columns_list(csvpath)
    for column in columns:
        print(column)


if __name__ == '__main__':
    main()

```

#感想
特になし。
Vue.jsについて学んだこと

### 本記事について

仕事で必要になり、Vue.jsについて勉強した。
Qiitaの記事作成の練習も兼ねて、勉強したことについてまとめていく。

### Vue.jsとは

Vue.jsとはクライアントサイドで使われるJavaScriptフレームワークのこと。
JavaScriptフレームワークはDOM（HTMLドキュメント全体の要素の構成のこと）操作を自動化するなど、より効率よくフロントエンドの開発が行えるようになっている。

JavaScriptフレームワークには、Vue.jsの他にAngular、Reactなどがある。

### Vue.jsの特長

- 学習コストが低い
 -  Vue.jsは他のフレームワークと比べると規模が小さく、その分覚えることが少なくて済む。
- MVVMモデル
 - MVVM(Model View ViewModel)モデルを採用しており、ユーザーが入力した情報と、格納したデータをデータバインディングにて自動的に処理することができる。



### 参考URL
[はじめに -vue.js](https://jp.vuejs.org/v2/guide/index.html) : 公式ドキュメント。vue.jsの基本的な使い方がかなり詳しく記載されている。
クロスサイトスクリプティングが起こる原因とその対策

# クロスサイトスクリティング(XSS)とは
掲示板サイトなどの入力内容をWebページに表示するWebアプリケーションにおいて、Webサイトの脆弱性を利用した攻撃手法のこと。
入力内容からWebサイトの表示を生成する処理の際、Webページに任意のスクリプトが紛れ込み、Webサイトを閲覧したユーザーにスクリプトが実行されてしまう。

# クロスサイトスクリティング(XSS)が起こる原因
起こる原因は2つ

1. 入力が制限されていないこと
2. HTMLタグやJavaScriptなどのスクリプトが入力された場合、その内容をそのまま実行してしまう
→ エスケープ処理がされていない

# 起こるとどうなるのか？
実際にクロスサイトスクリプティングの被害に合うと下記のようなことが起こってしまう。

- ユーザーを騙す表示によるフィッシング詐欺
    - 正当なメールやWebサイトを装い、個人情報・暗証番号等が取得されてしまう
- クッキー情報の取得によるセッションハイジャック
    - Webアプリケーションなどでユーザーを識別する情報、セッションID（IDやパスワード情報など）のCookie情報をネットワーク上で盗聴されたり、規則性から類推されることで、攻撃者が利用者になりすます攻撃手法
        - 不正な送金、利用者が意図しない商品購入、利用者が意図しない退会処理等が発生する
- Webサイトの改ざん
    - Webサイト内のコンテンツやシステムが、攻撃者によって意図しない状態に変更されてしまう

## 実例
### Youtube
「ニュース速報：ジャスティン・ビーバーが交通事故で死亡」といったデマのポップアップが表示されたり、他のWebサイトにリダイレクト、コメントが表示されないなどの被害が発生した。


### Twitter
- ユーザーのアカウントが遠隔的にハイジャックされ、訳の分からないリツイートを大量に投稿したりといった被害が発生

# 対策
## ①入力値を制限する
例えば、年齢や電話番号を入力する際は数値しか入力できないようにすれば、スクリプトを入力されることがなくなる
ただクライアントサイドのみで制限をかけてしまうとデベロッパーツール等で簡単に変更ができてしまうため、必ずサーバ側での制限設定を行うようにする

## ②エスケープする
例えば＜script＞〜＜/script＞という文字列をスクリプトではなく、文字列となるように置換してあげる

## ③WAFで防御する
①・②はアプリケーション作成の段階で対応するものであり、人が作成するためどうしても見落とす可能性がある
WAFではユーザからのリクエスト内容をチェックしているため、クロスサイトスクリプティングを防御することが可能
【Javascript】JS　変数　定数　違い 　一言でまとめました

##【ゴール】
javascriptの変数、定数の違い

##【メリット】
＊　javascript理解度向上

##【コード】
###変数（var , let）
＊**中身を何回も更新できる**

####var
＊再宣言可能
＊再宣言の際に(var)は不要

```js:hoge.js
var name = "太郎";

console.log(name);　// 太郎が出力


name = "次郎"；

console.log(name);　//次郎が出力

var name = "三郎"; //再宣言可能

```

#### let
＊同変数名は一度しか宣言できない

```js:hoge.js
let name = "太郎";

console.log(name);  //太郎が出力

let name ="次郎"; //エラー出る...

```

###定数
＊**中身は一回だけ決めれる**
#### const 
```js:hoge.js
 const name = "太郎";
 
 console.log(name); //太郎と出力
```



##【合わせて読みたい】

■JavaScriptで書く「let,var,const」の違い・使い分け 
https://techacademy.jp/magazine/14872

■ 【JavaScript】 js　繰り返し文　for / while
https://qiita.com/tanaka-yu3/items/942d9d4838ebe14be1c2

■ 【jQuery】初心者でもよく理解できたやつ
https://qiita.com/tanaka-yu3/items/a03734b248c3f2ee8461
kintoneに、LogRocketを追加してエラーを監視する

#なぜ導入するのか？
[kintone](https://kintone.cybozu.co.jp/)を使う人って、エラーの表現に疎い人が多いため、「なにかエラーが出ました」「動きません」という話が多く、どうにかしてエラーの状態が分かれば良いなと思って導入してみました。(失礼な言い方ですみません。。)

# 対象者
kintoneの管理者権限を持っていて、jsのカスタマイズができる人

# LogRocketって何？
https://logrocket.com/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29550/ea028e21-fae4-2ef0-be1a-468c95a1cbf6.png)

流行りの[DeepL](https://www.deepl.com/ja/translator)で翻訳すると

>バグが起こる理由を推測するのはやめよう

>LogRocket を使用すると、ユーザーがサイト上で行っていることを再生して、バグを再現したり、問題をより早く修正したりすることができます。

開発者の場合、1000セッション/月まで無料で試すことができる。[料金表](https://logrocket.com/pricing/)

# 導入の方法も簡単
サインアップ方法は、Google アカウントと紐付けられるから、省略。

1. 左上の、「New Project」から追加して、プロジェクト名を入力(**これで、すでに33%の進捗！**)
2. 次に、kintoneのログインした後、歯車マークから「システム管理」に飛んで、カスタマイズ項目の「JavaScript/CSSでカスタマイズ」に飛ぶ
3. PC用、スマートフォン用のJavaScriptファイルにそれぞれURLで「[https://cdn.lr-ingest.io/LogRocket.min.js](https://cdn.lr-ingest.io/LogRocket.min.js)」を追加する
4. また、次の「logrocket.js」をアップロードして追加し、保存

```logrocket.js
(function () {
    "use　strict"
    window.LogRocket && window.LogRocket.init('*******/project-name');
    var user = kintone.getLoginUser();
    LogRocket.identify(user.id, {
        name: user.name,
        email: user.email,
        code: user.code,
        employeeNumber: user.employeeNumber
    });

})();
```

「*******/project-name」については、LogRocketのページの、Install LogRocketのSCRIPT TAGのタブに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29550/b157403c-7cdb-10b6-7fde-b98a0a39edf8.png)

こんな感じで、載っているので、コピペしてくださいませ。

logrocket.jsは、すでに次の項目の「Identify users」は記載済みなので、この後からkintoneを動かすと、セッションやエラーなどがどんどん記録されます。


今回は、全体的に入れましたが、エラーの観測を常にしておきたいアプリだけ、とかに導入するのもアリだとは思います。
変分推論について

変分推論は近似推論の一種です．

例えば，混合モデルの事後分布は計算が膨大であり，現実的には解くことが難しい場合が多いです
そのため，ある程度近似することによって事後分布を推論しようというのが近似推論です

言い換えると，ある確率分布$p(z_1,z_2,z_3)$を近似分布$q(z_1,z_2,z_3)$に置き換えるということです
具体的にはKLダイバージェンスを用いて以下のように求めます
$$
q_{opt.} = argmin_q KL[ q(z_1,z_2,z_3) \mid \mid  p(z_1,z_2,z_3)]
$$

その中でも変分推論は，平均場近似という近似分布に以下のように独立性を仮定した分布になります


$$
p(z_1,z_2,z_3) \approx q(z_1) q(z_2) q(z_3)
$$


変分推論の流れとしては，上の例で言うと$q(z_1)$を求めるために，$q(z_2)$と$q(z_3)$を初期値として与え，
それを固定して最適化問題を解きます．同様に，$q(z_2)$は先程求めた$q(z_1)$と初期値の$q(z_3)$を固定して求めます

アルゴリズムはこのようになります

+ $q(z_2)$と$q(z_3)$を初期化
+ $q(z_1)$を $q(z_2)$と$q(z_3)$用いて期待値を導出． $q(z_2)$と $q(z_3)$も同様に求めたいパラメータ以外を用いて期待値を導出
+ ステップ1，2を繰り返して行う．
 
では，なぜこのように求めたいパラメータを用いて期待値を求めるのか導出していきます
冒頭でも書いたように，変分推論ではKLダイバージェンスを用いて近似分布を求めることでした．それを色々変形することで求まります．

$$
\begin{align}
KL[q(z_1,z_2,z_3) \mid \mid  p(z_1,z_2,z_3)]
&= -\langle \ln \displaystyle \frac{p(z_1,z_2,z_3)}{q(z_1) q(z_2) q(z_3)} \rangle_{q(z_1)q(z_2)q(z_3)} \\\
&= - \langle \langle \ln \displaystyle \frac{p(z_1,z_2,z_3)}{q(z_1) q(z_2) q(z_3)} \rangle_{q(z_2)q(z_3)} \rangle_{q(z_1)} \\\
&= - \langle \langle \ln p(z_1,z_2,z_3) \rangle_{q(z_2)q(z_3)} -  \langle \ln q(z_1) \rangle_{q(z_2)q(z_3)} - \\\
& \hspace{30px} \langle \ln q(z_2) \rangle_{q(z_2)q(z_3)} - \langle \ln q(z_3) \rangle_{q(z_2)q(z_3)}  \rangle_{q(z_1)} \\\
&= - \langle \langle \ln p(z_1,z_2,z_3) \rangle_{q(z_2)q(z_3)} -\ln q(z_1) \rangle_{q(z_1)} + const. \\\
&= - \langle \ln \displaystyle  \frac{\langle  \exp\{ \ln p(z_1,z_2,z_3) \rangle_{q(z_2)q(z_3)} \} }{q(z_1)} \rangle_{q(z_1)} + const. \\\
&= KL[ q(z_1) \mid \mid  \exp\{\langle  \ln p(z_1,z_2,z_3) \rangle_{q(z_2)q(z_3)} \}] + const. 
\end{align}
$$


とてもややこしい式なので一つ一つ説明してきます
まず1行目は以下のKLダイバージェンスの公式を利用しています
$$
\begin{align}
KL[q(x) \mid \mid  p(x)] &= - \int q(x)  \displaystyle \frac{p(x)}{q(x)} dx \\\
&= \langle \ln q(x) \rangle_{q(x)} -\langle \ln p(x) \rangle_{q(x)}
\end{align} 
$$

2,3行目は期待値全体を$q(1)$でくくり，バラバラにしています
そして4行目では，$z_1$に関係ない項を定数にしています．5行目では，全体に対数を取るようにしています．ちなみに，分子がこうなるのは$ e^{\log{x}} = x$を利用しています．こうした変換を繰り返すことで，再びKLダイバージェンスが出てきました

最後の式を見ると，$q(z1)$の近似分布は以下のようになることがわかります

$$
\ln{q(z_1)} = \langle \ln p(z_1,z_2,z_3) \rangle_{q(z_2)q(z_3)} + const.
$$

$q(z2)$と$q(z3)$も同様です．平均場近似によって独立だと近似したため，あとはかけ算するだけですね．

須山敦志さんの「[ベイズ推論による機械学習入門](https://www.amazon.co.jp/dp/B07L2V4H59/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)」を読んで学んだことを書いてまとめているだけなので，この本を読んだほうが良いです．．．
Blazor WebAssemblyを試してみる

他の方の書かれたQiita記事を拝見していて、ぼちぼちBlazor WebAssemblyも実用レベルになりつつあるのかなと思いましたので、試してみました。

# 準備

### .NET Core 3.1 SDKをインストール

[ここ](https://dotnet.microsoft.com/download)からダウンロードしてインストールします。

### テンプレートからアプリを作成する

以下のようにdotnetコマンドで作成します。

##### Blazor WebAssemblyのテンプレート最新をインストール  

`dotnet new --install Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0`

##### アプリ作成

`dotnet new blazorwasm -o dotnetcore-blazorwasm-sample`

### 追加のサンプルコードを書く

何かしら動きのあるサンプルを作りたかったので、今回は、`/testPage`にアクセスしたら１秒更新の時計を表示するページを追加してみます。

以下のコードを`/Pages/TestPage.razor`として追加します。

```C#:TestPage.razor
@using System.Timers
@implements IDisposable
@page "/testPage"

<h1>Test Page</h1>

<p>@message</p>

<p>Now Time: [@nowTime]</p>

@code {
    private String message = "This is test page.";
    private String nowTime = DateTime.Now.ToString();
    private Timer timer;
    protected override void OnInitialized()
    {
        timer = new Timer(1000);
        timer.Elapsed += (sender, e) =>
        {
            nowTime = DateTime.Now.ToString();
            StateHasChanged();
        };
        timer.Start();
    }

    public void Dispose() {
        timer.Stop();
        timer.Dispose();
    }
}
```

ページ生成時に`timer = new Timer(1000);`で１秒間隔のタイマーを作り、満了するごとに現在時刻をnowTimeに設定するようにします。
ポイントは`StateHasChanged();`を呼んでいるところで、これを呼ばないとビューの更新が必要なことが通知されず、表示が変わりません。

ページ破棄時に`Dispose()`を呼んでもらうために`@implements IDisposable`しています。
`Dispose()`内ではタイマーを止めてリソースを破棄しています。

### 実行

`dotnet run` で実行します。
ブラウザで`http://localhost:5000`にアクセスして確認します。

### 結果

![dotnetcore-blazorwasp-sample_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70686/d57de99a-ef0a-6eaf-63b0-73f91097f6a9.png)

上記のように時計が表示されて１秒毎に更新されます。


### 最後に

ちょっと起動時の`Loading...`表示が長かったりするかなとは思いましたが、こういった少し動きのあるページがJavaScript書かずにブラウザ上で動いているのはなかなか面白いですね。

なお、今回のサンプルコード全体はこちらの[GitHubリポジトリ](https://github.com/yoshinoyaussie/dotnetcore-blazorwasm-sample/tree/qiita-public)で参照できるようにしてありますので、興味あればご覧くださいませ。

では。
Rakuten Rapid APIを使ってWeb APIを公開してみたときのメモ

# 概要
個人で公開したWeb APIをRakuten Rapid APIで公開をしてみたので気になった機能をメモします。

# Rakuten Rapid APIとは

[Rakuten Rapid API](https://api.rakuten.co.jp/docs/ja/docs/what-is-rapidapi/)

> Rakuten RapidAPIは、開発者がAPIを検索・接続し、利用状況を管理できるAPIマーケットプレイスです。ご自身のプロジェクトに必要なAPIを検索してアプリに埋め込み、ダッシュボードでAPIの利用状況が一括管理できます。また、APIプロバイダの方は、Rakuten RapidAPIを活用することで、自社のAPIを数十万といるRakuten RapidAPIのアクティブ開発者に公開することができます。
> 
( [公式サイト](https://api.rakuten.co.jp/docs/ja/docs/what-is-rapidapi/)より抜粋)

Rakuten Rapid APIは上記の通りAPIの検索や管理を容易にするサービスです。
開発者が多数のAPIを一元管理して開発を行うことができるだけでなく、APIプロバイダがAPIの外部公開やマネタイズを手軽に行うことのできるサービスでもあります。

# 公開したAPI
以前Qiitaでも記事にした「[Chaplus 雑談対話API](https://www.chaplus.jp/)」という個人で開発したWeb APIを公開しました。(Rakuten Rapid APIは登録作業から実際に動作を確認するまで、数十分程度で作業が完了しました。)

APIの紹介記事はこちらです。
[Botが雑談に応えられるようにするWEB APIを公開してみた話【個人開発】](https://qiita.com/maKunugi/items/b1afb6441571119729a7)


# Rakuten Rapid APIで公開した目的
- Rakuten Rapid APIを触ってみたかったから
- APIキーやリクエストの管理が容易にできそうだったから
- APIを探す開発者にリーチできそうだったから

Rakuten Rapid APIを利用してみた目的は上記の通りです。
APIキーやリクエストの管理が容易にできそうだったことが決めてとなり、実際に利用をしてみることにしました。

# 機能紹介

APIの登録方法は公式Docに細かく記載されているので省略します。
https://api.rakuten.co.jp/docs/docs/getting-started/

この記事では、使ってみて便利だと感じた機能をメモしていきます。

## 認証とユーザ管理
Rakuten Rapid APIはユーザとAPIの中間にあるプロキシサーバの役割を担います。Rakuten Rapid API上で認証やユーザ管理を行うため、ほぼAPIプロバイダは実装をすることなく認証やユーザ管理の仕組みを導入できます。

![](https://i.imgur.com/YHY8ZVR.png)

![](https://i.imgur.com/pcil54t.png)

ユーザがリクエストを行うのに必要なAPIキー「X-RapidAPI-key」の管理や、リクエストが不正なものでないことを判断する「X-RapidAPI-Proxy-Secret」を利用できます。

[Cloud Endpoints](https://cloud.google.com/endpoints?hl=ja)のような細かな構成を実現することはできませんが、APIキーを用いたユーザ認証をしたいだけの場合など、要件が絞られていれば手軽に利用ができてとても便利です。

## リクエスト管理
![](https://i.imgur.com/psrgQba.png)

エンドポイントごとのリクエストの管理（制限）が可能です。
例えば、１日に何回までリクエストが可能かどうかなどを設定できます。

## マネタイズ
![](https://i.imgur.com/bjHwl8M.png)

リクエスト数に応じたマネタイズを設定可能です。月別、日別に設定ができます。


## 脅威防止
脅威防止として、SQL,Javascriptインジェクション攻撃のブロックや、Content-Typeヘッダーを指定しないリクエストのブロックを行ってくれます。

![](https://i.imgur.com/6iypzVN.png)

## 露出
APIを登録するとRakuten Rapid APIのサイト上で検索ができるようになります。
最適化をしておけばAPIを利用したい開発者へのリーチができそうです。

![](https://i.imgur.com/BqZHCEZ.png)


# まとめ
今回、公開したAPIは[こちら](https://api.rakuten.net/masan580/api/chaplus-api/details)です。

難しい作業なく、認証やリクエストの管理、マネタイズ、露出までを行うことができるので、APIプロバイダにとって非常に役立つサービスだと感じました。APIを提供したいと考えている方は利用を検討してみると良いかもしれません。
[gem][bundler]古いbundler を使用する bundle _1.17.3_ install でエラー 解決法




# 問題
`bundle install` 実行のbundler をダウングレードしたい。
(Gemfile で指定の各gemの bundler依存関係のため):


Mac で `gem install bundler` で入れる bundler が最新のもの(例えば 2.1.4) になり
そのまま`bundle install` だと通らない。

```
$ bundle install
Error:
Bundler could not find compatible versions for gem "bundler":
...
 Current Bundler version:
    bundler (2.1.4)
```

じゃあ bundler をダウングレード
`gem install bundler -v 1.17.3`
`gem install bundler:1.17.3 --default` などと
とversion 指定にしてインストールして
 `bundle _1.17.3_ install`
としてversion 指定の実行 でもなぜかエラー

```
$ bundle _1.17.3_ install
...
could not load such file
...
```



# 解決法

gem 自体をupgrade すれば
問題解決できた。

`gem update --system` でうまくいかなかったので
`gem install rubygems-update`


```
$ gem -v
2.x.x
$ gem install rubygems-update
$ update_rubygems
$ gem -v
3.1.4
```

で

```
$ bundle _1.17.3_ install
...
Bundle complete! ...
```

## 環境
MacOSX 10.10.5
ruby 2.5.8
rails 4.2.11.3



# 参考

https://makandracards.com/makandra/9741-run-specific-version-of-bundler

https://stackoverflow.com/questions/37149483/difference-between-update-rubygems-and-gem-update-system

https://stackoverflow.com/questions/57306611/how-can-i-remove-default-version-of-bundler
【Auth0】特定のアプリケーションにのみ多要素認証を必須にする

# はじめに
Rulesを使って特定のアプリケーションのみAuth0の多要素認証を有効にしてみます。

# 通常の多要素認証の設定
多要素認証の有効化は通常`Multi-factor Authentication`のページから行います。

![スクリーンショット 2020-06-29 17.34.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653972/0cd0bfc9-e057-96fc-1634-f6bfce8125d2.png)

多要素認証で利用する要素を選択して`Requere Multi-factor Auth`の項目を`Always`にすると全てのアプリケーションで多要素認証が有効化されます。

![スクリーンショット 2020-06-29 17.38.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653972/eef40332-0a27-6587-cf13-060afd73c280.png)

# Rulesを使って多要素認証が必須のアプリケーションを絞る
`Multi-factor Authentication`のページで多要素認証で利用する要素の選択まで行い
`Requere Multi-factor Auth`の設定は行わずにRulesを使うことで一部のアプリケーションだけ多要素認証を有効化することができます。

![スクリーンショット 2020-06-29 17.36.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653972/9180aae6-a896-a94f-2959-bebc9f24c926.png)

`CREATE RULE`を押して以下のコードを新しいRuleとして登録します。
コード内の`CLIENTS_WITH_MFA`配列に多要素認証を有効化したいクライアントのIDを設定してください。

```javascript
function (user, context, callback) {

	const CLIENTS_WITH_MFA = [
    // 多要素認証を有効化するアプリケーションのクライアントIDを並べる
    'Client_ID_1',
    'Client_ID_2'
  ];

  if (CLIENTS_WITH_MFA.includes(context.clientID)) {
    context.multifactor = {
      provider: 'any',
      allowRememberBrowser: true
    };
  }

  callback(null, user, context);
}
```

このRuleを有効にすると`CLIENTS_WITH_MFA`配列に含まれているクライアントIDのアプリケーションにログインするときだけ多要素認証が必要になります。

# おわりに
Rulesを活用して多要素認証のON/OFFをアプリケーションごとに設定してみました。
アプリケーションごとに認証強度を分けると言った要件がある場合に有効な手段なので試してみてください。
ChromeでSafari Books Onlineを翻訳したまま読み進めるためのブックマークレット

# こちらのブックマークレットは使えなくなりました＆不要になりました。
本家がGoogle翻訳後のHTMLでも次へボタンが効くようになりました。

# Safari Books Onlineについて
オライリーの本をおそらくすべて読めるし、翻訳されたような洋書はだいたい読める。
Effective Java,ドメイン駆動設計,人月の神話,Clean Architectureなど、とにかくなんでもある。

何がすごいかというと、**HTML形式で提供されるのでGoogle翻訳が効く**ということ。

# 紹介記事
* [Safari Books Onlineは英語が少しでもできるなら今すぐ登録すべき](https://qiita.com/wildmouse/items/51416c27ee27e4d566dd)  
* [3年間悩み続けてようやく利用開始したSafari Books Onlineが最高だった件](https://shinharad.hateblo.jp/entry/2019/02/22/205457)

# 利用の手引
[2018-08-02ACM Professional Membershipの登録](https://agnozingdays.hatenablog.com/entry/2018/08/02/235021)

ACMの会員になると99＄で利用できるとのこと。  
私はなにを間違えたかもっと昔に300ドルくらいで契約して更新解除忘れて継続中。
こちらの方のブログ自体も必見だったりする。

[ACM会員特典](https://www.acm.org/membership/membership-benefits)
ACMの[FAQ](https://learning.acm.org/faq/oreilly-faqs)も気になれば読んだほうが良いかも。

# 本題
Chromeの日本語訳をONにしたままだと、次へ、戻るが効かない！
そこで、ブックマークレットを利用して、「次へ」と「戻る」を有効化。
以下をそのままプックマークのURL欄へ登録すれば、Safari Books Onlineのページで翻訳したまま読み進められる。

# 次へ
```javascript
javascript:(function(){window.location.href=document.getElementsByClassName('next nav-link')[0]}())
```

# 戻る
```javascript
javascript:(function(){window.location.href=document.getElementsByClassName('prev nav-link')[0]}())
```
【PHP】Cloud9で$_SESSIONが反映されなかったときの対処法

#はじめに
 学習記録のアウトプット・自分自身の備忘録として書いた記事です。
 今回はPHPのセッションがうまくいかなかったためその概要と解決方法についてメモしていきます。

#やりたかったこと
以下のように設定した```$_SESSION['$csrfToken']```をページ遷移後に反映したい。

```php
$csrfToken = bin2hex(random_bytes(32));
$_SESSION['$csrfToken'] = $csrfToken;
```


#トラブルの症状
ページ遷移後に```$_SESSION```が記録されていませんでした。


#セッションファイルの出力先を指定する。
（これは必要ではないかもしれませんが念のため。）
Cloud9はそもそもデフォルトではphp5.6のため
```random_bytes```は使えません。
そのためphp7.2をyumでインストール。


この状態でphpinfo() を実行すると、session.save_pathの右カラムはno valueになっています。
デフォルトのセッションファイルの格納先が特に指定されていなかったため```/etc/php.ini```で

```php.ini
; RPM note : session directory must be owned by process owner
; for mod_php, see /etc/httpd/conf.d/php.conf
; for php-fpm, see /etc/php-fpm.d/*conf
; session.save_path = "/tmp"
```
↓";"を外す。

```php.ini
; RPM note : session directory must be owned by process owner
; for mod_php, see /etc/httpd/conf.d/php.conf
; for php-fpm, see /etc/php-fpm.d/*conf
session.save_path = "/tmp"
```
変更後デバックしてみて以下が作成されていることを確認。
``` /tmp/sess_* ```



#session_start()の書く位置
```php
<?php
session_start();
```
と```<?php```直下に書く必要があります。
尚且つ```$_SESSION```の直前ではなく、一番最初のphpタグの直下です。。。

#参考
https://note.kiriukun.com/entry/20191125-session-not-working-in-php#file
How to adopt Sentry to Laravel 6 with user context

## Check your Laravel version before get started.

```
$ php artisan --version
```

## Installation Sentry 

```
$ composer require sentry/sentry-laravel:1.8.0
```

### Adding sentry DSN on your env

```bash:.env
SENTRY_LARAVEL_DSN=https://[YOUR_URL]        
```

### Make config file for Sentry

```
$ touch config/sentry.php
```

```php:config/sentry.php
<?php
return array(
    'dsn' => env('SENTRY_LARAVEL_DSN'),
    'breadcrumbs.sql_bindings' => true,
    'send_default_pii' => true
);
```

### Modify your Hander file

```php:app/Exceptions/Handler.php
     public function report(Exception $exception)
     {
+        if (app()->bound('sentry') && $this->shouldReport($exception)) {
+            app('sentry')->captureException($exception);
+        }
+
         parent::report($exception);
     }
```


## Adding user context

```
$ php artisan make:middleware SentryContext
```

```php:app/Http/Middleware/SentryContext.php
<?php
namespace App\Http\Middleware;
 
use Closure;
use Sentry\State\Scope;
 
class SentryContext
{
    /** 
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {   
        if (auth()->check() && app()->bound('sentry')) {
            \Sentry\configureScope(function (Scope $scope): void {
                $scope->setUser([
                    'id' => auth()->user()->id,
                    // since email is sensitive information, be careful to handle it.
                    //'email' => auth()->user()->email,
                ]); 
            }); 
        }   
 
        return $next($request);
    } 
}
```

```php:app/Http/Kernel.php
    protected $routeMiddleware = [ 
        ...
+       'sentry.context' => \App\Http\Middleware\SentryContext::class
    ];  
```

### Adding group on route

```php:route/web.php
Route::middleware(['sentry.context'])->group(function () {
    Route::get('/', 'ToppageController@index')->name('home');
    // or page as you like
}); 
```

![Artboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256447/34622773-1671-9763-4077-f446dc9b75fb.png)
SEOの観点から見たlinkタグのrel属性一覧とその用途

# 目的

本稿は、プロジェクトで `dns-prefetch` を使用しているメンバがいた為、
今後の知見のために、上記についてまとめることで今後自身で対応する際に
調べる時間を減らすことを目的とする。

＃ どうせならば `dns-prefetch` 以外rel属性もまとめることで、
＃ 関連付けて覚えてしまおうという魂胆からプロジェクトで頻出度
＃ が高いrel属性も記載する。

# rel属性とは

自分のページと外部ページやファイルを関連づけるlinkタグの属性
であり、href属性で記載したURLとの関係性を表す属性である。

＃ linkタグは `<HEAD>～</HEAD>` 間で使用


# rel属性一覧

rel属性は複数あり、その一覧を以下に記載する。

* href先との関係性を検索エンジンに示す
* リソースをバックグラウンドで先に読み込む

＃ 随時追加予定


### href先との関係性を検索エンジンに示す

**▼ 使用例**

```html
<link rel="canonical" href="https://sample.co.jp">
```

検索エンジンに対してhrefで記載したURLが正規のURLであることを示す。

内容が同じなのにURLに差異があると、検索エンジンに別のページだと見なされる
可能性がある。その場合、評価が分散し、結果的にページの評価が下がってしまう。

＃ 同ページに`https://sample.co.jp` と `https://sample.co.jp/` 
＃ をhrefに記載している場合など。

そのため `canonical` を設定することでページの評価分散を避ける。



### リソースをバックグラウンドで先に読み込む

hrefで記載したリソースを事前に読み込んでおくことで、
ページ遷移時のパフォーマンスを向上させる（`Resouce Hints`）。

また `Resouce Hints` は以下で構成されており、各説明は以降で記載する。

* dns-prefetch
* preconnect
* prefetch  
* prerender


#### ■ dns-prefetch

**▼ 使用例**

```html
<link rel=”dns-prefetch” href=”//sample.co.jp”>
```

外部サイトから通信を確立する際に、事前に名前解決
を行うことで遷移時の処理を省略することが出来る。

#### ■ preconnect

**▼ 使用例**

```html
<link rel=”preconnect” href=”//sample.co.jp”>
```

TCP three-way handshaking[^1]や SSL/TLS session negotiation[^2]を事前に処理する。

#### ■ prefetch

**▼ 使用例**

```html
<link rel=”prefetch” href=”/sample.js” as="script">
```

リソースを予めキャッシュに格納する。

`dns-prefetch` や `preconnect` と違い、通信の確立ではなく画像のような
リソースを取得する際に使用する。また、`as属性` で取得するリソースの種類
を指定することで、ブラウザ側が最適なプロセスでリソースを取得可能となる。

＃ リソースのサイズが大きいまたはネットワーク速度が遅い場合は行わない。


#### ■ prerender

**▼ 使用例**

```html
<link rel=”prerender” href=”//sample.co.jp”>
```

`prefetch` のようなリソースのダウンロードだけでなく、リンク先のDOM構築や
JavaScriptの実行まで行う。CSSやJavaScriptが実行されることで、遷移した際はレン
ダリングが完了している状態となる。

＃ アクセス前なのにCSSのアニメーションが動作するといった事象が発生する。
＃ その場合、Page Visibility API などで対策する必要がある。
＃ 複数指定は不可。


# 参照URL

* https://blog.members.co.jp/article/33474
* https://itomakihitode.jp/term/?p=dns_prefetch
* https://webtan.impress.co.jp/e/2017/02/20/24816
* https://saruwakakun.com/html-css/basic/link-rel#section3 

[^1]: データ転送を行う前にコネクションの確立を行うこと。
[^2]: 暗号化した通信路上でHTTPプロトコルを利用すること。
Githubのチーム開発基本パターン

# Githubのチーム開発基本パターン

Githubのチーム開発に慣れていなかった頃はやり方を基本パターンで覚えて、コンフリクトなどイレギュラーな事態が起きたら調べたりチーム同士で確認していました。
その時の自分なりの基本パターンです。
すでにリモートに共同開発用のリポジトリがあることが前提です。

```
1.新規ブランチをマスターの内容を継承して作成(必要に応じて)
git checkout -b

2.変更内容をステージに上げる
git add .

3.コメントつけてコミット
git commit -m '○×△◻︎(変更内容がわかりやすいものを英文で)'

4.リモートにプッシュ
git push origin HEAD
```
ここまでが自分、並びに紐づいた相手のリモートに上げる方法

次は相手のリモートからマスターを持ってきて自分のローカルのマスターに内容を反映させる方法。

```
5.自分のブランチをマスターにする
git checkout master

6.どこがリモートかチェック、(upstreamを見る。)
git remote -v

7.リモートのマスターから情報を取得してそれをローカルのマスターに反映させる
git pull upstream master

8.トピックブランチに切り替えて

9.マスターをトピックに反映
git merge master

/////
もしくは
7.の段階。マスターの状態で切り替えて適当なブランチを作ってそこにマスターの情報を逃す。
そしてそれからそのブランチをトピックに反映させる。
/////

リモートにマージ後↓

10.ローカルのマスターに切り替える
git checkout master

11.自分のローカルを最新に
git pull upstream master
```
筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (17)

前回
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (16)](https://qiita.com/legacyworld/items/359eeb33722156442f66)
https://github.com/legacyworld/sklearn-basic

# 課題 8.7 主成分分析の例
Youtubeでの解説：第9回(1) 30分あたり
課題 8.3はCluster3をうまく再現できなかったので諦めた。

いつものアヤメデータを主成分分析する問題。
プログラムとしてはscikit-learnは簡単。グラフの部分だけpandasのscatter_matrixを使うのが今までと少し違うだけ。

```python:Homework_8.7.py
# 課題 8.7 主成分分析の例
# Youtubeでの解説：第9回(1) 30  分あたり
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris  
from sklearn.decomposition import PCA

iris = load_iris()
pca = PCA()
X = iris['data']
y = iris['target']
# 主成分分析
pca.fit(X)
transformed = pca.fit_transform(X)
# 寄与率
print(pca.explained_variance_ratio_)
# 描画
fig, ax = plt.subplots()
iris_dataframe = pd.DataFrame(transformed, columns=[0,1,2,3])
Axes = pd.plotting.scatter_matrix(iris_dataframe, c=y, figsize=(50, 50),ax=ax)
plt.savefig("8.7.png")
```

寄与率

```
[0.92461872 0.05306648 0.01710261 0.00521218]
```
グラフ
![8.7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629456/85cc0d70-165d-cd03-2206-a712cf28b95a.png)

第一主成分の寄与率が0.92で、グラフを見ても左端（第一主成分）はクリアに分かれているのがわかる。
なのでsetosaの分類器は第一主成分だけで92.5%分類出来て、4成分にしてもさして上がらないので、第一主成分だけで良いということ。

# 過去の投稿
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (1)](https://qiita.com/legacyworld/items/a3763760e65774dc0e33)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (2)](https://qiita.com/legacyworld/items/5a72c83860c1d0b1d352)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (3)](https://qiita.com/legacyworld/items/c9cd7865efb343c42e5e)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (4)](https://qiita.com/legacyworld/items/9231c44206c8f0823ff5)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (5)](https://qiita.com/legacyworld/items/2d2db10024d7dfb5f89b)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (6)](https://qiita.com/legacyworld/items/e54c664fc138b75dd166)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (7) 最急降下法を自作](https://qiita.com/legacyworld/items/bdbb0cbdc5b9b33fd1eb)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (8) 確率的最急降下法を自作](https://qiita.com/legacyworld/items/663fcd8189f0bdf38f64)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (9)](https://qiita.com/legacyworld/items/8da3476d40f9861a38e4)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (10)](https://qiita.com/legacyworld/items/4f2656e994fdbbfa44fc)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (11)](https://qiita.com/legacyworld/items/c3890ab296f3b4f0918d)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (12)](https://qiita.com/legacyworld/items/9f3c14931acd8d22ae39)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (13)](https://qiita.com/legacyworld/items/784d362cdf6c513d28b6)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (14)](https://qiita.com/legacyworld/items/d8274455667555248353)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (15)](https://qiita.com/legacyworld/items/fe25581b5b560d54767d)
https://github.com/legacyworld/sklearn-basic
https://ocw.tsukuba.ac.jp/course/systeminformation/machine_learning/
PythonAnywhereでFlaskアプリをLaunchする

## はじめに

この記事は、自身で製作しWeb公開にまで至ったボートレース３連単予測サイト「[きょう、ていの良い予想は当たるだろうか](https://www.pythonanywhere.com/user/YouHaveNiceBoat/webapps/#tab_id_youhaveniceboat_pythonanywhere_com)」の内部コード解説となります。今回はFlaskでつくったWebアプリケーションを実際にWeb Launchした流れをまとめます。

Flaskアプリの作成であったり、そのほかの情報は[こちら](https://qiita.com/NGOhiroshi/items/7bcbf01df7c32c93d655)をご覧ください。

## PythonAnywhere、こんな方には向いているかも！
以下のような方は、PythonAnywhereの検討をする価値ありです！

* Flaskで自作アプリをつくって、Localで動かせるようにはなったけども..この後、どうしたらいいんだろう？
* サーバー借りるといっても、いきなりお金かけるのも嫌だし、そもそもサーバーの設定などわからないことだらけ。。
* 自作Flaskを全世界の人に使ってみてもらいたい！

私自身、元々この方面はズブの素人だったため、どうしたもんか困っていましたが、PythonAnywhereで簡単に解決しました..!!

## 公開までの手順

* **まずはアカウントを作成しましょう→　[公式サイト](https://www.pythonanywhere.com)**

"Start running.."を押して、"Free.."を選びます。後は流れに従ってアカウント登録。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/b1251522-f441-37a9-d33d-34eceaf6d69e.png)
<img width="775" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/95360d04-452e-161e-9bb3-80a77236ab3c.png">

* **Usernameがそのままドメイン名になるので、名前選びには気をつけましょう**

<img width="547" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/2a008f11-ebae-fe77-8284-0751facb0533.png">

* **アカウントができたらLoginし、Webタブから"Add a new web app"をクリック**

<img width="793" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/9a25fc01-1731-640d-43dc-cf7f0c8d45e0.png">

* **その後は、流れに従って使用するWebフレームワークとして"Flask", Python環境は"Python 3.7"を指定しました。**

*※こちらはお使いのWebフレームワークやPythonのVersionに応じて選択ください。スナップショットを撮り忘れました..。。*

* **Webの立ち上げが完了したら、mysite以下のフォルダ＆ファイル構成をご自身のLocalの構成と同じにしていきます。**

私は素人らしく、愚直に手で保存していきました。。gitとか使えるとだいぶスマートにできそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/5c197c13-c237-8346-313f-5347ea3b14b1.png)

* **できあがったらWebタブにて、Reloadしusername.pythonanywhere.comをクリック！！**
<img width="862" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/550ae9fc-8831-8766-66bf-ce37fcf308cf.png">

* **できあがり！**

こんな簡単でいいんだ..!!
<img width="916" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/a653160f-03ca-73c7-68c2-9eea3de40c16.png">


## 気をつけること

* 黄色いボタンを押さないと、三ヶ月で失効する。

定期的に押しましょう。
<img width="814" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/6dc00fc4-f5a0-1e7d-be9b-f1ec3198c410.png">

* Webタブの下の方にhttpsの設定があるの、これをEnableに変更しReloadするとhttps://...となります。

<img width="789" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/1630bacd-39de-a415-323f-ad2714e379c2.png">

↓謎の感動
<img width="494" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635959/2e05b65f-fd98-4b06-ff1b-0d5c1f8dffd4.png">


## 感想

これまでWebサーバー借りたことないし、仕組みがよくわからない、、といった人にはかなりオススメかもしれません！！
簡単にネット上で公開でき、世界が広がるような経験を得られるかもしれないです！
Localで眠っているFlaskアプリを是非、PythonAnywhereでLaunchしてみてはいかがですか？
Goのはじめかた

# はじめに
この記事ではローカルにGoの環境を構築しHello Worldを表示するまでのメモを記載してます。
数年サーバサイドはPHPを触っていて、静的言語には無縁でしたがそろそろPHP以外の言語にチャレンジしてみたいというところと、あまり趣味がないの始めてみることにしました。

# 環境
MacOS 10.15
Go1.14.4
Homebrew 2.4.2

# Go Install
インストールはHomebrewを使えば非常にシンプルです。

```
$ brew update
$ brew install go
```
インストールされているかversionを表示させ確認しましょう。

```
$ go version
```
# コード実行
コード実行も非常に簡単です。
まずgoファイルを作成します。

```
$ touch main.go
```

その後以下を`main.go`に記載します。

```go
package main

import "fmt"

func main() {
  fmt.Println("HelloWorld")
}
```

こちらで最低限必要なコードは記述できました。
続いて実行ですが2パターン選択肢があります。

```
// run
go run main.go

// build
go build main.go
./main
```

Goはコンパイラ言語のため実行都度コンパイルし実行する必要があります。それがbuildのパターンです。
一度`go build`でビルド後、直下のファイルを指定し実行します。
もう一つが`go run`のパターンです。
毎回ビルドするのはとても手間がかかるのでビルド+実行を同時に行ってくれる優れものです。

それぞれ試してみましょう,`HelloWorld`と値が出力されれば成功です。

# 最後に
いかがだったでしょうか？非常に簡単に実行できたと思います。
案件数の兼ね合い等もあり、0からエンジニアを目指す方にはあまりオススメできないかもしれませんが、既にバックエンドエンジニアとして就業され、PHP,Rudyの次に学ぶ言語としてはとても良いのかなと考えております。

あと`Go 〇〇`で検索しても全然ヒットしないですね笑
[Mac][Ruby][Rbenv]rbenv install 2.x.x が通らない エラー 解決法




# 起こった問題
`rbenv` を使ってruby の古いversion (2.0.0-p648など)をインストールしようとするも
通らない。


## 環境
MacOSX 10.10.5



```
$ rbenv install 2.0.0-p648
...
Build Failed..

(log が消えてしまったので、ざっくりとだけ。。)
```

以下試した。が通らず。

```
$ env CFLAGS='-march=corei7-avx -O2 -pipe' RUBY_CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline`" rbenv install -v 2.0.0-p648
.. error

$ RUBY_CONFIGURE_OPTS="--with-openssl-dir=`brew --prefix openssl` --with-readline-dir=`brew --prefix readline`" rbenv install -v 
... error
```


# 解決法
結果 `brew upgrade ruby-build` して、
`CC=gcc` (新しいversion)を指定すれば通った。(これで他のversion の `rbenv install` も通った。)

```
$ brew upgrade ruby-build

$ CC=$(which gcc-9) rbenv install -v 2.0.0-p648 # 新しいgcc 指定で実行
```

# 備考
以下のような変数も考慮。コンパイルに使われる `openssl` のversion, `readline` が最新かなど。

```
env CFLAGS='-march=corei7-avx -O2 -pipe' RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local/opt/openssl --with-readline-dir=`brew --prefix readline`" CC=$(which gcc-9) rbenv install -v 2.0.0-p648
```

```
$ xcode-select -p # 念のため
/Library/Developer/CommandLineTools
$ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

$ brew upgrade readline
```


# 参考
Unable to install Ruby 2.0.0-p648 on ubuntu 16.04
https://github.com/rbenv/ruby-build/issues/1153

https://proggy.jp/rbenv-install-error/
jquery3でtag-itが動かない

rails5でjquery3を利用していたのですが、tag-itが動きませんでした。

どうやら、jquery3からandSelf()がなくなったことが原因らしいです。
[tag-it Githubの該当issue](https://github.com/aehlke/tag-it/issues/370)
tag-it.jsのandSelf()部分をaddBack()に書き換えれば動きます。

```js:tag-it.js（）
 _create: function() {
            // for handling static scoping inside callbacks
            var that = this;

            // There are 2 kinds of DOM nodes this widget can be instantiated on:
            //     1. UL, OL, or some element containing either of these.
            //     2. INPUT, in which case 'singleField' is overridden to true,
            //        a UL is created and the INPUT is hidden.
            if (this.element.is('input')) {
                this.tagList = $('<ul></ul>').insertAfter(this.element);
                this.options.singleField = true;
                this.options.singleFieldNode = this.element;
                this.element.addClass('tagit-hidden-field');
            } else {
                this.tagList = this.element.find('ul, ol').addBack().last();#ここ！
```

ファイルの124行目に一箇所だけあります。
OSとMicrosoftの歴史みたいなスライドを作ってみた

# SlideShareにアップロードしたので下記リンク参照
https://www.slideshare.net/MasatoHanayama/oswindowsmicrosoft-238326730


## 更新履歴
<dl>
<dt>2020/08/29</dt>
<dd>コメント頂いた内容を修正。</dd>
</dl>
Rancher付属のGrafanaを有効化する

1. 対象のクラスターを選択します
2. 上部ナビゲーションの `Tools` > `Monitoring` を選択します  
   ![Screenshot from 2020-06-29 21-53-14_v2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210737/4ee8966b-371f-8d68-e2ef-d4a85bdb4966.png)

3. `Enable Node Exporter` を `True` へ変更します  
   ※ 赤枠の部分です
   ![Screenshot from 2020-06-29 21-50-08_v2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210737/7d4f08d0-2c25-53c1-2aa1-37474fbf24cd.png)

    
4. しばらくすると、ダッシュボードに __Grafana__ のアイコンが表示されます  
   ![Screenshot from 2020-06-29 22-05-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210737/cafc56c3-4e5a-b96c-8f85-ef237f695ce4.png)
MacOSで仮想環境を作るソリューションを比較してみた 

## 背景
目的：MacOS Mojave （Version 10.14）でWindowsのVMを利用したい
（最終の目的はWindowsサーバーで色々作業するため、WindowsサーバーのGUIが要る）


## 仮想環境主なソリューション
仮想化の種類は色々ありますが、今回の問題に向いてるソリューションを以下三つを考えました。
仮想化ソフトを全般的に比較したい方は、[こちら](http://changineer.info/server/virtualization/virtualization_diff.html)をご参考ください。

* クラウド型仮想デスクトップサービス
* ホストOS ＋ リモートデスクトップアプリ ＋ リモートサーバー
* 仮想マシン（ホストOS型）
 
### クラウド型仮想デスクトップサービス
#### 説明
マネージド仮想デスクトップ、DaaS（Desktop as a Services）も呼ぶ
#### 代表製品
* AWSの[Amazon Workspace](https://aws.amazon.com/jp/workspaces/)（無料枠あり）
* AzureのWindows Virtual Desktop（無料枠あり）
* IBMのVMware Horizon on IBM Cloud（無料枠なさそう）


### ホストOS ＋ リモートデスクトップアプリ ＋ リモートサーバー
#### 説明
手元のコンピュータからネットワークで接続された他のコンピューターのGUIやデスクトップ環境を操作するアプリである
#### 代表製品
* [Microsoft リモートデスクトップ](https://www.microsoft.com/ja-jp/p/microsoft-%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88-%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97/9wzdncrfj3ps?activetab=pivot:overviewtab#system-requirements)
* Chrome リモートデスクトップ

### 仮想マシン
#### 説明
土台となる既存のホストOS上、ゲストOSを実行するためのソフト
#### 代表製品
* VMware Fusion（Mac向け、無料試用あり）
* VirtualBox（サポートされるホストOSはLinux、macOS、Microsoft Windows、Solaris。無料）

## 比較
今回上記三種類のソリューションの中、それぞれ代表案を１つ選択して比較しました。

|       |       Amazon Workspace|    Microsoft リモートデスクトップ ＋ EC2(Linux+ Windows)    |Virtual Box    |
|:-----------------|------------------|:------------------|------------------|
| 概要           |    AWS のフルマネージドDaaS ソリューション |        MacからEC2 windows にリモートデスクトップ（踏み台用のサーバー経由で）接続でログイン |Oracle VM Virtual BoxでWindowsサーバーを動かせる
| 実装の容易さ          |数十分掛かる | 数十分掛かる|2時間以上掛かる
| ロカールへの影響  | - クライエントインストールには118MB必要 <br> - 運用時ロカール PCにほぼ負担掛からない | - アプリインストールには42.72 MB必要<br> - ロカール PCにほぼ負担掛からない| - 少なくとも４GBのメモリが要る <br> - ８GBのPCの場合、ほぼ他の作業は同時実施できない
| 費用              | - 最初の月２Bundleまで40時間の無料利用 <br> - その後の課金方法は月額料金と時間料金二種類がある | - リモートデスクトップは無料 <br> - EC2 Linuxサーバーの料金とEC2 Windowsサーバーの料金はインスタンスタイプにより異なる      |無料
| 運用             |  - CloudWatchでモニタリング <br> - WorkDocsでファイル共有<br>（Workspaceユーザーの場合50GBまで無料） |     - CloudWatchでEC2インスタンスをモニタリング <br> -ファイル共有にはリモートデスクトップを使用 <br> - IAM設定やシークレット管理が必要    |VirtualBox Mangerでファイル共有やログ記録|

### 各ソリューションのセットアップ手順

#### Amazon Workspace
* Workspaceに利用するBundleを選択
* Workspaceクライエントをインストール
* Workspace クライエントを起動
* （オプション）ファイル共有用のWorkdocsをインストール

#### Microsoft リモートデスクトップ ＋ EC2(Linux+ Windows)
* Microsoft リモートデスクトップのインストール
* EC2で踏み台用Linuxサーバーをパブリックサブネットに、Windowsサーバーをプライベートサブネットにセットアップ
    * EC2のIAM権限をAdministratorAccessに設定したことは前提
    * セキュリティ上の理由で踏み台用サーバーが必要
* 踏み台用サーバーとWindowsサーバーの接続ため、キーペアの用意
* 踏み台用サーバーからリモートデスクトップと接続
* ファイアウォールの設定

#### Virtual Box
* 仮想マシン (Virtual Machine) の作成 （メモリスペーク設定が要る）
* 仮想ディスク (Virtual Disk) の作成 
* 仮想マシンの設定 
* OS のインストール 

## 参考
* http://changineer.info/server/virtualization/virtualization_diff.html
* https://thinkit.co.jp/story/2014/12/02/5456
* https://qiita.com/y-vectorfield/items/72e327d60d2806a62060
* https://qiita.com/9en/items/f4eab2f61485a9f3885a
* http://blog.serverworks.co.jp/tech/2020/01/17/post-78056/
HTML DJANGOのデータベース更新

このような形でvieww.pyからgoodの数をデータベースから引っ張ってきて数を＋1させて表示させたいのですが、うまくできません。どこが間違っているのでしょうか、、。😭よろしくお願いいたします。

    def good(self, pk):
        smart = Smart.objects.get(pk=pk)
        smart.good = smart.good + 1
        smart.save()
オブジェクトのプロパティを全てreadonlyにする

こちらの記事を閲覧し、再帰いけるやん！と思い作りました。
https://qiita.com/suin/items/c462533f5d110577eb92

# 先に成果物

```typescript
type Freeze<T extends object> = {
  readonly [P in keyof T]: T[P] extends object ? Freeze<T[P]> : T[P];
};
```

## これなんですか

これは、オブジェクトのプロパティを `readonly` にして、さらにそれがオブジェクトならその中まで `readonly` にしていくものです。
とりあえず `Freeze<T>` と名付けました。

## なにしているんですか

以下を紹介します。

1. `<T extends object>`
1. `[P in keyof T]`
1. `T[P] extends object ? Freeze<T[P]> : T[P]`

### `<T extends object>`
この `Freeze<T>` の対象となる型を指定しています。言い換えると `T` はオブジェクト型である必要があり、プリミティブ型を受け付けません。

### `[P in keyof T]`
`keyof T` はそのオブジェクトのキーを `Union types` で返却してくれるものです。

例

```typescript

type Zoo = {
  gorilla: unknown;
  giraffe: unknown;
  panda: unknown;
};

type Animals = keyof Zoo;
// 'gorilla' | 'giraffe' | 'panda'
```

そして `[P in]` はその `Union types` のどれかをキーとして持つオブジェクト、ということを意味します。

### `T[P] extends object ? Freeze<T[P]> : T[P]`

`T[P]` は与えられたオブジェクトのあるキーのときのプロパティです。それがオブジェクトであればまた `Freeze<T>` を適用し、そうでなければその値を返します。
ちなみにこの三項演算子なくして `Freeze<T[P]>` とすることはできません。理由は `<T extends object>` があるため `Freeze<T>` の `T` はオブジェクトである必要があるからです。

この `Type alias` のキーは `readonly` がついているので、これはそのオブジェクトがどのような構造をしていても、それをすべて `readonly` にできます。

#### 結論
`const assertion` を使うとこんなことしなくてもすぐにできる。
アルゴリズムイントロダクション第１章解答

# この記事について
この記事は、アルゴリズムイントロダクション第1巻の問題を全て解くという壮大なプロジェクトの一環です。
間違いや指摘があれば遠慮なくコメントをください！

#練習問題
## 1.1-1　
#####　ソートを必要とする実社会での応用あるいは凸包の計算を必要とする実社会での応用を説明せよ。
・勉強会のメンバーを名簿に整理するために、学年順にメンバーを並べ替える。
・物体が凸であるとは、ユーグリッド空間における物体の任意の2点を結んだ線分が、その物体内に含まれている状態のことを指す。凸集合とは、そのような物体の集合であり、凸包とは与えられた集合を含む最小の凸集合であると定義される。凸包の計算は、例えばある生物が存在する場所が座標としてわかるとき、ここからこの生物の生息範囲を調べることに利用できる。

## 1.1-2 
#####実社会の枠組みの中で用いられる計算速度以外の効率の尺度をあげよ。
　・データを伝送する速さ
　・メモリの消費量

## 1.1-3
##### 以前に見たことがあるデータ構造についてその長所と短所を述べよ。
　・連結リストは要素数の操作が用意だが、値の探索に時間がかかる

## 1.1-4
##### 上で述べた最短路問題と巡回セールスマン問題の類似点を説明せよ。また、相違点は何か。
類似点
　・どちらもグラフとしてモデル化可能
　・どちらも莫大な計算量となる
　・どちらも近似アルゴリズムが考えられており、またそれが有効である

相違点
　・最短路問題はスタートからゴールまでの最短路だが、巡回セールスマン問題はスタートからスタートに戻る最短経路を求める。
　

## 1.1-5　
#####最適解しか意味を持たない実社会の問題を示せ。また、「近似解」でも十分に意味を持つ問題を示せ。
　ソートは最適解しか意味を持たない。
　平方根の値は「近似解」でも十分に意味を持つ。

## 1.2-1
#####アプリケーション層でアルゴリズムが必要になる応用の例を挙げ、必要とされるアルゴリズムの機能を議論せよ。
　入力した文章に出現する任意の単語の出現回数を調べてくれるwebアプリがあったとする。このアプリの実現のために、文章を単語の単位まで分割する必要がある。そして、文章の個々の単語が入力の単語と一致すればカウンタを1増やし、一致しなければ何もしないといったアルゴリズムが必要である。

## 1.2-2
#####　同じ計算上で挿入ソートとマージソートの実現を比較する。サイズnの入力に対して、挿入ソートの実現には8n^2ステップかかり、一方、マージソートの実行には64nlgnステップかかるとする。挿入ソートがマージソートに勝るnを求めよ。
これは、$8n^2$が$64nlgn$より小さいnの範囲を求めることと同義。従って、次のようなプログラムを用意する。

```python3
import math

n = 2
while True:
    x = 8*n**2
    y = 64*n*math.log(n,2)
    print(x,y)
    if x > y:
        break
    else:
        n += 1
        
print(n)
```

やってることは単純です。$8n^2$と$64nlgn$に２以上の値(真数1以下は定義されていない)を代入していって、前者のほうが大きくなったら停止するだけです。

これを実行すると答え　$1< n <44$　を得ます。

## 1.2-3
####　同じ計算機上で、実行時間が100n^2のアルゴリズムが2^nのアルゴリズムより高速に実行できる最小のnを求めよ。
同様に計算して求めます。

```python3
import math

n = 2
while True:
    x = 2**n
    y = 100*n**2
    print(x,y)
    if x >= y:
        break
    else:
        n += 1
        
print(n)
```

これを実行すると $n = 15$が求めるnとなります。

#章末問題
##1-1
#####以下の表の各関数f(n)に対して、アルゴリズムが解くのにf(n)マイクロ秒かかるとき、t時間で解くことができる最大の問題サイズnを求めよ。
１マイクロ秒は$1.0×10^{-6}$秒です。この値と各関数を掛けたものが、1つの問題を解くのに必要な時間となります。つまり、$t=f(n)×1.0×10^{-6}$をnについて求める形になります。
例えば、
例１$lgn=log_2 n$の場合、
$a=1.0×10^{-6}$とし
$t = alog_2 n$
$\frac{t}{a}=log_2 n$
$({\frac{t}{a}})^2=n$
となります。
例２$\sqrt{n}$
$t = a*{\sqrt{n}}$
$\frac{t}{a}=\sqrt{n}$
$({\frac{t}{a}})^2=n$
 つまり、与えられているのは$n$についての関数なので、逆関数を求める必要があるということです。


| |1秒|1分|1時間|1日|1月|1年|1世紀|
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|  $lgn$|$10^{12}$|$10^{15.56}$|$10^{19.11}$|$10^{21.87}$|$10^{24.83}$|$10^{29.95}$|$10^{33.95}$|
|  $\sqrt{n}$|$10^{12}$|$10^{15.56}$|$10^{19.11}$|$10^{21.87}$|$10^{24.83}$|$10^{29.95}$|$10^{33.95}$|
|  $nlgn$ |
|  $n^2$  |$10^{3}$|$10^{3.89}$|$10^{4.78}$|$10^{5.47}$|$10^{6.21}$|$10^{7.49}$|$10^{8.49}$|
|  $n^3$ |$10^{2}$|$10^{2.6}$|$10^{3.19}$|$10^{3.65}$|$10^{4.14}$|$10^{5}$|$10^{5.66}$|
|  $2^n$  |19|25|31|36|41|50|56|
|  $n！$ |  |

$n!$や$nlgn$は解析的に解くことができません。従って、プログラムを使って解くことになりますが、それには天文学的な時間がかかるようです。私の頭ではここの計算方法が分かりませんでした。。。
読書メモ『自走プログラマー ~Pythonの先輩が教えるプロジェクト開発のベストプラクティス120』 

## はじめに
コードを書くだけではなくて、開発周辺の知識を得るために読みました。
個人的に参考になった部分をメモしていきます。2，4，6，などの番号は本書の目次番号です。

## 第1章 コード実装

2 関数名ではより具体的な意味の英単語を使おう
　→　参考：プログラマのためのネーミング辞書 https://codic.jp/

4 副作用のない関数にまとめる
　→　副作用とはデータが更新されることを意味する。
　　　更新系の関数でない(例えば正しいタイトルか確認する)関数ならば値を更新させないこと。

6 リストや辞書をデフォルト引数にしない
　→　その関数が使いにくくなるので、引数は単純な値にしたほうがよい。

8 インデックス番号に意味を持たせない
　→　コードが読みにくくなる。

10 コメントには「なぜ」を書く
　→　仕様はコードを読めばわかる。また、なぜこう処理しないのかを書いてもよい。

14 別メソッドに値を渡すためだけに属性を設定しない
　→　考えることや覚えることを減らせる。

16 utils.pyのような汎用的な名前を避ける
　→　クラスの意味を明確にする。


19 テストにテスト対象と同等の実装を書かない
　→　テストが同じ結果になる。文字列や数値はテスト内に直接書く。

21 テストケースは準備、実行、検証に分割しよう
　→　テストコードを読みやすくするため。（Arrange Act Assertパターンとも)

23 テストから外部環境への依存を排除しよう
　→　処理が遅い上にデータが残ってしまう。

26 テストケース毎にテストデータを用意する
　→　データの使いまわしは意図しないテストの失敗を招く。

31 過剰なmockを避ける
　→　単純なデータで確認できるならmockは使わない。

34 一度に実装する範囲を小さくしよう
　→　困難は分割せよ。

44 レビュー時間をあらかじめ見積もりに含めよう
　→　実装時間の2割をめどに。


## 第2章 モデル設計

46 マスターデータとトランザクションデータを分けよう
　→　マスターデータ・・・基礎となるデータ。商品情報や従業員情報など。
　　　トランザクションデータ・・・履歴となるデータ。購買履歴や給与支払い履歴など。

48 クエリで使いやすいテーブル設計をする
　→　正規化しすぎるとJOINしなければならず、性能が落ちてしまう。

50 一意制約をつける
　→　想定しないデータを入れないため。

51 参照頻度が低いカラムはテーブルを分ける
　→　テーブルの肥大化を防げる。

56 有意コードをなるべく定義しない
　→　有意コード・・・FD10001のようなFDが区分で10001が番号のようなコード。
　　　like検索は遅いのでなるべく使いたくない。

58 DBのスキーママイグレーションとデータマイグレーションを分ける
　→　マイグレーションは「移行」の意。
　　　どこかで処理が失敗した場合に原因の切り分けが難しくなる。

## 第3章 エラー設計

64 例外を握り潰さない
　→　例外をなかったことにして処理を続けてもどのみちどこかで処理が止まる。

71 info、errorだけでなくログレベルを使い分ける
　→　debug・・・ローカルでのみ出力
　　　info・・・挙動確認に必要な情報

74 ログファイルを管理する
　→　Unix系であれば/var/log以下にログを集約する。
　　　また、ログローテーションしてログを一定期間で圧縮する。

75 Sentryでエラーログを通知/監視する
　→　Sentryというエラートラッキングサイトがある。 https://sentry.io/welcome/

## 第4章 システム設計

79 本番環境はシンプルな仕組みで構築する
　→　便利さを求めて多機能なツールを使うと、仕組みが複雑化して運用コストがあがる。

89 ファイルをCDNから配信する
　→　CDN(Contents Delivery Network)・・・静的コンテンツを素早く配信してくれるサービスのこと。
　　　主に、AWS CloudFrontやGCP Cloud CDNなどがある。

91 時間のかかる処理は非同期化しよう
　→　リアルタイム処理が必要ない場合(メール配信等)は非同期処理する。

93 サービスマネージャーでプロセスを管理する
　→　LinuxであればSystemdで管理。

94 デーモンは自動で起動させよう
　→　Linuxであればsystemctlで自動機能の設定を。

97 バージョンをいつ上げるのか
　→　こまめに上げることで大幅な改修を減らす。

100 ファイルパスはプログラムからの相対パスで組み立てよう
　→　どこからプログラムが実行されても動くようにするため。

103 一時的な作業ファイルには絶対に競合しない名前を使う
　→　タイムスタンプでは競合する場合があるためツールを使うのが吉。

105 127.0.0.1と0.0.0.0の違い
　→　127.0.0.1はローカルループバックアドレス。そのコンピュータ内のみアクセス可。
　　　0.0.0.0はすべてのネットワークにバインドできる特別なIP。

107 リバースプロキシ
　→　ApacheやNginxなどを設置。
　　　リクエストを一旦経由させてサーバ負荷を下げたり、攻撃を軽減できる。

## 第5章 やることの明確化
112 作りたい価値から考える
　→　作ったあとに必要ないと気づく確率を減らす。
　　　参考図書：匠メソッド、リーン顧客開発、ストーリーとしての競争戦略

118 モックアップから実装までをイメージしよう
　→　実装がイメージできないときは仕様を確認する。

119 最小で実用できる部分から作ろう
　→　最小の完成形を見つければモチベーションを維持できる。

120 ストーリーが満たせるかレビューしよう
　→　モックアップが一通り揃った段階で再度レビューする。

## 感想
ソフトウェア開発の経験が浅い人は1章から順番に読めばよいし、
コードは書けるけど設計が微妙という人は5章から読めばよく、
読み手のことを考えた構成で素晴らしいと思いました。

Python特有の話はあるものの、基本的には他の言語にも応用可能です。
ソフトウェア開発の全体像を捉えたい人には最適の一冊ではないでしょうか。

『自走プログラマー ～Pythonの先輩が教えるプロジェクト開発のベストプラクティス120』
https://gihyo.jp/book/2020/978-4-297-11197-7
マッスルJavaオブジェクト指向 2日目 ~継承~

# 継承とは

- クラスの定義内容を受け継ぐこと
  - メソッド・フィールドを定義し直さなくてもそのまま使える：便利

## Javaにおける継承
- 拡張:継承したクラス(子クラス)で独自のメソッドやフィールドを追加 
- 再定義(オーバーライド):継承したクラス(子クラス)で元のメソッド・フィールドの定義を変更できる

## 継承のイメージ
- 親よりも子の方が強い
  - 亀仙人(親クラス)と弟子の悟空(子クラス)
      - 弟子の悟空は かめはめ波(親の定義をそのまま使える) ＋　3倍かめはめ波(オーバーライド)　＋　舞空術(拡張)  

## 継承の用語
- 元のクラス(継承されるクラス)
  - 親クラス 
  - スーパークラス
  - 継承元 

- 元のクラスを継承したクラス
  - 子クラス
  - サブクラス
  - 派生クラス
  - 継承クラス
  - 継承先 

##  継承のコード例：定義の仕方
- extendsキーワード
- 子クラスでは、親クラスのフィールドやメソッドを書かなくても使える
- 親クラスは１つしか指定できない

```
class 子クラス名　extends 親クラス名{

}
```

## 継承のコード例
- 親クラス

```
public class Animal{
  public void eat(String f){
    System.out.println(f+"を食べます");
  }
  public void sleep(){
    System.out.println("眠ります");
  }
  public void wakeUp(){
    System.out.println("起きます");
  }
}
```

- 子クラス
  - Birdクラスは、親クラスのAnimalクラスのsleepメソッドやwakeUpメソッドを呼び出せる
  - ①：拡張
  - ②：オーバーライド

```
public class Bird extends Animal{
  
  // ①:拡張
  public static int wing = 2;
  pulic void fly(){
    System.out.println("飛びます");
  }

  // ②:オーバーライド(上書き)
    // 親と同じメソッド名
  pulic void sleep(){
    System.out.println("木の上で眠ります");
  }
}
```
## 「super」 キーワード

- オーバーライドを行う際に、親クラスの定義を利用できる
- オーバーライドした子クラスのメソッドの中から、親クラスのメソッドやフィールドにアクセスしたいときに用いる

```
public class Bird extends Animal{

  pulic void sleep(){
    System.out.println("木の上で眠ります");
    
    // super
    super.sleep();
}
```