OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby on Rails チュートリアル(第4版)　第3章

## 3.1　演習
1.BitbucketがMarkdown記法のREADME (リスト 3.3) をHTMLとして正しく描画しているか、確認してみてください。
　省略
2.本番環境 (Heroku) のルートURLにアクセスして、デプロイが成功したかどうか確かめてみてください。
　省略

## 3.2.1 演習
1.Fooというコントローラを生成し、その中にbarとbazアクションを追加してみてください。

```
$ rails generate controller Foo bar baz
```

2.コラム 3.1で紹介したテクニックを駆使して、Fooコントローラとそれに関連するアクションを削除してみてください。

```
$ rails destroy controller Foo bar baz
```

## 3.4.2 演習
1.StaticPagesコントローラのテスト (リスト 3.24) には、いくつか繰り返しがあったことにお気づきでしょうか? 特に「Ruby on Rails Tutorial Sample App」という基本タイトルは、各テストで毎回同じ内容を書いてしまっています。そこで、setupという特別なメソッド (各テストが実行される直前で実行されるメソッド) を使って、この問題を解決したいと思います。まずは、リスト 3.30のテストが green になることを確認してみてください (リスト 3.30では、2.2.2で少し触れたインスタンス変数や文字列の式展開というテクニックを使っています。それぞれ4.4.5と4.2.2で詳しく解説するので、今はわからなくても問題ありません)。
　GREENになった

## 3.4.3 演習
1.サンプルアプリケーションにContact (問い合わせ先) ページを作成してください16 (ヒント: まずはリスト 3.15を参考にして、/static_pages/contactというURLのページに「Contact | Ruby on Rails Tutorial Sample App」というタイトルが存在するかどうかを確認するテストを最初に作成しましょう。次に、3.3.3でAboutページを作ったときのと同じように、Contactページにもリスト 3.40のコンテンツを表示してみましょう。)。

```ruby:/test/controllers/static_pages_controller_test.rb
  test "should get contact" do
    get static_pages_contact_url
    assert_response :success
    assert_select "title", "Contact | #{@base_title}"
  end
```

```ruby:/config/routes.rb
  get 'static_pages/contact'
```

```ruby:/app/controllers/static_pages_controller.rb
  def contact
  end
```

```ruby:/app/views/static_pages/contact.html.erb
  <% provide(:title, "Contact") %>
  <h1>Contact</h1>
  <p>
   Contact the Ruby on Rails Tutorial about the sample app at the
   <a href="https://railstutorial.jp/contact">contact page</a>.
  </p>

```

## 3.4.4 演習
1.リスト 3.41にrootルーティングを追加したことで、root_urlというRailsヘルパーが使えるようになりました (以前、static_pages_home_urlが使えるようになったときと同じです)。リスト 3.42のFILL_INと記された部分を置き換えて、rootルーティングのテストを書いてみてください。

```ruby:/test/controllers/static_pages_controller_test.rb
  test "should get root" do
    get root_url
    assert_response :success
  end
```

2.実はリスト 3.41のコードを書いていたので、先ほどの課題のテストは既に green になっているはずです。このような場合、テストを変更する前から成功していたのか、変更した後に成功するようになったのか、判断が難しいです。リスト 3.41のコードがテスト結果に影響を与えていることを確認するため、リスト 3.43のようにrootルーティングをコメントアウトして見て、 red になるかどうか確かめてみましょう (なおRubyのコメント機能については4.2.1で説明します)。最後に、コメントアウトした箇所を元に戻し (すなわちリスト 3.41に戻し)、テストが green になることを確認してみましょう。
　省略



## メモ
- `assert_select`メソッドでは、特定のHTMLタグが存在するかどうかをテストする (この種のアサーションメソッドはその名から「セレクタ」と呼ばれることがある)
- `provide`メソッドを使ってタイトルをページごとに変更する。
- `<%= yield %>`は、各ページの内容をレイアウトに挿入するためのもの。
- コントローラを新規作成するためのrailsコマンドは`rails generate controller ControllerName アクション名 (省略可)`。
Kotlin/Native Multiplatformプロジェクトのコンパイルエラーの解決法

# 1. キャッシュを削除する

```
$ rm -rf ~/.konan
```

# 2. OSを再起動する

以下のエラーになった時はOS再起動で直りました。

```
 * Compiler version info: Konan: 1.3.71 / Kotlin: 1.3.71
 * Output kind: LIBRARY
e: java.nio.file.ClosedFileSystemException
        at com.sun.nio.zipfs.ZipFileSystem.ensureOpen(ZipFileSystem.java:1084)
        at com.sun.nio.zipfs.ZipFileSystem.getFileAttributes(ZipFileSystem.java:316)
        at com.sun.nio.zipfs.ZipPath.getAttributes(ZipPath.java:664)
        at com.sun.nio.zipfs.ZipFileSystemProvider.readAttributes(ZipFileSystemProvider.java:294)
        at java.nio.file.Files.readAttributes(Files.java:1737)
        at java.nio.file.Files.isDirectory(Files.java:2192)
```
gitの初期設定　gitのeditorをVSCodeにする。

ターミナルに以下を入力する。
example、example@emailには、それぞれgithabで登録した名前、メールアドレスを入れる。


```ruby:qiita.rb
$ git config --global user.name "example"
$ git config --global user.email example@email
$ git config --global core.editor 'code --wait'
```

きちんと登録できたか確認するためには以下のコードを使う。
```ruby:qiita.rb
$ git config user.name
$ git config user.email 
$ git config core.editor 
```

それぞれ、名前、メールアドレス、code --waitという文字が表示されればきちんと登録されている。
IBM Cloud Container Registryのイメージプルシークレットが1つになったという話

IBM Cloud Kubernetes Serviceをオーダーすると自動的にIBM Cloud Container Registry（ICR）のイメージプルシークレットが作成されますが、かつてはICRのリージョンごとにシークレットが分かれていました。

最近（多分2020年4月頃だと思われます）、これらを統合した``all-icr-io``というシークレットができるようになりました。全リージョンのものが含まれているので、今後はそれ1つを使えばよいとのことです。

```
$ kubectl get secrets | grep icr

all-icr-io # これ
default-au-icr-io
default-de-icr-io
default-icr-io
default-jp-icr-io
default-uk-icr-io
default-us-icr-io
```

現在このシークレットがない場合は、CLIからプルシークレットの更新をすることで反映されます。

```
$ ibmcloud ks cluster pull-secret apply -c <cluster>
```

なお、コマンド実行から反映まで数分かかります。

# 参考

https://cloud.ibm.com/docs/containers?topic=containers-registry&locale=en

> **I see image pull secrets for the regional registry domains and all registry domains. Which one do I use?**
Previously, IBM Cloud Kubernetes Service created separate image pull secrets for each regional, public icr.io registry domain. Now, all the public and private icr.io registry domains for all regions are stored in a single all-icr-io image pull secret that is automatically created in the default namespace of your cluster.
>
>To let your workloads pull container images from other namespaces, you can now copy only the all-icr-io image pull secret to that namespace, and specify the all-icr-io secret in your service account or deployment. You do not need to copy the image pull secret that matches the regional registry of your image anymore.
unable to launch "/usr/bin/lxsession"  で Lubuntu にログインできない

### 症状
ログイン画面でパスワードを入力すると、以下のメッセージが表示される。
"okay" ボタンをクリックすると、ログイン画面に戻されてしまい、ログインできない。
![loginerror.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/ebd3fcba-62e3-cf62-a30f-b74b57ab22ff.png)
原因が不明だが、/usr/bin/lxsession が存在していない状態らしい。

### バージョン

```
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"
```

### 対処
1.[Ctrl] + [Alt] + [F2] を押下し、コンソール画面のモードに切り替える。
ユーザとパスワードを入力し、ログインする。

2.以下のコマンドで lxsession の再インストールを行う。

```
sudo apt-get install --reinstall lxsession
```

3.lxsession が存在していることを確認する。
※再インストール前は、/usr/bin/lxsession が消えていた
![lxsession.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/ed36cb0f-6d8c-506b-9af9-0acd3da17289.png)

4.再起動し、ログインが可能になっていることを確認する。
一応、バグとして報告がされているようですが、同じ理由で消えてしまったかどうかは不明。
https://bugs.launchpad.net/ubuntu/+source/ubiquity/+bug/1770801
今回は幸い復旧できる範囲でしたが、何れにしても突然重要なファイルが消失してしまうのは困るので何らかの備えが必要（いつも後回しになりがちですが）。
Pulseaudio上のSteam/Discord/任意のチャットでノイズが入る問題への対処

たぶんChromium系のエンジンを使っているとダメ。Electronとかもダメ。
どこのバグなのか分からないですが、以下の設定を導入してpulseaudioを再起動すると直ったので、備忘録しておきます。

調査したPulseaudioのバージョン: 13.0

以下のようにしてリングバッファのサイズを小さく変更します。

``` /etc/pulse/daemon.conf
default-fragment-size-msec = 2
```

さらに、以下のように設定を変更してタイマーベースの動作からポーリングベースへ変更します。

``` /etc/pulse/default.pa
load-module module-udev-detect tsched=0
```

設定ファイルの変更後、`pulseaudio -k`してPulseaudioを再起動します。

手元の環境ではこれで直りました。
Firebase 匿名認証でログインしたユーザーか判別する方法

#はじめに
結構便利なFirebaseの匿名認証。

匿名認証を活用したい場面としては[こちら](https://qiita.com/xkent/items/ddfaf68f4f7a3bec420c)の記事の通りで、**ログイン機能を持たせる必要がないアプリでも、データベースのセキュリティは安全に保つ必要がある。**

[JavaScript を使用して Firebase 匿名認証を行う  |  Firebase](https://firebase.google.com/docs/auth/web/anonymous-auth?hl=ja)
>アプリに登録していないユーザーが、セキュリティ ルールで保護されているデータを使用できるようになります。

しかし、アプリによっては匿名認証でログインしたユーザーと、普通にメアドとかでログインしたユーザーが混在する場合がある。

色々と検索してみたが、**Firebase側で「匿名認証ユーザー or 認証ユーザー」を判別する関数が用意されていないっぽい**（知っている人いたら教えてください！！:sweat:）ので、無理やり判別してみた。。

#環境
Ionic + Angular

プロジェクトに[AngularFire](https://github.com/angular/angularfire)が入っていること

#匿名認証でログインした場合、displayNameがない
displayName自体、Firebaseの認証で必須ではないが大体のアプリケーションでは使われているだろう。

で、当たり前だが匿名認証でログインした場合、displayNameがない。
存在するのは`uid`のみ。

これで簡単に判別できた:grinning:

```typescript:home.page.ts
import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';


@Component({
  selector: 'app-my-page',
  templateUrl: './my-page.page.html',
  styleUrls: ['./my-page.page.scss'],
})
export class MyPagePage implements OnInit {
  anoUser = false;

  constructor(
    private afAuth: AngularFireAuth,
  ) { }

  ngOnInit() {
    this.afAuth.auth.onAuthStateChanged((user) => {
      if (user.displayName != null) {
        console.log(user.displayName);
      } else {
        this.anoUser = true;
      }
    });
  }
```

```html:home.page.html
<ion-header>
  <ion-toolbar color="primary">
    <ion-title>マイページ</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content class="ion-padding">
  <div *ngIf="!anoUser; else elseBlock">
    <ion-grid>
        <ion-col size="12" size-sm="8" offset-sm="2">

          <div class="ion-text-right">普通にログインしてますね</div>
        </ion-col>
      </ion-row>
    </ion-grid>
  </div>

<ng-template #elseBlock>
  <ion-grid>
    <ion-row>
      <ion-col>
        <h2>匿名でログインしてるね</h2>
      </ion-col>
    </ion-row>
  </ion-grid>
</ng-template>
</ion-content>
```

#追記`isAnonymous`で判別できました！
@qrusadorz さん、コメントより教えていただき感謝します:relaxed:

```typescript
// 省略
isAnonymous = null;
// 省略

ngOnInit() {
    this.afAuth.auth.onAuthStateChanged((user) => {
      if (user != null) {
        this.isAnonymous = user.isAnonymous;
       // 匿名ユーザーなら「true」となる
        console.log('匿名でしょうか？ ' + this.isAnonymous);

      }
    });
  }
```

```html
 <div *ngIf="!isAnonymous; else elseBlock">
    <ion-grid>
    <ion-row>
      <ion-col>
         <h2>普通にログインしてるね</h2>
      </ion-col>
    </ion-row>
  </ion-grid>
  </div>

<ng-template #elseBlock>
  <ion-grid>
    <ion-row>
      <ion-col>
         <h2>匿名でログインしてるね</h2>
      </ion-col>
    </ion-row>
  </ion-grid>
</ng-template>
```
読書メモ_人を動かす

プログラマーの人生マニュアル『SOFT SKILLS (ソフトスキル)』の中でこの本が紹介されており、読みました。
とても興味深い本でした。人を批判したり、怒ったりするより、相手を気持ちよくさせる方が両者ともに利益になると感じました。
仕事でも活用していきたいと思います。

# PART1 人を動かす三原則
## 盗人にも五分の理を認める
### ①批判も非難もしない。苦情も言わない。
- 他人の欠点より、まず自分の欠点を改める。
- 人を非難する代わりに、相手を理解するように努める  
  
## 重要感を持たせる
### ②率直で誠実な評価を与える。
- 人は誰しも褒められたい欲求がある。
- 他人の長所を考え褒める(お世辞ではなく)

## 人の立場に身を置く
### ③強い欲求を起こさせる
- 常に相手の立場に身を置き、相手の立場から物事を考える
- まず、相手の心の中に強い欲求を起こさせること
- 素晴らしいアイデアが浮かんだときは、それを相手に思いつくように誘導して、それを自由に料理させる。

# PART2 人に好かれる六原則
##1 誠実な関心を寄せる
- 自分の事ばかりを考えるのではなく他人に興味を持つ

##2 笑顔を忘れない
- 人間は心掛けたとおりになる。(つらいときでも笑顔で)

##3 名前を覚える
- 名前は、当人にとって、最も快い、
最も大切な響きを持つ言葉であることを忘れない。

##4 聞き手に回る
下記は行わないようにする。

- 相手の話を、決して長くは聞かない
- 終始自分の事だけを長くしゃべる
- 相手が話している間に、何か意見があれば、すぐに相手の話をさえぎる
- 相手はこちらよりも頭の回転が鈍い。そんな人間のくだらないおしゃべりをいつもでも聞いている必要はない。  
  話の途中で遠慮なく口を挟む

##5 関心のありかを聞く
- 相手の関心を見抜いて話題にする(時には事前に勉強を)

##6 心からほめる
- 重要感を与える - 誠意を込めて
- 人と話をするときはその人自身のことを褒める


# PART3 人を説得する12原則
##1 議論を避ける
- ◎議論に負けてもその人の意見は変わらない
- 意見が一致する点を探せ
- 議論に唯一かつ方法として議論を避ける

##2 誤りを指摘しない
- ◎相手の意見に敬意を払い、誤りを指摘しない
- 教えないふりをして、相手に教える(誘導する)
- 自分の意見を断定的に述べない。「自分としてはこう思うのだが、～」のように始める
- 自分の判断基準でなく相手の判断基準で考える

##3 誤りを認める
- ◎自分の誤りを直ちに快く認める
- 怒ろうとしている相手に対して素直に認めることで相手は怒りの矛先を失う

##4 穏やかに話す
- 穏やかに話す
- ”バケツ1杯の苦汁よりも1滴の蜂蜜の方が多くハエが取れる”
  - もし、相手を自分の意見に賛成させたければ、まず諸君が彼の見方だと分からせること、相手の理性に訴える最善の方法である。 

##5 "YES"と答えられる問題を選ぶ
- 相手が即座に"YES"と答えられる問題を選ぶ
- 本題の前に相手に"YES"で答えられる質問を複数回行い、相手の心理を肯定的な法に持っていく

##6 しゃべらせる
- 相手にしゃべらせる
- 敵をつくりたければ、友に勝つがいい。見方をつくりたければ友に勝たせるがいい

##7 思いつかせる
- 相手に思いつかせる
- 相手の発案だと思わせて、こちらに協力させるやり方

##8 人の身になる
- 人の身になる
- 相手の立場になって物事を見極める

##9 同情を寄せる
- 相手の考えや希望に対して同情を寄せる
- 人間は誰もが同情を欲しがる
- 魔法の文句「あなたがそう思うのは、もっともです。もし、私があなただったら、やはり、そう思うでしょう。」

##10 美しい心情に呼びかける
- 人の美しい心情に呼びかける
-人間は誰でも理想主義的な傾向を持ち、自分の行為については、美しく潤色された理由をつけたがる。

##11 演出を考える
- 演出を考える
- 同じ事実を提供しても、興行的な手法には効き目ある。

##12 対抗意識を刺激する
- 対抗意識を刺激する
- 自己表現の機会を与え、優位を占めたい欲求、重要感を得たい願望、これを刺激する

# PART4 人を変える9原則

##1 まずほめる
- まずほめる。
- ネガティブなことを発言するときはまず褒める

##2 遠回しに注意を与える
- 遠回しに注意を与える。
- 直接てきではなく、間接的に伝える
- ジョニー、パパもママもお前の成績が上がって嬉しいよ。しかし、代数をもっと勉強していたら、成績はもっとあっがていたと思う  
→ そして、来学期も同じように勉強を続ければ代数だって、他の科目と同じように成績が上がると思うよ  
◎批判しないように表現を変える

##3 自分の過ちを話す
-　まず自分の誤りを話したあと相手に注意する

##4 命令をしない
- 命令をせず意見を求める
- 命令を質問の形で受け入れられ相手に創造性を働かせる

##5 顔をつぶさない
- 顔を立てる
- たとえ自分が正しく、相手が絶対に間違っていても、その顔をつぶすことは、相手の自尊心を傷づけるだけに終わる
- 人前もかまわず怒ったりしない

##6 わずかなことでもほめる
- わずかなことでも心から惜しみなくほめる
- お世辞ではなく本当のことを褒める
- 人は褒められて成長する

##7 期待をかける
- 期待をかける
- 期待をかけたとおりになろうと人は頑張る

##8 激励する
- 激励して、能力に自信を持たせる
- 短所ばかり指摘せず、長所を褒めて伸ばす

##9 喜んで協力させる
- 喜んで協力させる
- 肩書を与えることも有効
- 人を変える必要が生じた場合、次の事項を考えてみるべき
- １．誠実であれ。守れない約束はするな。自分の利益は忘れ、相手の利益だけを考えよ。
-  2．相手に期待する協力は何か、明確に把握せよ
-  3．相手の身に慣れ。相手の真の望みは何か？
-  4．あなたに協力すれば相手にどんな利益があるか？
-  5．望み通りの利益を相手に与えよ
-  6．人に物を頼む場合、その他の実が相手の利益にもなると気づくように話せ。
Kaggle~住宅価格予測②~

# はじめに
[前回](https://qiita.com/ProgramWataru/items/e556a7162f0fb5473531)、線形回帰にて実装したが今回は非線形を用いての実装してみた。

引き続きこちらの記事を参考にデータ前処理を実装した。
[「データ前処理」- Kaggle人気チュートリアル](https://qiita.com/hkthirano/items/12e046b3e02961d8460d)

# モデルを作成
① 線形回帰（LinearRegression）
② Ridge回帰（Ridge）
③ サポートベクターマシン回帰（SVR）
④ ランダムフォレスト回帰（RandomForestRegressor）
こちらの４つについてモデルを作成した。

```python
# 説明変数と目的変数
x = df_train[['OverallQual', 'YearBuilt', 'TotalBsmtSF', 'GrLivArea']]
y = df_train['SalePrice']

# モジュールをインポートする
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 訓練データとテストデータとに分ける
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
```

### 平均二乗誤差を算出する関数を作成する
```python
def calc_model(model):
    # モデルを学習させる
    model.fit(X_train, y_train)
    # X_testに対する予測値
    pred_y = model.predict(X_test)
    # 平均二乗誤差を出す
    score = mean_squared_error(y_test, pred_y)
    return score
```

####線形回帰
```python
# 線形回帰のとき
from sklearn.linear_model import LinearRegression
# モデルを構築
lr = LinearRegression()
# 平均二乗誤差を算出
lr_score = calc_model(lr)
lr_score
```
```python
# >>>出力
0.02824050462867693
```

####Ridge回帰
```python
# Ridge回帰のとき
from sklearn.linear_model import Ridge
# モデルを構築
ridge = Ridge()
# 平均二乗誤差を算出
ridge_score = calc_model(ridge)
ridge_score
```
```python
# >>>出力
0.028202963714955512
```

####サポートベクターマシン回帰
```python
# サポートベクターマシン回帰のとき
from sklearn.svm import SVR
# モデルを構築
svr = SVR()
# 平均二乗誤差を算出
svr_score = calc_model(svr)
svr_score
```
```python
# >>>出力
0.08767857928794534
```

####ランダムフォレスト回帰
```python
# ランダムフォレスト回帰のとき
from sklearn.ensemble import RandomForestRegressor
forest = RandomForestRegressor()
# 平均二乗誤差を算出
forest_score = calc_model(forest)
forest_score
```
```python
# >>>出力
0.03268455739481754
```

結果として非線形回帰の平均二乗誤差は大きく出た。


# テストデータの前処理
### 欠損値の有無
```python
# テストデータの前処理
# Idの値を抜き出す
df_test_index = df_test['Id']
# 欠損値の確認
df_test = df_test[['OverallQual', 'YearBuilt', 'TotalBsmtSF', 'GrLivArea']]
df_test.isnull().sum()
```

```python
# >>>出力
OverallQual    0
YearBuilt      0
TotalBsmtSF    1
GrLivArea      0
dtype: int64
```

TotalBsmtSFの欠損値を平均値で補完する。

```python
# 欠損値を平均値で補完する
df_test['TotalBsmtSF'] = df_test['TotalBsmtSF'].fillna(df_test['TotalBsmtSF'].mean())
# 欠損値を確認する
df_test.isnull().sum()
```

```python
# >>>出力
OverallQual    0
YearBuilt      0
TotalBsmtSF    0
GrLivArea      0
dtype: int64
```
欠損値はなくなった。

### CSVファイルへ出力
```python
# モデルを当てはめる
pred_y = ridge.predict(df_test)

# データフレームの作成
submission = pd.DataFrame({'Id': df_test_index,
                          'SalePrice': np.exp(pred_y)})
# CSVファイルに出力
submission.to_csv('submission.csv', index=False)
```

結果は、0.17184と結果は伸びず。
Ajaxについて

# 非同期通信（Ajax）
リクエスト後にレスポンスが帰ってきた際、ブラウザが再読み込みされること無く通信が行われる通信方法です。非同期通信は英語で"Asynchronous JavaScript + XML"と表現され、略してAjax（エイジャックス）と呼ばれます。
# JSON
Java Script Object Notationの略で、データ交換を行うためのデータ記述形式の一種です。Rubyのハッシュと同様、キーとバリューの組み合わせでデータを表現する形式です。!

# JSONを用いたリクエストとレスポンス
[image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/a0783b59-6755-a673-5f29-4ff23ea8d089.png)
# respond_to
Railsんpコントローラーで利用できる。リクエストがHTNLのレスポンスを求めているのかを条件分岐してくれます。
<img width="279" alt="スクリーンショット 2020-07-02 21.42.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/b99c0f13-ec91-6a5c-f6e3-ad87785d2c7c.png">
# $.ajax
jQueryで非同期通信を行うための記述です。.ajaxの部分がメソッドの呼び出しとなっています。
#  done/fail
<img width="601" alt="スクリーンショット 2020-07-02 21.47.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/592387a6-3e60-e7a8-dc76-db9752de1eed.png">

ajaxメソッドの後につけることで、非同期通信が成功した際/失敗した際に行う処理を書くことができます。両方とも、ajaxメソッドとセットとなるメソッドです。doneは通信が成功したときに、failは通信が失敗したときに動きます。
Splunk マルチバリューの外れ値を削除する

https://community.splunk.com/t5/Reporting/replacing-large-numeric-values-with-0/m-p/507054
でやったことのまとめ

#課題
```sql:multivalue.spl
| makeresults 
| eval _raw="xTemp_wl0
48
50
43
60
60
54
61
60
1161181233
43
60
49"
| multikv forceheader=1
| stats list(xTemp_wl0) as xTemp_wl0
```
| xTemp_wl0 |
|--:|
| 48<br>50<br>43<br>60<br>60<br>54<br>61<br>60<br>1161181233<br>43<br>60 <br>49 |
このような一つだけとても大きい数があるマルチバリューの平均を出したい
そのまま`avg()`すると大きな値になるので、外れ値を除外、`０`にしたい
という課題でした。
#mvmap
```sql:mvmap.spl
| makeresults 
| eval _raw="xTemp_wl0
48
50
43
60
60
54
61
60
1161181233
43
60
49"
| multikv forceheader=1
| stats list(xTemp_wl0) as xTemp_wl0
| stats avg(eval(mvmap(xTemp_wl0,if(xTemp_wl0>100,0,xTemp_wl0)))) as average
```
| average |
|--:|
| 49 |
Splunk ver 8以降でつかえる`mvmap`を使用するとこんな感じ
やってることは`eval`と`if`の評価なのでわかりやすい

https://docs.splunk.com/Documentation/Splunk/latest/SearchReference/MultivalueEvalFunctions
#rex
```sql:rex.spl
| makeresults 
| eval _raw="xTemp_wl0
48
50
43
60
60
54
61
60
1161181233
43
60
49"
| multikv forceheader=1
| stats list(xTemp_wl0) as xTemp_wl0
| rex mode=sed field=xTemp_wl0 "s/\d{3,}/0/g"
| stats avg(xTemp_wl0) as average
```
| average |
|--:|
| 49 |

`rex`はマルチバリューでも普通に使えるので、正規表現`\d{3,}`で三桁以上の数字を`0`にしている。

#まとめ

- マルチバリューには`match()`や`like()`の評価系だけでなく`rex`も使える。
- `stats`等の集計コマンドもマルチバリューを展開しなくてもそのまま計算できる。 <br> https://docs.splunk.com/Documentation/Splunk/latest/SearchReference/CommonStatsFunctions
- JSONから展開したフィールドはマルチバリューが多いので活用してください。

:sweat: 小ネタばかりだな
[Python]PylanceのVS Code拡張機能をさっそく使ってみた。

VS Codeなどで使えるPylanceという拡張機能がリリースされていたので早速使ってみました。

参考 : [型ヒントでPython開発を加速 ～Microsoft、VS Code向けの拡張機能「Pylance」を発表](https://forest.watch.impress.co.jp/docs/news/1262974.html)

# （大雑把に）どんな拡張機能？

- マイクロソフト製のPythonの拡張機能です。
- Python拡張機能に入っているようなPythonの入力補完周りが有効になります。これはまあ大半のVS Code使ってPythonのコード書いている方はPythonの拡張機能入れていらっしゃるでしょうからそこまでは大きく変わりません。
- 以前書いたPythonの型チェック用のPyrightと同じように、コードを書きつつ型のミスや補完が効きづらい箇所で型アノテーションをすることで補完が効くようになってくれます（内部でPyrightが使われています）。
    - Pyrightの記事: [入力補完を充実させ、より堅牢なPythonコードのための型アノテーションとPyright入門](https://qiita.com/simonritchie/items/7492d1c1a3c13b2f27aa)
- importが足りない箇所のエラーのチェックと、足りないimportをコードに挿入してくれる選択肢を出してくれます。
- この記事を書いている2020-07-02時点ではまだPreview版です。

# インストール方法

VS Codeの拡張機能のページでpylanceなどと検索してインストールするだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228778/3d9a6013-abcb-d826-5cf2-330ec6e99ce0.png)

ただし、私の場合はPyrightの拡張機能を事前に入れたままだったのですが、競合したのかPylanceをインストールしたらエラーが出るようになりました。Pyrightの拡張機能を無効化した後にVS Codeを再起動したらエラーが無くなりました。

# 型チェックを有効化する

デフォルトだと型チェックの機能が無効になっています。有効化するにはVS Codeの設定画面を開いて、「python.analysis.typeCheckingMode」を検索して、設定をbasicもしくはstrictに切り替えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228778/2908629d-3abd-d721-cf48-3c2ceba51e04.png)

basicは型アノテーションがしてある箇所で正しいかどうかがチェックされるといった具合の少し緩い感じのチェックのようです。

strictは型アノテーションなどがしていない箇所自体もエラーになったりするようです。最初からstrictであれば問題ありませんが、途中から型アノテーションをはじめてstrict設定をすると既存コードでエラーがたくさん出てきてちょっと辛い感じではあります:sweat:

# importエラー時に該当するimportを挿入する

Pyrightなどに無かった？機能として、Pythonコードでimportをし忘れていたといったときに、importをしてくれる機能がPylanceに追加になっています。

この機能、Pythonではない他の言語を使って仕事をしていた頃似たようなものを結構愛用していたので、使えるようになって嬉しい感じです！

importが足りないケースなどでは以下のようにVS Code上で赤い下線によるエラー表示になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228778/e0c8cb18-0f83-55f8-3e7b-431bbfed76d4.png)

その状態でカーソル位置をエラーになっている部分（画像では`np`）に合わせると、電球らしきアイコンが出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228778/96801477-3940-f4bc-d230-4e51b17e3899.png)

この状態で`Ctrl + .`を押すか、電球アイコンをクリックすると挿入するimportのリストを表示してくれます。numpyとかとやらずにnpとかでもちゃっと認識してくれるのは賢い・・・！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228778/e7867165-c6aa-a2b7-4162-2e0c683eac40.png)

該当のものを選択すると、import文が挿入されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228778/1ce17352-ef8d-83a2-3546-66a86ffa6a19.png)

また、この機能はマウスオーバー時に表示されるポップアップ上の「Quick Fix...」をクリックしても同様の機能が使えました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228778/4f745043-67c1-958f-9fc7-fe60a3deeb4c.png)
[Android]自動スクロールで手を動かすことなく実機確認を行う

一覧など、無限スクロールが存在する機能を使用するときに、実機にかかる負担をAndroidStudioのMemory Profilerで監視をし~~重箱の隅をつつく~~品質をチェックしているのだが、手で動かすのがだるい。

なので、無限スクロール自動化をしてみた。

# SampleCode

簡単にRecyclerViewのSampleコードを実装したので、こちらを使用する。
https://github.com/yamachita0109/RecyclerView

# 実際に自動scrollしてみた

下記コマンドをコマンドラインに貼り付ければOK。
もっと細かい値を指定したい場合は、[公式ドキュメント](https://developer.android.com/studio/command-line/adb?hl=ja)を参考にすること。

```
$ while [ true ]; do
adb shell input swipe 521 1540 492 432
done;
```

## デモ

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300430/f9b71546-4c14-6dd6-7911-0d075e864ea6.gif)

# まとめ

・RecyclerViewをスクラッチで実装したのは初めて、もっと美しく実装して、実サービスに耐えうる形にしたいなぁ。

・adbコマンドでなんでもことが発覚。
実機操作を記憶して、スクリプト化することもできるそうな。
ちょっと試してみようかな。

・他にもっと便利なadbコマンドの使い方がある方は是非教えてください！！
powershellでAWS S3から指定したフォルダ下のファイルを一括でダウンロードする

事前に[こちら](https://aws.amazon.com/jp/powershell/)からAWS Tools For Powershellをダウンロード、インストールする必要がある。

```powershell
$Bucket = 'バケット名'
$Prefix = '/' # / で全てのファイルをダウンロード、 '/workspace'など任意のフォルダを指定可能
$LocalFolder = 'C:/workspace/' # ダウンロード先
$AccessKey = 'アクセスキー'
$SecretKey = 'シークレットキー'
$Region = 'ap-northeast-1'
Read-S3Object -Bucket "$Bucket" -Prefix "$Prefix" -Folder "$LocalFolder" -AccessKey "$AccessKey" -SecretKey "$SecretKey" -Region "$Region"
```
MySQL: インデックスなき派生テーブルをなくしてクエリ速度を改善

# 環境

* MySQL 5.7

# インデックスなき `<derived2>`

MySQLで遅いクエリがあり、`EXPLAIN` してみると、

| table         | type | key  |
|:--------------|:-----|:-----|
| `<derived2>`  | ALL  | NULL |

と表示され、インデックスがあたっていないテーブルがありました。

**そのテーブルの行数が多かったので、結果としてクエリ速度が遅くなっていました。**

# 原因の把握

## `<derived2>` とは

上の `<derived2>` は、FROM句のサブクエリで生成された**派生テーブル (derived table)** です。

下の例だと、`t1` が派生テーブルになります。

```sql
SELECT * FROM (SELECT * FROM t1) AS derived_t1;
```

## インデックスがあたらない原因

**サブクエリ内で `GROUP BY` が用いられた場合**、生成される派生テーブルにはインデックがあたらないようです。

> The subquery for the derived table t1 can not be merged because it has a GROUP BY clause. Hence, MySQL 5.7 will materialize the result of this subquery, scan the resulting temporary table, and do primary-keys looks-up directly on the orders table.

*「[MySQL 5.7: Improved Performance of Queries with Derived Tables - MySQL Server Blog](https://mysqlserverteam.com/mysql-5-7-improved-performance-of-queries-with-derived-tables/)」より引用*

つまり次のような場合、 `derived_t1` にはインデックスはあたらない(はず)です。

```sql
SELECT price_total FROM (
  SELECT SUM(price) price_total FROM t1 
  INNER JOIN t2 ON t2.t1_id = t1.id
  GROUP BY t1.id
) AS derived_t1;
```

# 解決方法: INNER JOIN 句で `GROUP BY`

「**サブクエリ + `GROUP BY`**」が問題なので、 `GROUP BY` を INNER JOIN 句に移動させ、サブクエリをなくします。

例えば、上と同じ例を使うと、次のようなSQL文になります。

```sql
SELECT SUM(price) price_total FROM t1 
INNER JOIN (
  SELECT price, t1_id FROM t2
  GROUP BY t1_id
) t2 ON t2.t1_id = t1.id
```

これでインデックスなき派生テーブルはなくなり、クエリ速度が改善されました。

# まとめ

インデックスなき派生テーブルをなくすには、サブクエリはなくし、`GROUP BY` を INNER JOIN 句に寄せることが必要です。

# References

- [Derived Tables in MySQL 5.7 - MySQL Server Blog](https://mysqlserverteam.com/derived-tables-in-mysql-5-7/)
- [8.2.2.4 Optimizing Derived Tables and View References with Merging or Materialization - MySQL](https://dev.mysql.com/doc/refman/5.7/en/derived-table-optimization.html)
- [MySQL 5.7: Improved Performance of Queries with Derived Tables - MySQL Server Blog](https://mysqlserverteam.com/mysql-5-7-improved-performance-of-queries-with-derived-tables/)
- [Query Optimization - <Derived 2> Type: ALL, Key = NULL - StackOverflow](https://stackoverflow.com/questions/32446149/query-optimization-derived-2-type-all-key-null)
PCでは動くBootstrap4のモーダルがスマホでは動かない！

#1.なぜ動かなかったか
結論から先に書くと、**「入れ子にしていたから」**です。リスト形式のデータとそのデータに対応する削除ボタンを表示し、それぞれのデータを削除する前に確認のためのモーダルを用意していたのですが、そのモーダルが入れ子になっていたのが原因でスマホ上では動きませんでした。
若干違いますが、イメージ的には下のような感じです。

```html:index.html
<table>
  <tr>
    <td>コンテンツ</td>
    <td>削除ボタン</td>
    <div class="modal">コンテンツに対応する削除確認用モーダル<div>
  </tr>
  <!-- for文で繰り返す-->
</table>
```

#2.解決策
bodyタグを閉じる直前にモーダルを置くことで、無事動くようになりました。以下のような感じです。

```html:index.html
<body>
  <table>
    <tr>
      <td>コンテンツ</td>
      <td>削除ボタン</td>
    </tr>
    <!-- for文で繰り返す-->
  </table>

  <div class="modal">コンテンツに対応する削除確認用モーダル<div>
  <!-- for文で繰り返す-->
</body>
```
【初心者でもわかる】横並びにする3つの方法を、ナイフとフォークでやってみる

# どうも、7noteです。今回は要素を横並びにする３つの方法を説明。高級レストランのように綺麗にナイフとフォークを並べましょう。

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/abreast/
FirebaseにJavascriptのプロジェクトを追加する 

※Vue.jsを使用
#Firebase上にプロジェクト作成
####①Googleアカウントを取得しておく
####②[FirebaseHP](https://firebase.google.com)→使ってみる→プロジェクト追加
####③プロジェクト名を設定して次へ
####④hosting設定にチェックを入れる
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/583a894e-708f-7ff7-b6c2-24c9b57b2a83.png)

####⑤[Googleアナリティクス](https://marketingplatform.google.com/intl/ja/about/analytics/)を設定した場合は必要項目にチェックを入れる
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/4c45dec6-68e3-3207-643a-504c04c0b70c.png)
#アプリを追加する(SDKの追加→Firebase初期化)
####⑥追加するアプリの種類を選択(今回はウェブを選択)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/76b477c1-6211-4ecd-7412-3bd08c4e9c6c.png)
####⑦SDKを追加してFirebaseを初期化する
使ってみるをクリックするとjavascriptアプリでの実装方法が説明されているので
[モジュールバンドラを使用する](https://firebase.google.com/docs/web/setup?authuser=0#%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-%E3%83%90%E3%83%B3%E3%83%89%E3%83%A9%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B)タブを選択
※コンソールからFirebase SDK snippetをコピーするのでページだけ開いておいて次へ進む
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/7be42a3e-0b56-52c0-4e53-6fee477f444b.png)
####⑧CLIをインストール,デプロイ画面を飛ばしてコンソールへ進む
####⑨⑦で開いたページの手順を踏んでFirebaseを初期化する
まず、以下のコマンドを入力
```
$ npm init
```
```
$ npm install --save firebase
```
次にコンソールよりFirebase SDK snippetをコピー
![９.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/39fb1d8e-9b9f-4dc0-718b-1dbf08293b19.png)
![2020-07-02 (22).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/b0fbd79b-27c1-9b9e-063a-23ed17064a06.png)
main.js(ts)にFirebase SDK snippetをペーストして、
```
import firebase from 'frirebase';
```
を追記

```ts:main.ts
import * as firebase from 'firebase/app';
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import vuetify from './plugins/vuetify';


Vue.config.productionTip = false;

const firebaseConfig = {
  apiKey: 'XXX',
  authDomain: 'XXX',
  databaseURL: 'XXX.firebaseio.com',
  projectId: 'XXX',
  storageBucket: 'XXX',
  messagingSenderId: 'XXX',
  appId: 'XXX',
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

new Vue({
  router,
  store,
  vuetify,
  render: (h) => h(App),
}).$mount('#app');
```
今回はanalyticを選択していない場合は記載無し
次に以下のコマンドを入力する
```
$ npm install -g firebase-tools
```
```
$ firebase init
```
```
$ firebasedeploy
```
####※Databeseを使用する場合はコンソールで設定を済ませておく
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/1e92439b-0af6-2f3e-1162-f5e2aa608703.png)
日本で使用する場合はリージョンはasia-northeast1(東京)か2(大阪)を選択
私はよく分からず3を選択しましたが、3はソウル拠点になります←

####デプロイに成功したらコンソール→Hostingからアプリページを見ることができます
回帰の評価指標、RMSE（平均平方二乗誤差）の落とし穴！

#はじめに
　機械学習の回帰モデルの評価としてはRMSE（平均平方二乗誤差）がよく使われます。一方で、RMSEは外れ値に弱いということが紹介の中でよく書かれていますが気にせず使われている例が見られます。 
　「それじゃあ一体どれくらい弱いのか？」というのを考えることでアンチパターンとして抑えておきましょう。
　先に結論を書くと**「目安として、平均の10倍以上の値が存在する場合は気をつけて使用する必要がある。その場合は対数をとったRMSLEを使用するのが良い」**となります。

#①RMSE（平均平方二乗誤差）とはどんなもの？
まあ、名前のとおりです。誤差、つまり実際の値と予測値の差分を二乗した後に平均してルートを取るというものです。
 
```math
\textrm{RMSE} = \sqrt{\frac{1}{N}\sum_{i=1}^{N}(y_{i}-\hat{y}_{i})^{2}}
```
計算式は偏差値にかなり近くて、偏差が誤差に変わっただけです。なので上手く使えば「このモデルはだいたいこれぐらいの誤差を出すんだろうな」というイメージが作れます。
 


#②RMSEがおかしくなるときは？ 値のスケールについて。
　**RMSE**は人気があって使う人が多いですが、**外れ値が存在する場合に外れ値に値が引きずられやすい**という欠点があります。 
意外と気にしてない人が多いのではないでしょうか。
　誤差としての値しか計算に入らないので**「10を20」**と予測した場合の誤差と、**「100を110」**と予測した誤差が同じものとして評価されます。 
　また、殆ど数十くらいのデータの中に**「1,000を900」**と予測する誤差があった場合に**1つのデータだけ重要度がぜんぜん違う**という扱いとなってしまいます。 

```python
import numpy as np
a = np.array([10]*100) # 誤差10を100個用意したと仮定
print(np.sqrt((a**2).mean())) # RMSEはもちろん10
a = np.append(a, [100]*1) # 101個目に100を追加
print(np.sqrt((a**2).mean())) # RMSEは14.07まで上昇！

```
　計算の際に二乗されるので10倍のスケールの誤差は指標上の重要度は100倍となります。もし平均的な誤差の100倍もの値が存在するとしたら、その重要度は平均的な誤差10,000倍、つまり10,000レコード分にもなってしまいます。
　そして機械学習では外れ値ほど予測が難しいので、外れ値が存在する場合必然的に評価が安定しなくなります。

#　③じゃあ評価指標はどうすればよいの？
　個人的には比率として考えられる**RMSLE**もしくは**MAE**がいいかなと思っています。機械学習モデルは**まずオーダーを正しく当てる**くらいで考えておくべきなのかなと。
　**RMSLE**はRMSEの対数をとったものです。yのlogを取ることでRMSLEにできます。こうしてRMSEとして扱って最後にexpにするのが使いやすいかなと考えます。 
　**MAE**は平均する際に二乗ではなく絶対値をとったものです。こうすると誤差が増幅されることがないので外れ値に強くなります。ただ、モデル学習の際の損失係数として使いにくいです。
　もちろん**「外れ値は殆どない」「大きな値のミスが問題だ」**という場合はRMSEを使っても問題はないです。

# ④実例紹介
　最近のコンペだとProbSpaceさんの[不動産取引価格予測コンペ](https://prob.space/competitions/real_estate_2020)でRMSEが使われて、データの中に平均の100倍以上の値が紛れていて順位が大きく変動したというのがありました。[「スケールの差によってどれくらいRMSEが変化するのか分析したトピック」](https://prob.space/competitions/real_estate_2020/discussions/chun1182-Post21529374c1836d01be4c)（ログイン必要）もありますので興味があればご覧ください。
　実案件でも「RMSEは知っているけど外れ値の可能性を考えた場合にモデル評価に適切かまでは認識してなかった」というのを見たことがあります。

#結論
　結論としては**「スケールが違うデータが来る可能性がある場合はRMSEを使わない！RMSLEを使う！」**に尽きると思います。RMSEしか見ないのは、分類でAccuracyしか見ないくらい危険だと思います。
　ちなみに上で上げたProbSpaceさんの不動産価格予測コンペですが、2020年8月11日締切で[評価指標をRMSLEに変更して再度開催](https://prob.space/competitions/re_real_estate_2020)されています。前回参加した人の解法などがある状態から参加できるので初心者におすすめなコンペになっていると思います。アンチパターンの例としてあげて申し訳ない気分ですが、このように再度開いていただけるのは素晴らしく思っております。
　以上、評価指標は注意しておかないと大きな落とし穴にはまったり、逆に気をつけるだけでコンペで良い順位取れたりするので、気にしておいて損はないものだ、という話でした。
postgreslのコンテナに外から複数のコマンドを一回で

`sh -c`でヒアドキュメントを使用したコマンドを実行して実現できる。

```bash
docker-compose exec service_name sh -c "psql -U user_name -d db_name <<EOF
UPDATE table_name_1 SET hoge = 1 WHERE id = 1;
UPDATE table_name_2 SET fuga = 1 WHERE id = 2;
UPDATE table_name_3 SET piyo = 1 WHERE id = 3;
EOF"
```

[参考](https://matsuand.github.io/docs.docker.jp.onthefly/compose/reference/exec/)
爆速シリアライズSimple Binary EncodingをRustで導入

https://speice.io/2019/09/binary-format-shootout.html
このサイトによると、FlatbuffersやCap’n Protoよりも断然速いSBE(Simple Binary Encoding)というのがあるらしいので、動かしたくなった
しかし、あまりにも誰も使われなかったので、公式のRustサポートがなくなったらしい

もう少し評価されても良いコードだと思ったので、導入方法だけ書いておく
(日本で、少し流行らねえかな)

# **サンプルを動かす**
普通にgithubからcloneして、
https://github.com/real-logic/simple-binary-encoding

git checkout 23e8c16caf03d2b073bc850f37b1fb68cecbe54a

公式のRustのサポート終了したバージョンまで戻します。
ターミナルで、rootディレクトリまで行って、

./gradlew
と入力します。
(Javaを誰でもビルドできるようにするツールらしい)

次に
./gradlew generateRustCodecs
と入力します。
これで、sbe-samples/src/resources/...のxmlが、rust/car_example/src/car_example_generated_codec.rsに変換されました。
このrsファイルを使えば、依存crateがなく純粋なRustのコードだけで、SBEにシリアライズ/デシリアライズが可能になります。

# **自分のスキーマを書く**
build.gradleから、generateRustCodecsで実行される行動を変更できます
build.gradleのtaskに書いてあるdependsOnのアクションが実行されるようになってるみたいです

```groovy:build.gradle
task generateRustTest(type: JavaExec) {
    main = 'uk.co.real_logic.sbe.SbeTool'
    classpath = project(':sbe-all').sourceSets.main.runtimeClasspath
    systemProperties(
        'sbe.output.dir': 'rust/my-proj',
        'sbe.xinclude.aware': 'true',
        'sbe.target.language': 'uk.co.real_logic.sbe.generation.rust.Rust',
        'sbe.target.namespace': 'my_codec')
    args = ['mine/my-entity.xml']
}

task generateRustCodecs {
    description = 'Generate rust test codecs'
    dependsOn 'generateRustTest' // 新しく追加
    // dependsOn 'generateRustCarExample', 'generateCarExampleDataFile' // 元々の実行関数
}
```

などとします。

スキーマは、
xmlの
sbe:messageSchemaの中に書きます
以下、
xi:includeで、他の読み込むxmlを書きます
typesでエイリアスタイプを定義します
sbe:messageにそのEntityの内部変数を定義します。

# **最後に**
最近、SBEのRustのサポートは終了したのですが、現状、多言語間で通信可能な、最速に近いバイナリフォーマットっぽいので、いろいろ使い道はありそうです。Googleの、Flatbuffers, Protobufも悪くないのですが、SBEは完全に独立していて、高速に動くし、割といいのでは？と思ってます。

Rustの流行度次第では、またサポートもすぐに再開するかもなので、RustとSBEがもっと流行ればいいなと個人的に思ってます。

あと、serdeとかあるし、逆にRustのコードから、SBEのスキーマを書き出すのも普通にできそうですよね。(簡単そうならやってもいいかも)
【PHP】添字配列をarray_mergeすると、配列の連番が0からになる

###添字配列をarray_mergeすると、配列の番号が0からの連番になる

```php

// 2つの配列をarray_mergeする
$array1 = [
    '101' => 'red',
    '103' => 'yellow'
];

$array2 = [
    '100' => 'blue'
];
```
予想する返却値

```php

array(3) {
  [100]=>
  string(3) "blue"
  [101]=>
  string(6) "red"
  [103]=>
  string(4) "yellow"
}
```
実際の返却値

```php

$array_merge = array_merge($array1, $array2);

var_dump($array_merge);

// 実行結果
array(3) {
  [0]=>
  string(3) "red"
  [1]=>
  string(6) "yellow"
  [2]=>
  string(4) "blue"
}
```


###例えば
以下のような時は注意が必要です。

- 年数を配列のkeyにしている時
- 「01」や「001」のような値をkeyにしている時
 - 「10」や「100」のように桁が上がったときにバグる
cumprodとcummaxについて

#1 目的 
cumprodとcummaxの使い方例を説明します。


#2 内容

cumprod ・・・ 配列の全要素について累積積を計算します。
cummax  ・・・ 配列の全要素から最大値を取り出します。


```python:test.py
import numpy as np
import pandas as pd


dat = [
    ['2019-07-01',10],
    ['2019-07-02',12],
    ['2019-07-03',8],
    ['2019-07-04',14],
    ['2019-07-05',7],
    ['2019-07-08',3]
]
df0 = pd.DataFrame(dat,columns=["A","B"])

print(df0)

df1=df0['B'].pct_change()
df2=(1 + df1)
df3=(1 + df1).cumprod() #0番目からi番目の要素までの累積積を算出します。
df4=(1 + df1).cummax()  #0番目からi番目の要素の中で最大値を取り出します。
print(df1)
print(df2)
print(df3)
print(df4)
```

```console
<df0:基本データ>
            A   B
0  2019-07-01  10
1  2019-07-02  12
2  2019-07-03   8
3  2019-07-04  14
4  2019-07-05   7
5  2019-07-08   3

df1: (df0['B']のi番目とi-1番目の変化率を計算する)
0         NaN
1    0.200000
2   -0.333333
3    0.750000
4   -0.500000
5   -0.571429
Name: B, dtype: float64

df2: (df1+1を計算する)
0         NaN
1    1.200000
2    0.666667
3    1.750000
4    0.500000
5    0.428571
Name: B, dtype: float64

df2: (cumprod() 累積積を計算する)

0    NaN
1    1.2
2    0.8　 (=1.2×0.666667)
3    1.4   (=1.2×0.666667×1.75)
4    0.7   (=1.2×0.666667×1.75×0.5)
5    0.3   (=1.2×0.666667×1.75×0.5×0.428)
Name: B, dtype: float64

df3: (cummax() 要素の中から最大値を取り出す。)

0     NaN
1    1.20   (df2:要素1から要素1までの中での最大値)
2    1.20   (df2:要素1から要素2までの中での最大値)
3    1.75   (df2:要素1から要素3までの中での最大値)
4    1.75   (df2:要素1から要素4までの中での最大値)
5    1.75   (df2:要素1から要素5までの中での最大値)
Name: B, dtype: float64
```
FormaDesigner 作成手順 アクション設定編　2

#FormaDesigner 作成手順 アクション設定編　

##Formaのアクション設定の手順を紹介　その1

※最新バージョンのものではありませんのでご注意ください
※コラボレーションなど拡張機能はありません。あくまで標準のアクション設定手順となります。

###アクション設定とは

IMが提供するローコード,高速開発サービスのFormaDesignerに搭載されている機能。
UI操作でサーバサイドの接続や、クライアントロジックなどを操作できる。

###アクション設定の処理を実装する
※事前に前記事の[発火条件の設定](https://)を参照していただくことで
本記事がわかりやすくなる....気がする。

Formaフォーム>編集画面アクション設定>ペンマークを押下することでイベント設定画面で選択したアイテムイベントで実行する外部連携・アクションを設定するための画面が展開されます
「アクション設定」画面の内容は以下の通りです。

![image (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664173/5f4d77a0-2486-c6aa-fa01-ecedc6952991.png)


※IM社様が提供するドキュメント(https://www.intra-mart.jp/document/library/bis/public/bis_specification/texts/spec/action_setting.html) より一部抜粋

1）外部連携・アクションの対象の画面アイテムの「ラベル」、「フィールド識別ID」を表示します。
2）外部連携処理のタイミングとなる画面アイテムのイベントタイプを表示します。
3）アクション設定しているアクションの種類を表示します。
4）アクションとして設定した内容の説明を入力します。
5）2件以上の外部連携・アクションを登録している場合に、直前に実行する外部連携・アクションの処理がエラーの時に処理を続行する（次の処理を実行する）か、処理を中止するかを設定します。

+ 処理を続行する→直前の外部連携・アクションの結果に関係なく、処理を実行します。
+ 処理を中止する→直前の外部連携・アクションの結果がエラーとなった場合、処理を中止します。
+ スキップ→直前の外部連携・アクションの結果がエラーとなった場合、処理をスキップします。
6）アイコンをクリックすると、選択されたアクションに応じて、以下の設定画面に遷移します。
+ 外部連携 → 「データマッパー」画面に遷移します。
+ 入力モード変換 → 「入力モード変換設定」画面に遷移します。
+ 表示モード変換 → 「表示モード変換設定」画面に遷移します。
+ カスタムスクリプト → 「カスタムスクリプト設定」画面に遷移します。
+ 
7）アイコンをクリックすると、「条件設定」画面に遷移します。
8）アイコンをクリックすると、登録済みの外部連携・アクション設定を削除します。

####画面アイテム「ボタン」のアクション設定の発火条件について

一覧選択や日付などのテキストフィールドとアイコンを組み合わせたアイテムは発火条件なども少し異なります。
以下の表はIM社様によって提供されている一覧表です

<img width="362" alt="8C1D0C52-4DCF-42E3-A21D-A669555E0654.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664173/231a122c-6abd-d6f4-1e91-5e5f47b8ec98.jpeg">
該当の操作については[こちら](https://www.intra-mart.jp/document/library/bis/public/bis_specification/texts/spec/action_setting.html)をご覧ください
<img width="1109" alt="08D31207-8B5D-41A7-B49E-E20C8E0AFF86.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664173/e69ec231-e0bf-e33f-645e-f4d0ee15d394.jpeg">

※IM社様が提供するドキュメント(https://www.intra-mart.jp/document/library/bis/public/bis_specification/texts/spec/action_setting.html) より一部抜粋
EntityFrameworkを使ってDBモデルの作成（超簡易）

# はじめに
**EntityFramework**を使えば、GUI操作で簡単にEDM（Entity Data Model）が作れる。
ここでの利用についてEntity Data Modelを簡単に説明すると、DBを扱った場合指定したテーブルにマップしているモデル。このモデルを使ってデータアクセスを実現する。
「**CnnectionStringBuilder**」っていうDBに接続していちいちSQL発行するやつを使うより楽だし遥かに汎用性があって使いやすい気がする。

この記事では開発環境の構築を行っていること前提で説明を進めていくので、DB作ったりテーブル作ったりとか事前準備の手順なんて記述してない。

ちなみにEntityFrameworkとかいまだなんなのか理解してないしネットに転がってる記事難しすぎるから、簡単な操作だけ抜粋して資料っぽく説明付けていつでも思い出せるようにこの記事を作る。

※これは【超簡易】なのでスクショだらけです

# 環境
・VS2019
・.NetFramework 4.7.2
・SQLServer 15.0.2000.5
・EF6（Nugetからインストールするだけ）

# DBモデル作成
環境構築の説明はめんどくさいので割愛して、さっそく操作説明に入ります。
## ①プロジェクト作成
適当にプロジェクトを作る。（画像ではコンソールアプリケーションのプロジェクト）
ソリューションエクスプローラから以下の操作をする。
・「追加」→「新しい項目」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666502/2bbd9b86-323c-6546-6c49-ef227dd18a00.png)
## ②ADO.NET Entity Data Model選択
環境整えてるならあるはず。選択して名前決めたら「追加」を押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666502/42f55085-ece5-8d7d-1e53-dae587333d0b.png)
## ③モデルのコンテンツ選択
どうやってDBのモデルを作るか選ぶ。
「データベースからEF Designer」ってやつを選択して「次へ」を押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666502/ac1f2c4a-22fb-1873-f299-b9e44e5d37bd.png)
## ④データ接続の選択
接続するDBを選択する。（モデルを作りたいDBを選ぶ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666502/ef4b04e0-bf7c-16f2-79c0-44b5bac6dd25.png)
「新しい接続」を選択すると接続プロパティが表示される。以下を入力して「テスト接続」をクリック。
・データソース（画像の状態がデフォルト）
・サーバ名
・認証
・データベース名の選択または入力
※Windows認証の場合はこのまま進めるが、SQLServer認証の場合はユーザ名とパスワードを事前に確認しておいたほうがいい（セキュリティの設定とかも）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666502/0b9020e0-e588-4ff2-5e4c-6ce62589a8a2.png)
テスト接続が成功すると以下の画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666502/3ee5cdcf-5863-c875-9e85-de75d15e253d.png)
テスト接続成功後、データ接続の選択画面に戻って「次へ」を押下。
## ⑤データベースオブジェクトと設定の選択
DBモデルとして作成したいテーブル名の横にあるチェックボックスにチェックを付ける。

「生成されたオブジェクトの名前を複数化または単数化する」と「モデルに外部キー列を含める」にもチェック。

最後に「モデル名前空間」を命名して「完了」を押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666502/2a9e6043-51bd-5eaa-499a-19c3b13c29b8.png)
これでDBモデルが完成する。
## ⑥DBモデル完成
こんな画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666502/f2755124-e33b-7d5a-e187-3d7642a746f8.png)

おわり
初心者によるプログラミング学習ログ 358日目

#100日チャレンジの358日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
358日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">昨日の作業・やったこと⇩<br>●ブログ1記事作成<br>●kindle読書　20分ぐらい<br>●プログラミング学習358日目　2.0h<br>・架空LP pc版作成(<a href="https://twitter.com/ririru_123?ref_src=twsrc%5Etfw">@ririru_123</a>) 2.0h<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a> <a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a></p>&mdash; ぱぺまぺ@社畜✕投資✕ブロガー (@ppmp65) <a href="https://twitter.com/ppmp65/status/1278420415770062849?ref_src=twsrc%5Etfw">July 1, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
3分間ネットワーク備忘録 第４回

## 概要

[前回の記事](https://qiita.com/kenmaro/items/7c5c3317d328c2ef7fa1)に引き続き、
[3分間ネットワーク](http://www5e.biglobe.ne.jp/aji/3min/)を勉強して備忘録として纏めていきます。

今回は、
- [第８回](http://www5e.biglobe.ne.jp/aji/3min/08.html)
- [第９回](http://www5e.biglobe.ne.jp/aji/3min/09.html)

を振り返っていきたいと思います。

##アナログ通信、ディジタル通信
第一回の記事(https://qiita.com/kenmaro/items/ea3bbc95cfe9dc97936b)で
補足として言及しましたが、ここで`アナログ通信`とディジタル通信`について話が出てきました。

これからの数回の３分間ネットワークの記事が第一層である`物理層`の話になるので、
ここでネットワークメディアについて博士が話しており、その際にアナログ、ディジタルについて解説しています。

モデムがこのアナログ、ディジタル信号を変換します。

ここで、
- 電話回線
- ISDN
- LAN
- CATV
- ADSL

などの有名な回線について解説があり、その回線にパソコンをつなぐためには、
- どのケーブルが必要なのか
- ホスト（パソコン）とケーブルをつなぐための間に何が必要なのか

について博士が解説してくれています。

#### 電話回線
モデムが必要であり、EIA/TIA-232 というケーブルが必要。

#### ISDN
TA,DSUが必要であり、EIA/TIA-232 というケーブルが必要。

#### LAN
NICが必要で、LANケーブルが必要

#### CATV
NIC、ケーブルモデムが必要であり、LANケーブルで接続される。

#### ADSL
NIC,ADSLモデム、スプリッターが必要であり、LANケーブルで接続される。

と纏められています。


### 信号に起きる障害について
信号が伝送される時に、主に、
- 減衰
- ノイズ
- 衝突
などの障害が起こりえます。
減衰は信号の振幅が伝送距離によって減衰していくこと、
ノイズは、たとえば隣の線にも信号が流れている時に影響を受けること（クロストーク）、
衝突は名前の通り、複数の信号がぶつかって破損してしまうことです。

### ネットワーキングメディアの規格

ネットワーキングメディア（ケーブルなど）の規格は、`IEEE`　や、`EIA/TIA`によって決められています。

主に使われているのは３種類のケーブルで、
- 同軸ケーブル
- ツイストペアケーブル
- 光ファイバケーブル

と博士が説明しています。

この中でも今の主流（あくまでも３分間ネットワークが書かれた当時の主流）は
ツイストペアケーブルであり、１本の導体が通っている同軸ケーブルに比べ、
８本の銅線がまとめてよられているツイストペアケーブルは、キャンセレーションによって、干渉により強い、と説明されています。

それぞれの規格には名前があり、名前によって`何Mbps`なのか、上のどの種類のケーブルに該当するのかなどが
わかるようになっています。



### まとめ

第一層の解説の初めあたりに該当する、
３分間ネットワークの[第８回](http://www5e.biglobe.ne.jp/aji/3min/08.html)、[第９回](http://www5e.biglobe.ne.jp/aji/3min/09.html)を備忘録的に纏めました。



今回はこの辺で。


おわり。
RDSのインスタンス変更をキャンセルする

# tl;dr
AWS CLIで以下コマンドを叩く。

```bash
aws rds modify-db-instance --db-instance-identifier {DBインスタンス名} --db-instance-class {変更前のインスタンスクラス} --apply-immediately
```

# 経緯
手が滑ってRDSのインスタンスタイプを変更してしまった、、、
<img width="1658" alt="スクリーンショット 2020-07-02 19.18.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130232/3fb2492f-1c3f-817e-3f86-1ef08ef15cc8.png">

こんな感じで「保留中の変更」が表示されるようになったが、キャンセル方法が分からない。もう一度もとのインスタンスタイプに変更すればいいのかと思ったが、Webコンソールではできない。
次のメンテナンスウィンドウまでにどうにかしないとまずいのでサポートケースを上げたところ、CLIなら可能とのこと。コマンド再掲。

```bash
aws rds modify-db-instance --db-instance-identifier {DBインスタンス名} --db-instance-class {変更前のインスタンスクラス} --apply-immediately
```

焦っていて見つけられなかったが、ドキュメントにもちゃんと書いてあった。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html
> 次のメンテナンスウィンドウで保留中の変更を適用しない場合は、変更を元に戻すように DB インスタンスを変更できます。これを行うには、AWS CLI を使用し、--apply-immediately オプションを指定します。

スケジュールされている変更は以下コマンドで確認可能。空で返ってくればインスタンス変更はちゃんとキャンセルされたということ。これはWebコンソールでも確認可能。実際キャンセル後に見てみたら↑の画像の「保留中の変更」が消えていた。

```bash
aws rds describe-db-instances --db-instance-identifier {DBインスタンス名} --query 'DBInstances[].[PendingModifiedValues]'
```

<br>

教訓: Webコンソールでいじった内容をWebコンソールで戻せると思ったら負け。
コミットする際のcommit failed - exit code 1 received with output: git: 'secrets' is not a git command. See 'git --help'.のエラー対処法

Gitにてブランチをコミットしようとした際にエラーが出てコミットできなくなったのでその対処法を記載しておこうと思います。(ツールはGithubDesktopを使用しております。)

このエラーはコミットする際にgit-secretsを利用するファイルはあるけどgit-secretsがないですよ、ということを意味しています。(ぼくの解釈ですが。。。)

このエラーの対処法は主に2つあります。

##.git/hooks
1つ目の方法はリポジトリ内の.git/hooksにある「commit-msg, pre-commit, prepare-commit-msg」という実行ファイルを削除する方法です。

```
$ ls  #カレントディレクトリにあるファイルやディレクトリを表示する
$ ls -l  #ファイルやディレクトリの詳細も同時に表示する
$ ls -a  #隠しファイルも含めファイルやディレクトリを全て表示する
$ ls -la  #隠しファイルを含む全てのファイルやディレクトリの詳細を表示する
```

.git/hooksは隠しファイルなのでlsコマンドを使用しファイルの場所を確認します。

```
$ rm test.html  #test.htmlを削除する
$ rm -r test  #testというディレクトリとその中身を削除する
$ rm -f test  #testというファイルを警告なしで削除する
$ rm -rf test  #testというディレクトリとその中身を警告なしで削除する
```

ディレクトリとファイルの場所を確認したらrmコマンドで「commit-msg, pre-commit, prepare-commit-msg」のファイルを削除します。

##git-secretsをインストールする
2つ目の方法はHomebrewにgit-secretsをインストールする方法です。

```
$ brew install git-secrets
```

こちらのコマンドを入力すれば完了です。


以上どちらかの方法でコミットできるようになるかと思います。
[光-Hikari-のPython]09章-01 クラス（オブジェクトの基礎）

#[Python]09章-01 オブジェクトの基礎
今まで、文字列や数値、データ構造の分野ではリストやタプルなどに触れました。データ構造の個所で触れましたが、これらは**オブジェクト**と言いました。

さて、このオブジェクトとは何でしょう。まずはオブジェクトについて説明して少し掘り下げていきたいと思います。


##オブジェクトとは
まずは**Python Console**にて以下のコードを入力して確認してみましょう。

```.py
>>> S = 'hello'
>>> type(S)
<class 'str'>
```

**S**という変数に'hello'という文字列を代入しています。さて、次に**type()**関数により、**\<class 'str'\>**が出力されています。
これは、S変数がが現在**str型のオブジェクト**であることを意味しています。

では、strオブジェクトの詳細を見てみましょう。以下のURLから閲覧できます。
[https://docs.python.org/ja/3/library/stdtypes.html#text-sequence-type-str](https://docs.python.org/ja/3/library/stdtypes.html#text-sequence-type-str)

マニュアルを見てみると、str型はテキストシーケンス型と書かれています。要するに文字列型のオブジェクトということです。

さて、マニュアルを少し下に送ると、「文字列メソッド」というものが出てきます。
例えば、一番最初にある*str*.capitalize()メソッドを実行してみましょう。
なお、このマニュアルにある、*str*はstr型のオブジェクトを表すので、今回実際に入力するときにはSという変数名となります。

```.py
>>> S
'hello'
>>> S.capitalize()
'Hello'
```
先頭のみ、大文字になったことが確認できたと思います。詳細は*str*.capitalize()メソッドマニュアルを見てください。

また、ほかのメソッドも見てみましょう。*str*.replace()メソッドを実行してみましょう。

```.py
>>> S.replace('l', 'L')
'heLLo'
```

replaceメソッドにより、文字列中の文字を変更ができます。詳細はマニュアルを見てみましょう。

他にもいろいろなメソッドを**マニュアルを見ながら**やってみましょう。今後、マニュアルに書いてある内容は一部を除き、割愛していきたいと思います。

さて、このstr型だけではないですが、オブジェクトの型にはほかにもあります。以下のコマンドでいろいろな方を確認してみましょう。

以下は**int型オブジェクト**となります。

```.py
>>> num1 = 100
>>> type(num1)
<class 'int'>
```

以下は**float型オブジェクト**となります。

```.py
>>> num2 = 10.5
>>> type(num2)
<class 'float'>
```

以下は**list型オブジェクト**となります。

```.py
>>> ls = ['Japan', 'America', 'China']
>>> type(ls)
<class 'list'>
```

以下は**tuple（タプル）型オブジェクト**となります。

```.py
>>> tp = (10, 20, 30)
>>> type(tp)
<class 'tuple'>
```


以下は**dict（ディクショナリ）型オブジェクト**となります。

```.py
>>> dc = {'jp':'Japan','us':'America', 'ch':'Chine'}
>>> type(dc)
<class 'dict'>
```

これらそれぞれの型のオブジェクトには**メソッドを持ちます**。実際に調べてみましょう。ほとんどは以下のURLに記載してあります。
[https://docs.python.org/ja/3/library/stdtypes.html](https://docs.python.org/ja/3/library/stdtypes.html)

<font color=red>＜重要＞</font>
実は、**あるデータとその振る舞い（メソッド）が一塊**になっているものを一般に**オブジェクト**と言います。
例えば、

```.py
>>> ls = [1, 3, 3, 2, 1, 2, 2, 1, 1, 2]
>>> ls.count(2)
4
```
とすれば、lsは**リスト型のオブジェクト**であり、そのオブジェクトは「1, 3, 3, 2, 1, 2, 2, 1, 1, 2」という**データを持ち**、count()という**メソッドも持ちます**。


また、関数もオブジェクト（**functionオブジェクト**）と言えます。

```.py
def calc_func(x):
    print('関数内で実行します')
    f = (x ** 2) + (3 * x) + 4
    ##計算結果fを返す
    return f

print(type(calc_func))
```

><font color="#090" bgcolor="black">【実行結果】</font>
\<class 'function'\>

##オリジナルのオブジェクト
先ほどはint型やstr型、そしてlist型などのオブジェクトがありましたが、実はオブジェクトは自分で作成することができます。
これについては次回触れていきたいと思います。

##最後に
このオブジェクトの概念は非常に取り扱いの難しいものなので、最初は壁を感じるかと思います。ポイントは先ほどのURLにもあった、いろいろなマニュアルを読んでみることです。
最初は意味が分からなくても、読んでいくことで意味が分かってくるようになりますので、ポイントはマニュアルを見ながら実際に実行してみることです。

###[【目次リンク】へ戻る](https://qiita.com/ko0821/items/379e8bd9e6ea01089419)
ある条件に一致した時だけCSSで枠線を表示するにはoutlineを使うのがよさそう

ボタンにフォーカスしたときだけ枠線を表示したい状況があり、
意気揚々と以下のような CSS を書いたところ、
フォーカスしたときに枠線は表示されるものの、
同時にボタンの表示位置がずれるという残念な結果になった。

```css
#target-button:focus {
  border: solid 5px red;
}
```

どうやら `border` は枠線を表示するスペースを必要とするため、
常に枠線を表示するような場合には良いが、
フォーカスやホバーしたときにだけ枠線を表示する場合には向かない模様。

似たようなプロパティで `outline` はスペースを取らずに枠線を表示できるため、
こちらを使用したら上手くできた。
フォーカスやホバーなど、特定の条件に一致した時だけ枠線を表示するなら `outline` を使うのがよさそう。

ただし、 `outline` では 上だけ表示 や 下だけ表示 といったことができないようなので、
そういったことがやりたい場合はまた他の方法を探す必要がありそう。。。

---

以下、ホバーしたときだけ枠線を表示するサンプル。
BUTTON1 が `border` 、BUTTON2 は `outline` で枠線を表示しています。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="jz4o" data-slug-hash="eYJypRL" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="css_border_outline">
  <span>See the Pen <a href="https://codepen.io/jz4o/pen/eYJypRL">
  css_border_outline</a> by jz4o (<a href="https://codepen.io/jz4o">@jz4o</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
統計学習

# 統計学2級対応　統計学基礎より

##ロレンツ曲線

所得など、経済的な集中度を表すために描かれたグラフ

###書き方（例、所得データの場合）

1. データを所得が低い順に並べる
2. データを階級に区分し、各階級の度数と総所得金額を算出する
3. 各階級の所得金額の相対度数をとる
4. 各階級の累積相対度数を横軸に、所得金額の累積相対度数を縦軸にとりグラフを描画する

###ロレンツ曲線が45度線上にある時、富は完全に平等に分配されている。
45度線から下方に遠ざかるほど、富の不均衡が存在する。

この、ロレンツ曲線と45度線の乖離を**ジニ係数**といい、不均衡を数値で示すことが出来る。


##ジニ係数

ジニ係数は、正方形に対し、45度線とロレンツ曲線の弧に挟まれた**扇型の面積の割合の2倍**で表される。
値は0~1の範囲におさまる。
0に近づくほど完全平等、１に近づくほど不均衡である。
また、ジニ係数が一致した場合でもロレンツ曲線の形状が一致するとは限らない。