OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby と Python で解く AtCoder ABC011 C 動的計画法

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。
# 今回のお題
*[AtCoder Beginner Contest C - 123引き算](https://atcoder.jp/contests/abc011/tasks/abc011_3)*
<font color="brown">Difficulty: 761</font>

今回のテーマ、動的計画法

以前解きました、*[Ruby と Perl と Java で解く AtCoder ABC 129 C (後編) 動的計画法](https://qiita.com/superrino130/items/b9cad212d64f8bcb0eda)*と似た感じです。

1,2段飛び－＞1,2,3の引き算

# Ruby
```ruby.rb
n = gets.to_i
a = Array.new(n + 1, n)
b = Array.new(n + 1, 101)
b[n] = 0
3.times do
  ng = gets.to_i
  a[ng] = -1 if ng <= n
end
n.downto(1) do |i|
  if a[i] > 0
    if i - 1 >= 0 && a[i - 1] > 0 && a[i] - 1 >= 0
      a[i - 1] = a[i] - 1
      b[i - 1] = b[i] + 1 if b[i - 1] > b[i] + 1
    end
    if i - 2 >= 0 && a[i - 2] > 0 && a[i] - 2 >= 0
      a[i - 2] = a[i] - 2
      b[i - 2] = b[i] + 1 if b[i - 2] > b[i] + 1
    end
    if i - 3 >= 0 && a[i - 3] > 0 && a[i] - 3 >= 0
      a[i - 3] = a[i] - 3
      b[i - 3] = b[i] + 1 if b[i - 3] > b[i] + 1
    end
  end
end
puts b[0] < 101 ? "YES" : "NO"
```
```array.rb
a = Array.new(n + 1, n)
b = Array.new(n + 1, 101)
```
引き算のテーブルと、回数を控えるテーブルを用意します。

```ans.rb
puts b[0] < 101 ? "YES" : "NO"
```

`0`になった時の回数をみて、Yes/Noを判定します。

ところで引き算の場合、引数がマイナスになった時の処理が入りますので、煩雑な感じがします。
そこで、プラス版も書いてみました。

```rubyplus.rb
n = gets.to_i
a = Array.new(n + 4, n)
b = Array.new(n + 4, 101)
b[0] = 0
3.times do
  ng = gets.to_i
  a[ng] = -1 if ng <= n
end
n.times do |i|
  if a[i] > 0
    1.upto(3) do |j|
      if a[i + j] > 0
        a[i + j] = a[i] + j
        b[i + j] = b[i] + 1 if b[i + j] > b[i] + 1
      end  
    end
  end
end
puts b[n] < 101 ? "YES" : "NO"
```
```array.rb
a = Array.new(n + 4, n)
b = Array.new(n + 4, 101)
```
配列を長めにとって対応しています。
# Python
```python.py
from sys import stdin

def main():
    input = stdin.readline
    n = int(input())
    a = [n] * (n + 4)
    b = [101] * (n + 4)
    b[0] = 0
    for i in range(3):
        ng = int(input())
        if ng <= n:
            a[ng] = -1
    for i in range(n):
        if a[i] > 0:
            for j in range(1, 4):
                if a[i + j] > 0:
                    a[i + j] = a[i] + j
                    if b[i + j] > b[i] + 1:
                        b[i + j] = b[i] + 1
    print("YES" if b[n] < 101 else "NO")
main()
```
`Python`はプラス版です。

||Ruby|Python|
|:--:|:--:|:--:|
|コード長 (Byte)|358|540|
|実行時間 (ms)|69|29|
|メモリ (KB)|14372|9196|
# まとめ
+ ABC 011 C を解いた
+ Ruby に詳しくなった
+ Python に詳しくなった
Reactプロジェクト作成から画面遷移まで

#本記事の目標
1. TypeScriptでReactを構築
2. react-routerで画面遷移を実装

パッケージのインストールの話はしません。
必要なパッケージが入っている前提で話します。

#プロジェクト作成
以下のコマンドをうち、my-appというプロジェクトを作成します。
（my-appのところには好きなアプリ名に変更してください。）

```
npx create-react-app my-app --template typescript
```

プロジェクトの作成が終わったら,以下の二つのコマンドを順番に打ちます。

```
cd my-app
yarn start 
```

以下の画面が出ればOKです。
<img width="1440" alt="reactデフォルト画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489954/da065ad6-b175-f9a8-10ee-081847bc1e1f.png">

#rootフォルダの設定
tsconfig.josnの "compilerOptions"の中に以下を書き込む。
こうすることで、rootフォルダをsrcに設定でき、import文が綺麗になる。

```
"baseUrl": "src" 
```


#react-routerの導入
以下のコマンドをうち、react-routerを導入する。

```
yarn add react-router-dom
yarn add @types/react-router-dom
```

##ページ作成
表示させたいページを作成していく。
今回はHomeとAboutというページを作成する。

###Homeページ
srcフォルダの中にpagesフォルダを作成する。
pagesフォルダの中にHome.tsxを作成する。

```ruby:Home.tsx
import React from "react";
import { Link } from "react-router-dom";

class Home extends React.Component {
  render() {
    return (
      <div>
        <div
          style={{
            display: "flex",
            flexDirection: "row",
            justifyContent: "space-between",
            width: 110,
          }}
        >
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
        </div>
        <h1>Home</h1>
      </div>
    );
  }
}

export default Home;
```

###Aboutページ
pagesフォルダの中にAbout.tsxを作成する。

```ruby:About.tsx
class About extends React.Component {
  render() {
    return (
      <div>
        <div
          style={{
            display: "flex",
            flexDirection: "row",
            justifyContent: "space-between",
            width: 110,
          }}
        >
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
        </div>
        <h1>About</h1>
      </div>
    );
  }
}

export default About;
```
##routerの設定
作成した画面を表示する設定を行う。

###routerの設定
srcフォルダにRouter.tsxを作成する。
イメージ的にはここで表示するページのパスを設定する。

```ruby:Router.tsx
import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Home from "pages/Home";
import About from "pages/About";

export default class Router extends React.Component {
  render() {
    return (
      <BrowserRouter>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route exact path="/about" component={About} />
        </Switch>
      </BrowserRouter>
    );
  }
}
```

###indexの設定
index.tsxを以下のように変更する。
Routerタグのところにrouter.tsxで設定したページが切り替わって表示される。

```ruby:index.tsx
import React from "react";
import ReactDOM from "react-dom";
import * as serviceWorker from "./serviceWorker";
import Router from "Router";

ReactDOM.render(
  <React.StrictMode>
    <Router />
  </React.StrictMode>,
  document.getElementById("root")
);

serviceWorker.unregister();
```

###ページの確認
yarn startをすると以下の画面が表示される。
リンクを押すとHome画面とAbout画面を切り替えられる。

<img width="1440" alt="Home画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489954/552d29d5-9263-7551-82c8-34e48cbac98b.png">

#削除していいデフォルトファイル
以下に書かれたデフォルトファイは使わないので、削除してもOKです。
- App.css
- App.test.tsx
- App.tsx
- index.css
- logo.svg
【rails】urlを取得する際gsubを使って力技でエンコードしました！！！！

パスワード付きの投稿にアクセス制限をかけるときに使いました。
[【rails】投稿にパスワードを設定する方法、url直打ち対策済み](https://qiita.com/hiruhiru/items/9dffc729f5192df243a8)

```ruby:qiita.rb
url = request.url.gsub!(/%21|%22|%23|%24|%24|%25|%26|%27|%28|%29|%2A|%2B|%2C|%2F|%3A|%3B|%3C|%3D|%3E|%3F|%40|%5B|%5D|%5E|%60|%7B|%7C|%7D|%7E|/,
    "%21" => "!", "%22" => '"', "%23" => "#", "%24" => "$", "%25" => "%", "%26" => "&", "%27" => "'", "%28" => "(", "%29" => ")",
    "%2A" => "*", "%2B" => "+", "%2C" => ",", "%2F" => "/", "%3A" => ":", "%3B" => ";", "%3C" => "<", "%3D" => "=", "%3E" => ">", "%3F" => "?", "%40" => "@",
    "%5B" => "[", "%5D" => "]", "%5E" => "^", "%60" => "`", "%7B" => "{", "%7C" => "|", "%7D" => "}", "%7E" => "~")
```

コピペして使ってね。

参考
https://www.seil.jp/doc/index.html#tool/url-encode.html
strongSwan で iOS 端末の VPN 接続が 1 時間で切れないようにする

strongSwan の IKE SA のリキー間隔はデフォルトで 4 時間になっていますが、iOS は 1 時間経過すると IKE SA を破棄してしまうため、それまでにリキーが行われないと VPN 接続が切れてしまいます。
そのため strongSwan の設定でIKE SAのリキー間隔を 1 時間にします。Child SA のリキー間隔はそれよりも短い 30 分にします。

### swanctlの場合
```swanctl.conf
connections {
    <コネクション名> {
        ...
        rekey_time = 1h
    }

    ...

    children {
        <子SA名> {
            ...
            rekey_time = 30m
        }
    }
}
```

### ipsec.conf を使う場合
```ipsec.conf
conn <コネクション名>
  ...
  ikelifetime=1h
  lifetime=30m
```

これで 1 時間以上接続しても VPN 接続が切れないようになります。
Turbo intruderでrace conditionを調査する

Burp Suiteの[Turbo intruder](https://github.com/PortSwigger/turbo-intruder)を使用してrace conditionを調査する方法。

1. BApp StoreからTurbo Intruderを入れる
1. 大量に送信したいリクエストを1つキャプチャする
1. Proxy > HTTP historyから当該リクエストを右クリック → Send to turbo intruder
1. 下記スクリプトを入力 (https://github.com/PortSwigger/turbo-intruder/blob/master/resources/examples/race.py をベースに微修正)

    ```python
    # script for testing race condition
    def queueRequests(target, wordlists):
        engine = RequestEngine(endpoint=target.endpoint,
                            concurrentConnections=30,
                            requestsPerConnection=100,
                            pipeline=False
                            )

        for i in range(30):
            engine.queue(target.req, i, gate='race1')

        engine.openGate('race1')
        engine.complete(timeout=60)

    def handleResponse(req, interesting):
        table.add(req)
    ```

1. リクエストのどこかに `%s` を入れる (`X-Intruder: %s` ヘッダ追加など)
1. Attackボタンをクリック、またはCommand-Enter (Mac)
初心者によるプログラミング学習ログ 375日目

#100日チャレンジの375日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
375日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>昨日の作業・やったこと⇩<br><br>●kindle読書 10分<br>●ブログ1記事作成<br>●プログラミング学習375日目 1h<br>・Udemyフロントエンド講座<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%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?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/%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></p>&mdash; ぱぺまぺ@社畜✕投資✕ブロガー (@ppmp65) <a href="https://twitter.com/ppmp65/status/1284613497733566464?ref_src=twsrc%5Etfw">July 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Unity 3D入門 #4 [目の前のオブジェクトを調べる]

ゲームを作るために、キャラクターの目の前にあるものを調べる機能をつけます。



Rayを用いてプレイヤーがアイテムを拾う処理についてhttp://phanta.tech/2019/01/15/unity_fps_gotitem/ を参照

また、RaycastHitについてhttps://yttm-work.jp/unity/unity_0022.html を参照

ここで、勘違いしていたことは、Debug.DrawRayはGameビューに映らないことでした。（Sceneビューにも映らなかったが）

Rayはうまく発射できていると仮定して次に進みます。

```
void Update()
{
    Ray ray = new Ray(player.transform.position, player.transform.forward);
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, maxDist))
	{
        if (hit.collider.gameObject.tag == "Item")
        {
            Debug.Log(hit.transform.name+"と交差");
        }
    }
```

これはプレイヤーからプレイヤーの進行方向に発射されたRayが何かにぶつかった時、ぶつかったオブジェクトがItemタグを持っていたらLogに出力するコードです。

追記：maxDistは2.0f程が良い

しかし、これではプレイヤーの足元から光線が出てしまい、思った挙動をしていませんでした。

```
Vector3 pos = player.transform.position;
pos.y += 0.5f;
Ray ray = new Ray(pos, player.transform.forward);
```

そのため、上のようにyに高さを加えることで、プレイヤーの腰辺りからRayを出すようにしました。


最後に、RayがぶつかったItemの色を赤に変えるコードを入れて、GIFでもわかりやすくします。
追記：オブジェクトの色を変える参考URL( https://qiita.com/Hal_mai/items/1469398078e81bc7ef27 )

```
hit.collider.gameObject.GetComponent<Renderer>().material.color = Color.red;
```

今回の進捗GIFです。

![ezgif-7-c26166ca8600.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670403/27920ca9-7e39-79d3-0a4a-1e84a4173bd3.gif)
[HTML/CSS高速コーディング]ギリギリまでコードを書かないChrome DevToolsのリアルタイムレイアウト編集テクニック

HTMLとCSSを書くとき、レイアウトの微調整に保存とリロードを繰り返していませんか？
それ、Chromeの開発者ツールを使うと編集しながらリアルタイムで内容を確認できますよ！

## 要素の選択
### 右クリックメニューの「検証」
右クリックメニューの「検証」を選ぶと選択要素に一発で移動できます！
＊重なってる要素があると重なり上の一番上になっている要素が選択されます
<img width="337" alt="スクリーンショット 2020-07-19 22.48.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122390/4ca65dd6-331d-e636-9da6-fd7b03e2c841.png">


### Elementパネルの操作
|キー|動作|
|---|---|
|↑|1行上の要素（タグ）へ|
|↓|1行下の要素へ|
|←|開いていた親要素を閉じる|
|→|閉じていた子要素を開く|

![名称未設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122390/e7db1b0d-ba82-1d87-1e83-62479960dedf.gif)

キーボード操作で要素を移動していくと快適ですね！


## CSSのリアルタイム反映

<img width="429" alt="スクリーンショット_2020-07-19_21_59_11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122390/6a8e412e-1a7f-5811-fb29-430a4c934b21.png">
CSSファイル由来のクラスのスタイルはクリックして編集可能です。
新しいプロパティの追加もできますし、設定しているものを無効化することもできます。


![画面収録 2020-07-19 22.15.56.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122390/7a55a2cc-8df0-f508-21eb-0c15592789e8.gif)


gif中の数値指定をなめらかに変えているところではマウスホイールを使っています。
キーボードの上下でもOK。

|キー|数値の変化|
|----|---|
|↑/↓|+1/-1|
|Shift + ↑/↓| +10/-10|
|Shift + PgUp/PgDown| +100/-100|
|[Win]Alt[Mac]Opt + ↑/↓| +0.1/-0.1|


[キーボード ショートカットのリファレンス | Chrome DevTools](https://developers.google.com/web/tools/chrome-devtools/shortcuts?hl=ja#styles_%E3%82%B5%E3%82%A4%E3%83%89%E3%83%90%E3%83%BC)

いい感じの数値やスタイルになったらコードへペースト！

## HTMLの編集
エレメントタブの右クリックメニューのEdit as HTMLでHTMLが編集できます。
Enterだと改行になりますがEscではキャンセルになるので気をつけてください。
確定は`[Win]Ctrl/[Mac]Cmd + Enter`です。 Thx @sanfrecce-osaka
![画面収録 2020-07-19 21.40.38.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122390/8b38297c-87b8-4919-6e1d-8592524bef96.gif)

### ElementタブのDOM操作系ショートカット
Ctrl + Cで選択要素がクリップボードに入ります。
Ctrl + Vで貼り付け、Deletキーで削除できます。

属性をダブルクリックしたり、内部テキストをダブルクリックすると編集状態にできます。
要素を増やした場合のレイアウトや空だった場合のレイアウト、
中の文字数が多い時のレウアウト確認にお使いください。


# まとめ
リロードしなくても、Chrome DevToolsでかなり自由にDOMとCSSが編集できることがわかりました。
この方法ならリアルタイムに画面上で幅感やレイアウトを確認しながら編集できるのがいいですね。

このテクニックをうまく使えば、スタイルやHTMLの構造をDevTools上で考えて、最後にファイルへコピーするだけで済ますことができます。
知っていればHTMLとCSSが高速にコーディングできること間違いなし。是非使ってみてください。

## 他にもテクニック
- [\[CSS単位系\] vh, vw に潜む甘い罠\[widthとheightに使うときの注意\] \- Qiita](https://qiita.com/fruitriin/items/71c0cb9aeca28882bdc4)
- [\[サーバーサイドAPIデバッグ術\]ブラウザのリクエストを簡単にリトライしてサーバーの挙動を見る方法 \- Qiita](https://qiita.com/fruitriin/items/72d66cf88b8319512620)
- [\[JavaScriptデバッグテクニック\]メソッド実行中の変数の中とか見たくない？ \- Qiita](https://qiita.com/fruitriin/items/d0a1cd943233cd22ef30)
Java 8+ API desugaring メモ

# はじめに
Java 8+ API desugaring[^1] のメモです。

# 概要

## ◆ 特徴
minSdkVersion 的に非対応の Java 8 の機能を使えるようにします。

<font color="red">例えば、API 26 から追加された [DateTimeFormatter](https://developer.android.com/reference/java/time/format/DateTimeFormatter) が、API 25 以下の端末上でも利用できるようになります。</font>

```kotlin
// SimpleDateFormat はスレッドセーフではないので何とかしたい
SimpleDateFormat("yyyy-MM-dd", Locale.US)
```

```kotlin
// DateTimeFormatter を使えばスレッドセーフになる
// 　　　　→ だけど API 26 からしか使えない、、、
// 　　　　　　　　→ そうだ、desugaring があるじゃないか！
DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.US)
```

## ◆ desugaring 前
minSdkVersion 的に非対応の Java 8 の機能を使用すると、Android Studio 上では警告が表示されます。

![device-2020-07-19-194252.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219474/d03db411-bc6b-8bb9-c8e3-2b3222cc299d.png)

ビルドは実行できますが、当該ライブラリが含まれない端末では実行時にエラーとなります。

![device-2020-07-19-194252.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219474/793f4c7a-69c6-4566-240b-f6ea117e68bc.png)


## ◆ desugaring 後
ビルドも実行もでき、当該ライブラリが含まれない端末での実行も問題なく行うことができます。

![device-2020-07-19-194252.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219474/62b2c024-7fac-0470-91cd-ca823728b0da.png)

# 条件
Android Gradle Plugin 4.0.0 以降

# 対象API
https://developer.android.com/studio/write/java8-support-table

※ `java.time`, `java.util.Optional`, `ConcurrentHashMap`(bug fix 済み) など

# 設定

## minSdkVersion > 20 の場合
```groovy
android {
    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
dependencies {
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
}
```

## minSdkVersion <= 20 の場合
```groovy
android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

  compileOptions {
    coreLibraryDesugaringEnabled true
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
}
```

[^1]: https://developer.android.com/studio/write/java8-support#library-desugaring
ポートフォワーディングで github に ssh する

## やりたいこと

AWS で Private Subnet（基本的に外界から断絶されたサブネット）に配置されたサーバから、Public Subnet に配置された NAT インスタンス経由で、github にアクセスする。Local Machine から NAT 経由でサーバにアクセスするのの逆。Private Subnet 内のインスタンスからは、基本的にはあちこち ssh でアクセスさせない。

なお、サーバの OS は Amazon Linux2。

## github の IP
[github meta](https://api.github.com/meta)

クソいっぱいある！全部で56個（レンジ）ある。使うのは、git の部分の35個だけかな？


## プレフィックスリスト の作成
Inbound/Outbound の Rules に1つずつ全部追加するのはシンドイので、プレフィックスリストを使う。

```VPC > マネージドプレフィックスリスト```

新規作成。今後増えるやも知れないので、上限40個くらいにしておく。溢れたら作り直す。

## Security Group(or NACL) の設定

SG か NACL かは、ポリシー次第。
NAT の SG or Public Subnet の NACL or both の Outbound に 22 ポートで先程作成した プレフィックスリストを加える。
Private Subnet のサーバから Public Subnet の NAT サーバに対して 22 ポートを受け付けていなければ、開ける。Inbound。
22番ポートのルートがルートテーブルになければ、それも追加。

## RSA key の作成および登録

github にアクセスしたい Private Subnet のサーバで、RSA Key を NAT 用と github 用の 2 つ作る。

```
$ cd ~/.ssh
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f nat_rsa
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f github_rsa
```

鍵の使い回しはやめよう！鍵にパスワードは付けよう！
生成された鍵を登録する。

- nat_rsa.pub の中身を NAT サーバの .ssh/authorized_keys に追記
- github_rsa.pub の中身を [github > settings > SSH and GPG keys](https://github.com/settings/keys) に登録

SSH トンネルが成功している時点で、パーミッション関連は大丈夫だと思いますが、外に出ていく用に User を作ったりすることもあるかも知れないので、念の為書くと、

- NAT サーバの .ssh: 700
- NAT サーバの authorized_keys: 600
- nat_rsa, github_rsa: 600

## .ssh/config の設定

```
Host nat
    HostName xxx.xxx.xxx.xxx
    User your_user_name
    IdentityFile ~/.ssh/nat_rsa
    TCPKeepAlive yes
    IdentitiesOnly yes
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/github_rsa
    ProxyCommand ssh -W %h:%p nat
```

NAT サーバの Private IP Address と your_user_name は自分のものに。

## 疎通確認

NAT サーバの ```/var/log/secure``` を監視しておく（私は、less / shift + f 派）

Private Subnet のサーバにて

```
$ ssh git@github.com
PTY allocation request failed on channel 0
Hi xxxxx! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
Killed by signal 1.
```
つながった。NAT サーバのログもちゃんと反応している。
clone 等も問題なくできる。

というわけで、NAT 経由の ssh ポートフォワーディングで、github に接続できた。おしまい。
JSONのサイズ取得の違い

```GAS:test.gs
function test(){
  var jsonObject = {
    "aaa": [ {"a":1, "b":2, "c":3},{"a":4, "b":5, "c":6} ],
    "bbb": 333,
    "ccc": 444
  };

  Logger.log(jsonObject.length);
  Logger.log(jsonObject.aaa.length);
  Logger.log(Object.keys(jsonObject).length);
  Logger.log(Object.keys(jsonObject.aaa).length);
}
```

```出力結果:ログ
[20-07-19 22:34:03:645 JST] null
[20-07-19 22:34:03:648 JST] 2.0
[20-07-19 22:34:03:650 JST] 3.0
[20-07-19 22:34:03:652 JST] 2.0
```
Gitコマンド ~Stash編~

#概要
Git操作に使うコマンドを備忘録用にまとめてみました。
今回はstash操作編です！

#コマンド一覧

- 現在の作業を一時中断し、退避

```
$ git stash save
```
　　※saveは省略可

- 退避した作業の一覧を表示

```
$ git stash list
```

- 退避した作業の復元

```
$ git stash pop
```

- 退避した作業の削除

```
$ git stash drop
```


- 退避した作業を全て削除

```
$ git stash clear
```

以上
[Jasmin]ジャスミンで適切なマッチャーを使えるようになるメモ[toBe(),toEqual()]

#目的

- ジャスミンでテスト駆動開発ができるようになる。

#今日やること

- ジャスミンはあらかた触れるようになってきたので、適切なマッチャーを使えるように、toBe、toEqualを比較する。


#マッチャーとは何か

マッチャーとは、テストの評価条件を定義するメソッドです。
例えば、toBe(b)がマッチャーに該当します。

その他に真偽判定の```toBeTruthy()``` や```toBefalsy()``` などもあります。

```Js:toBe()
it('aはbと厳密等価である', () => {
  let [a, b] = [10, 10];
  expect(a).toBe(b); // => OK
});

```

#toBe()

値、型を比較して、同一のものか判断します。
つまり、厳密等価です。詳しくは[こちら（MDN)](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Strict_equality))

（メモリの場所も含め同じ場所である必要がある。?）


```Js:toBe()
it('aはbと厳密等価である', () => {
  let [a, b] = [10, 10];
  expect(a).toBe(b); // => OK
});

it('aはbと厳密等価である', () => {
  let [a, b] = [10, '10'];
  expect(a).toBe(b); // => NG
});
```

#toEqual()

値が等しい

```Js:toEqual()
it('aはbと同値比較で等しい', () => {
  let [a, b] = [
    {"foo": ['bar', 'baz']},
    {"foo": ['bar', 'baz']},
  ];
  expect(a).toEqual(b); // => OK
});

it('aはbと同値比較で等しい', () => {
  let [a, b] = [
    {"foo": ['bar', 'baz']},
    {"foo": ['bar', 'baz']},
  ];
  expect(a).toEqual(b); // => NG
});
```

#結局どちらを使うべきなのか？

##基本的には、toBeの方が厳格なのでよいのでは（先輩方・・教えてください・・）
【Python】データサイエンス100本ノック（構造化データ加工編） 007 解説

- データサイエンス100本ノックをやりきる会を作りました🎉
- こちらの[Slack招待URL](https://join.slack.com/t/data-science-100nocks/shared_invite/zt-gfncg9vm-8W8b3UrDg8R~TKaqUkQpgw)からご参加ください！！
- ぜひ一緒に励まし合いながら、データサイエンス100本ノックをやり切りたいと思っています！

##Youtube
[動画解説](https://youtu.be/F3phP67mXxE)もしています。

##問題
P-007: レシート明細のデータフレーム（df_receipt）から売上日（sales_ymd）、顧客ID（customer_id）、商品コード（product_cd）、売上金額（amount）の順に列を指定し、以下の条件を満たすデータを抽出せよ。
- 顧客ID（customer_id）が"CS018205000001"
- 売上金額（amount）が1,000以上2,000以下

##解答
```:コード
df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \
.query('customer_id == "CS018205000001" & 1000 <= amount <= 2000 ')
```

##出力
|  | sales_ymd | customer_id | product_cd | amount |
|--:|--:|:--|:--|--:|
| 72254 | 20180911 | CS018205000001 | P071401005 | 1100 |

##解説
・PandasのDataFrame/Seriesにて、列を指定しつつ、指定した行のうち、条件に当てはまる行を確認する方法です。
・列情報を絞り、かつ、行を指定して、かつ、条件に当てはまる情報を確認したい時に使用します。
・**'<データ名>[['<列名A>','<列名B>','<列名C>']].guery('<列名A> == "<行情報A>" & 1000 <= <列名B> <= 2000')'**で、指定した列(列名A,列名B,列名C)のうち、列名A が指定した 行情報A に該当する行で、かつ、列名B が1000以上2000以下の行を表示します。

※比較演算子については、[こちら](https://www.atmarkit.co.jp/ait/articles/1907/23/news010.html)の記事が参考になります
Re:VIEWの執筆ルール

## はじめに

[技術書典7](https://techbookfest.org/event/tbf07) で初めて [Re:VIEW](https://github.com/kmuto/review) を使って技術書を執筆しました。
そのときにRe:VIEWの使い方で注意すべきことがいくつかあったので、本記事にまとめます。

## 環境

- Re:VIEW：4.2.0

## Re:VIEWの執筆ルール

基本的にはTechBoosterさんに合わせます。

### 執筆

執筆に関するルールです。

#### 「。」のあとは改行する

∵1行が長いと、ソースレビュー時に読みにくいため
変更時に差分をわかりやすくするため

#### できる限り `@<br>{}` で改行しない

∵文章を改行するときは段落とすべきなため

#### 絵文字を使わない

∵出力できず、ビルドエラーになるため

#### 見出しに `@<code>` タグを使わない

∵電子版でビルドエラーになるため

#### 見出しに `@<fn>` タグを使わない

∵目次にも脚注のマークが表示されてしまうため

#### URLは `@<href>{}` で括る

∵電子版で簡単にアクセスできるようにするため
例： `@<href>{https://example.com/}`
機械学習エンジニアのためのjavascript 早見表

機械学習エンジニアだとPython をよく使うことはあるが、ついついjavascript の使い方を忘れてしまうのではと思い、以下のような早見表を作った。ほぼ、自分のための備忘録ではあるが・・・

下記は node で実行。

### 誰向け?
- javascript そんなに使わない。けど、時には必要かも・・・・
- python よく使う人

### operation

```
=== //type and value
== //value
% //mod
... // spreads
Array.from(tf_arr.keys()) // spreads same
```





### arrow

(python でいう `lambda`)

single

```
> fake_func=() => 42
> fake_func()
42
```

multiple

```
> res=() => (x) => x*2
[Function: res]
> double=res()
[Function (anonymous)]
> double(3)
6
```



### array

push

```
> var res=[];res.push(1)
1
```

pop

```
> res.pop()
1
```

splice

```
> var arr=[1,2,3,4,5,6];res = arr.splice(0,3); 
[ 1, 2, 3 ]
> arr
[ 4, 5, 6 ]
```


slice

```
> arr=[1,2,3,4,5,6];
[ 1, 2, 3, 4, 5, 6 ]
> arr.slice(0,3)
[ 1, 2, 3 ]
> arr
[ 1, 2, 3, 4, 5, 6 ]
```

length

```
arr.length
```

ForEach　
(これより先は、ほぼarrow 関数を入れる感じ)

```
> var res=[]
undefined
> arr=[1,2,3,4,5,6];
[ 1, 2, 3, 4, 5, 6 ]
> arr.forEach((z)=>{res.push(z)})
undefined
> res
[ 1, 2, 3, 4, 5, 6 ]
```

map

```
> arr.map((x)=>{return 2*x})
[ 2, 4, 6, 8, 10, 12 ]
```

filter

```
> arr.filter((x)=>{return x%2===0})
[ 2, 4, 6 ]
```

reducer

```
> arr.reduce((stock,x)=>{return stock + x})
15
> arr.reduce((stock,x)=>{return stock + x},100)
115
```

keys (index)

```
> var tf_arr=[true,false,true,false,true,true]
> tf_arr.keys()
Object [Array Iterator] {}
> [...tf_arr.keys()]
[ 0, 1, 2, 3, 4, 5 ]
```

get keys of true

```
> [...tf_arr.keys()].filter((x)=>{return tf_arr[x]})
[ 0, 2, 4, 5 ]
```



same value array

```
> Array(4).fill(true)
[ true, true, true, true ]
```

zip

```
> zip=(x,y)=>{return x.map((v,k)=>{return [v,y[k]]})}
> zip([1,2,3],[4,5,6])
[ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
```







### for loops

iterrate

```
> for (const x in tf_arr){console.log(x)}
0
1
2
3
4
5
```

key  only

```
> dict={"a":1,"b":2}
> for (key in dict){console.log(key)}
a
b
```


key value  only

```
> for (const [key, value] of Object.entries(dict)) {console.log(key,value)}
a 1
b 2
```

enumerate

```
> for (const [k,v] of tf_arr.entries()){console.log(k,v)}
0 true
1 false
2 true
3 false
4 true
5 true
```



### 補足

arrow と func 一緒じゃない？ => 違う

挙動は同じ。けど、this 等が参照できない。Vue, React 使う場合はこれを気をつけるべき！

詳細は下記参照

https://stackoverflow.com/questions/34361379/are-arrow-functions-and-functions-equivalent-exchangeable
なぜwebアプリケーションはアップデートなしにUIや機能の変更ができるのか

※初学者のため間違っている部分などございましたらご指摘ください。

タイトルの通りですが、**「なぜWebアプリケーションはアップデートなしにUIや機能の変更ができるのか」**と疑問に思ったので調べてみました。
ググってもクリティカルな記事を見つけられなかったのでwebアプリケーションの構造から考えてみました。
Twitterのweb版はたまにUIや機能の変更がありますよね。最近だと、「予約投稿の機能」でしょうか。
こういった変更がアップデートなく使えるようになっているのはなぜだろうと思ったのです。
一方のスマホアプリだと、ストアでのアップデートがあるのでそこで変更がされていることはわかるわけですが。

#Webアプリケーションの構造
基本的なwebアプリケーションの構造はこんな感じ。
今回の話で重要になってくるのが、リクエストとレスポンスが**毎回行われる**という点。

![Webアプリのコピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326789/c7443ddc-6621-4acd-6ce7-89fb93277234.jpeg)

#開発部門も含めた構造
Twitter社内の開発も含めて書いてみました。今回は予約投稿の機能を例に取っています。
予約投稿機能の開発を終え、それをMasterブランチへMergeします。
そのMasterブランチを**デプロイ**するという流れになっています。

![Webアプリ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326789/b530891d-2a37-8b20-f15b-d88a590fd042.jpeg)

#デプロイが行われた時点で書き換わる
デプロイが行われた時点で変更が完了しています。
今回は、デプロイが行われた時点で「予約投稿機能」が追加されたWebアプリケーションに変わっているという事です。
その書き換わったアプリケーションにユーザーがリクエストを送る。
よって、アップデートなく機能が追加されたものにアクセスできるということになっているというわけです。

#最後に
結局、「デプロイ」があるから、アップデートなく機能の追加・変更が行われていることがわかりました。
「アップデートなく」というのも定義が難しいですね。
スマホのように**「ストアでのアップデートという作業がない」**という意味で、実際には裏側ではアップデート（コードの変更）が行われているという、、。
この辺の用語の使い分けってあったりするのでしょうか。

#参考書籍
[プロになるためのWeb技術入門](https://www.amazon.co.jp/%E3%80%8C%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8D-%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%E3%80%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B/dp/4774142352/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2XZVJOY9JQG4K&dchild=1&keywords=%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEweb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80&qid=1595164531&sprefix=%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%2Caps%2C127&sr=8-1)
AWSの内部通信で好きなドメインを使えるようにする

# はじめに
AWSの内部通信をしているときに、いくら内部通信とは言えデフォルトELB払い出しドメイン名を使うのは分かりにくいよね、ということでやり方を探してみたところ、内部通信であればRoute53のエイリアスレコードというものを使えば実現できるらしい。

[料金を確認](https://aws.amazon.com/jp/route53/pricing/)すると、ELBへのエイリアスへのクエリはなんと無料らしい。さすがにホストゾーンは料金がかかるようだが、それでもホストゾーン単位に$0.50/月程度。利便性を考えればおつりがくる金額だ。

さっそくやってみよう。

# いきなりIaC
なにげに、めちゃくちゃ設定簡単だった。
ALBまでリソースが作られているのであれば、以下で出来上がりだ。

今回のサンプルでは、VPCとNLBをinternal_hostzone_testというデータソース名で引っ張ってきている。
特に中身で難しいところはない。```type = "A"```がエイリアスレコードを意味する。

```HCL:route53.tf
resource "aws_route53_zone" "internal_hostzone_test" {
  name = "neruneruo.com"

  vpc {
    vpc_id = "${data.aws_vpc.internal_hostzone_test.id}"
  }
}

resource "aws_route53_record" "internal_hostzone_test" {
  zone_id = "${aws_route53_zone.internal_hostzone_test.zone_id}"
  name    = "www.neruneruo.com"
  type    = "A"

  alias {
    name                   = "${data.aws_alb.internal_hostzone_test.dns_name}"
    zone_id                = "${data.aws_alb.internal_hostzone_test.zone_id}"
    evaluate_target_health = true
  }
}
```

# ちょっとだけ罠
ホストゾーンの詳細を確認してみると、以下のような注意書きがされる。

> プライベートホストゾーンを使用するには、次の Amazon VPC 設定を true に設定する必要があります。
> enableDnsHostnames
> enableDnsSupport

この項目はデフォルトではONではないので注意が必要だ。
おそらく、VPCの設定画面では```enableDnsSupport```が「DNS 解決」、```enableDnsHostnames```が```DNS ホスト名```と書かれている設定だと思う。思う、と書いたのは、正しく項目を確認するのであれば以下のCLIを実行すれば値を得られるのだが、「DNS 解決」を無効にした時点でCLIすら通らなくなってしまうので、本当に正しいかが分からないのである……。

```
$ aws ec2 describe-vpc-attribute --vpc-id vpc-xxxxxxxxxxxxxxxx --attribute enableDnsSupport
```
```
aws ec2 describe-vpc-attribute --vpc-id vpc-xxxxxxxxxxxxxxxx --attribute enableDnsHostnames
```

# curlで確認
さて、ちゃんと確認してみよう。

```
$ curl -D - -s  -o /dev/null http://www.neruneruo.com/
HTTP/1.1 403 Forbidden
Date: Sun, 19 Jul 2020 13:11:57 GMT
Server: Apache/2.4.43 ()
Upgrade: h2,h2c
Connection: Upgrade
Last-Modified: Fri, 08 May 2020 17:01:39 GMT
Accept-Ranges: bytes
Content-Length: 3630
Content-Type: text/html; charset=UTF-8
```

うむ！なんかForbiddenにはなってしまったが、確かにApacheが応答してくれたから良しとしておこう！
redux-devtools にて JavaScriptのMapを表示


## tl;dr

```typescript
if (process.env.NODE_ENV !== 'production') {
  (Map.prototype as any).toJSON = function() {
    const obj = {};
    this.forEach((value: any, key: any) => obj[key] = value);
    return obj;
  }
}
```

そもそも、Mapのデータをdevtoolでは表示できないみたいです。
ですが、Mapに無理くり`toJson`を作ってあげれば、devtoolで表示できるようになります。
ReactNativeDebuggerでReduxのデータを確認しようと思ったのに表示できてないの原因がわからずハマりました。


## REF
- [Displaying Map in state · Issue #124 · zalmoxisus/redux-devtools-extension · GitHub](https://github.com/zalmoxisus/redux-devtools-extension/issues/124#issuecomment-221972997)
ewwでgithubのrawファイル閲覧すると捗る（Emacs）

## はじめに

Emacsのテキストブラウザewwの新たな可能性を発見してしまった。

github上のファイルをsyntax highlight効かせた状態で閲覧できる。

何が嬉しいか考えてみると、Emacs上でそのファイルベースに編集できたりするくらいだけど。

## ewwって

Emacsのテキストブラウザ。

`M-x eww`の後に表示したいページのurlを入力するとブラウジングできる。

`g`でリロード、`l`でhistory backとか

https://www.gnu.org/software/emacs/manual/html_mono/eww.html

## 手順

ewwでブラウジングしてgithubで閲覧したいファイルを開いたら、rawのリンクを辿ってrawファイルのページに遷移。

モードを対象ファイルのsyntax highlightできるモードに切り替える。

### 細かく書くとこんな感じ

* `M-x eww` -> https://github.com/npm/cli/blob/latest/lib/install.js -> `Enter`
* `Raw`の箇所にカーソル移動
* `M-x eww-follow-link`
* ファイルの内容が表示されるのを待つ
* `M-x js2-mode`

この後は`C-x C-w`とかで一旦別ファイルにしてから編集とかできる

## 参考

https://futurismo.biz/archives/2950

この方は`eww`を使い倒しているようで面白かった。
SASテクニック 幾何平均/幾何標準偏差の計算

# SASによる幾何平均/幾何標準偏差の算出

幾何平均とは...
高校で相加・相乗平均の関係をやったと思うが、あれの相乗平均のほう
詳しい計算はwikiみましょか
https://ja.wikipedia.org/wiki/%E5%B9%BE%E4%BD%95%E5%B9%B3%E5%9D%87

対数変換→平均値/標準偏差を算出→指数変換
で、幾何平均や幾何標準偏差を求めることができる

SASのmeansプロシジャでそのままでは出ないようだったので、いろいろ試してみた

R版
https://qiita.com/saspy/items/3403943d85b427937be3

# 使用するデータ
SASHELP.CLASSのHEIGHTでためす(ついでに性別ごとの計算にしてみる) 

```sas
data work.CLASS;
  set sashelp.CLASS( keep = SEX HEIGHT );
  if HEIGHT > 0 then LOGVAL = log( HEIGHT );
run;
proc Sort;
  by SEX HEIGHT;
run;
```

<img width="191" alt="class2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564185/7ed0c74c-0de1-880e-6b73-6c1372da35d5.png">

# ttestプロシジャによる方法
幾何平均、幾何CV(%化はしない)、幾何平均や幾何CVの信頼区間を算出する

※現実的ではないが、変数値がすべて同じ場合でも幾何平均の信頼区間が出てしまう
(log(幾何標準偏差)が0のため、計算できないはず)

classを使うと、2群の群間比も出せる
(class変数は2値、class変数 = "Ratio (1/2)"のレコードに群間比)

```sas
ods select none;
ods output ConfLimits = work.GEO_1( drop = UMP: );
proc Ttest data = work.CLASS dist = lognormal;
  by SEX;
  var HEIGHT;
run;
ods select all;
```

ods selectは指定しなくてもいいが、アウトプットにいろいろ出てきてうざいのでつけてる


# SQLプロシジャで直接的に計算する方法
とりあえず幾何平均、幾何標準偏差、幾何CVを計算
信頼区間もめんどいが式を書けば出せるはず

自然対数ってexp(1)以外に表せた気もするがわからん
追記:constant関数で数学定数を指定できるようで、constant( "e" )でokかな

```sas
proc Sql;
  create table work.GEO_2 as
    select 
      SEX ,
      exp( 1 ) ** ( mean( log( HEIGHT ) ) ) as GEOMEAN ,
      exp( 1 ) ** ( std( log( HEIGHT ) ) ) as GEOSTD ,
      100 * sqrt( exp( 1 ) ** var( log( HEIGHT ) ) - 1 ) as GEOCV
    from work.CLASS
    group by SEX
    order by SEX;
quit;
```

# meansプロシジャ&dataステップでがんばる方法
対数変換した値でもってるとか、
テストデータとかですべて同じ値のときはこっちがいいかも

```sas
proc means data = work.CLASS noprint nway;
  class SEX;
  var LOGVAL;
  output out = work.MEANS_RESULT( drop = _: )
    n = N mean = MEAN std = STD lclm = LCLM uclm = UCLM var = VAR;
run;

data work.GEO_3( keep = SEX N GEO: );
  set work.MEANS_RESULT;
  array STAT_VAR{*} MEAN STD LCLM UCLM;
  array GEO_VAR{*} GEOMEAN GEOSTD GEOLCLM GEOUCLM;

  do i = 1 to dim( STAT_VAR );
    GEO_VAR{i} = exp( 1 ) ** STAT_VAR{i};
  end;
  GEOCV = 100 * sqrt( exp( 1 ) ** VAR - 1 );
run; 
```

# 結果
<img width="580" alt="geo1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564185/81e1a421-c19a-28ef-e459-4436fe60f6c0.png">

geomeanって関数もあるようなので、
横に転置してgeomean関数使うのもあり
surveymeansプロシジャでも出せる


https://www.sas.com/offices/asiapacific/japan/service/technical/faq/list/body/stat058.html
https://documentation.sas.com/doc/ja/pgmsascdc/9.4_3.4/statug/statug_surveymeans_syntax01.htm
【C#】非同期メソッドの呼び出しでNULL条件演算子 ？. を使ってもNULL参照例外を起こす

## `null`条件演算子`?.`で安全に参照型にアクセスできるはず...

`?.`を使うと`null`かもしれない参照型に安全にアクセスすることができます。
`?.`はアクセスの前に、左辺が`null`かどうかテストし`null`でない場合、アクセスが行われます。

下記コードなら`httpResponse.Content`が`null`でも`null`参照例外をスローしないと考えました。

```csharp
HttpResponseMessage httpResponse = await this.httpClient.SendAsync(httpRequest);
// null かもしれない参照型の非同期メソッドを呼び出す
string content = await httpResponse.Content?.ReadAsStringAsync();
```

しかし、 `Content`が`null`の場合、参照例外がスローされました。

```shell
System.NullReferenceException: Object reference not set to an instance of an object.
```

## 何が起こったか

`?.`演算子は`?.`の左辺が`null`の場合、`null`が返します。

```csharp
await httpResponse.Content?.ReadAsStringAsync();
```

**`Content`が`null`の時、`null`を`await`してしまっています。**

## どう解決したか

`??`（`null`合体演算子）を使い、`?.`が`null`を返した時に`Task`を返すようにします。
今回は`Content`が`null`の時は空文字が欲しかったので以下のようにしました。

```csharp
HttpResponseMessage httpResponse = await this.httpClient.SendAsync(httpRequest);
// ※実行順序を正しくするため`await`する内容を`()`で囲む必要があります。
string content = await (httpResponse.Content?.ReadAsStringAsync() ?? Task.FromResult(string.Enmpty));
```

戻り値がない場合は、`Task.CompleteTask`を使い以下のようにします。

```C#
await (this.FooService?.BarAsync() ?? Task.CompleteTask);
```

これで`null`かもしれない参照型の非同期メソッドを安全に呼び出すことができました。
結構見逃しやすい部分ですので注意したいと思います。
【備忘録】pyqtとopencvでQtのライブラリが競合した場合の対処法

2021/02/25 追記：知らない間に`opencv-python`の[最近のアップデート](https://github.com/opencv/opencv-python/commit/fd4e6040af94d9db3da25874132ca092b4c9e3a1)で修正されたようです。

# 症状
概要はタイトル通り。詳細は以下の通り。

## 環境
| 条件   |内容|
|:------|:--|
| OS    |macOS Catalina 10.15.6 |
|python環境 | pyenv + Anaconda2020-02/miniconda3-latest |
|- Pyqt5 | 5.15.0 |
|- opencv-python|4.3.0|


## 内容
`opencv-python`と`PyQt5`を同時使用するプログラムを実行したところ、長ったらしいエラーメッセージと共に強制終了。

```
objc[54311]: ClassQMacAutoReleasePoolTracker is implemented in bot /Users/hogehoge/opt/anaconda3/lib/python3.7/site-packages/PyQt5/Qt/lib/QtCore.framework/Versions/5/QtCore (fugafuga) and /Users/hogehoge/opt/anaconda3/lib/python3.7/site-packages/cv2/.dylibs/QtCore (fugafuga). One of the two will be used. Which one is undefined.
objc[54311]: Class QT_ROOT_LEVEL_POOL__THESE_OBJECTS_WILL_BE_RELEASED_WHEN_QAPP_GOES_OUT_OF_SCOPE (同上).
objc[54311]: Class KeyValueObserver (同上).
objc[54311]: Class RunLoopModeTracker (同上).
(中略)

You might be loading two sets of Qt binaries into the same process. Check that all plugins are compiled against the right Qt binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.
qt.qpa.plugin: Could not load the Qt platform plugin "cocoa" in "/Users/hogehoge/opt/anaconda3/lib/python3.7/site-packages/cv2/qt/plugins" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: cocoa, minimal, offscreen, webgl.
```
もうまずこのメッセージ量で諦めかけた。けどやらないわけにはいかなかった。

# 原因
とりあえずこいつが脳死で参照しているopencvのQtのpluginフォルダを見に行ったらほぼ空っぽ。importの順番かアルファベット順かはちゃんと確認してないけど、こいつが原因のようで。

# 試行錯誤

参考: https://qiita.com/sukoppu1102/items/f5c00b520da0fa5d2ff3

windowsでの不具合だが、エラー箇所が似ている。試しに`QT_PLUGIN_PATH`をPyQtのほうに入れてみる

結果：ダメ

# 解決法
(2021/02/25修正)
最近修正されたようで、最新版にアップデートすると問題なく動作します。

- https://github.com/opencv/opencv-python/commit/fd4e6040af94d9db3da25874132ca092b4c9e3a1

```
pip install -U opencv-python
```
Python3 エンジニア認定基礎試験

2020年3月15日(日)にPython3 エンジニア認定基礎試験を受験しました。
一応、合格したので記事を書いておきます。
少しでも次受ける方の参考になれば幸いです。

## 受験理由
■１ Pythonに興味があったから。
■２ Pythonを用いて機械学習などおこないたいと思い、その最初の一歩とするため。

## 感想
■１ 比較的簡単です。主教材『Pythonチュートリアル 第3版（Guido, 鴨澤（訳）, 2016, オライリージャパン）』を読み、[DIVE INTO EXAMの模擬試験](https://exam.diveintocode.jp/exam)を受けて満点取れるようになれば大丈夫だと思います。模擬試験で満点が取れるというのは、「なぜ正解か」「なぜ間違っているか」が全て分かったうえで、満点が取れるという意味です。ただ、正解を覚えるだけでは落ちるかもしれません。また、2020年7月19日時点では、[プライム・ストラテジーでも模擬試験](https://study.prime-strategy.co.jp/)が受けられるようですので、これも試してみてもよいかもしれません。
■２ 主教材が難しい場合は、特にプログラミング初めての方は『スラスラ読める Pythonふりがなプログラミング (ふりがなプログラミングシリーズ)（リブロワークス, 2018, インプレス）』を読んで、次にもう少し難しめの本『Pythonエンジニア育成推進協会監修 Python 3スキルアップ教科書（辻ら, 2019, 技術評論社）』などを読んでから、主教材を読んだ方がよいかもしれません。
	
## 学習教材
■１ スラスラ読める Pythonふりがなプログラミング (ふりがなプログラミングシリーズ)（リブロワークス, 2018, インプレス）
・・・ プログラム超初心者用：ほとんどプログラム組んだことない方は、とりあえず、読んだ方がよいと思います。
■２ Pythonエンジニア育成推進協会監修 Python 3スキルアップ教科書（辻ら, 2019, 技術評論社）
・・・ プログラム初心者用：超初心者を卒業したら初心者用のこれを読みましょう。
■３ Pythonチュートリアル 第3版（Guido, 鴨澤（訳）, 2016, オライリージャパン）
・・・ プログラム初心者用：主教材ですが、オライリーの本は人によっては読みにくいと感じるようですので（私は読みにくかったです）、他の本で慣れてから読んだ方がよいです。読みにくいですが、主教材ですので、この本で勉強した方がよいです。
■４ DIVE INTO EXAMの模擬試験
・・・有名な模擬試験：とにかく満点が取れるまで何度も解きましょう。

## 学習方法
■１ 『スラスラ読める Pythonふりがなプログラミング』を7割ほど読み、Pythonに慣れたら、『Pythonエンジニア育成推進協会監修 Python 3スキルアップ教科書』を読み進めます。これも5割ほど読んだら、主教材『Pythonチュートリアル 第3版』を読み進めます。全部の本を完全に読み終わらなくてもよいので、DIVE INTO EXAMの模擬試験を解きます。模擬試験で間違えた箇所を上記の本で確認しながら、Pythonの理解を深めます。という感じで、初めてのプログラムの本で心が折れないように、模擬試験を解きながら、ちょっとずつ主教材を読んでいきました。

## 反省点
■１ 特になし。

## 試験前にやっておいてよかったこと等
■１ 模擬試験を全て完全に理解できるまで学習したこと。
【Solidity】Payable関数とWithdraw関数

コントラクトに対してEtherを送金することができます。
また、送金されたコントラクトは、受け取ったEtherを別のアドレス（例えばコントラクトを作成した人のアドレス）に送金することもできます。

送金を受け取る関数がPayable、送金するのがWithdraw関数になります。

それぞれの例は以下の通りです。

```Solidity
contract ManagementEther {
  address public owner;

  // コンストラクタ
  function ManagementEther() public {
    owner = msg.sender;
  }

  // payable修飾子を付けることでetherを受け取れるようになる
  function receiveEther() external payable {
    // 送金されたetherの値は`msg.value`で取得可能
    // 何かしらの処理を行う
  }

  // withdraw関数
  function withdraw() external onlyOwner {
    // オーナーのみ実行可能
    require(msg.sender == owner);
    // コントラクトのオーナーのアドレスにこのコントラクトのetherの残高を送金する
    owner.transfer(this.balance);
  }
}
```
この例ではreceiveEtherがpayable関数になります。
関数にpayable修飾子を付けます。
送金されたetherはmsg.valueで取得することができます。

withdraw関数はそのままwithdrawという名称の関数を作成します。
ここではこのコントラクトを作成したオーナーのみ実行可能にしています。
this.balanceでこのコントラクトに蓄積されているetherの残高を取得できます。
ここでは、オーナーのアドレスに全残高を送金しています。

このようにSolidityでは簡単にetherの受け取り、送金の関数を実装することができます。
もう怖くない！Internet Explorer対応

# もう怖くないInternet Explorer対応
IE！それはエンジニアを恐怖に陥れるブラウザ
IE！それは実装を先んじすぎたがために滅びることとなったブラウザ

奢れるものも久しからず、ただ風の前の塵に等しい…

我々はこの滅びゆくブラウザに対しても対応を行わなければならないことが時折発生します。
そのため、ここに基本的なInternet Explorerへの対応方法をまとめ、しるすことにしました。

※この記事はIE11への対応を想定していますが、Androidブラウザのような他のブラウザやIE11以前のものに対してもこの考え方は役に立つ部分があるでしょう。

~~BtoCで一般の人が使うなら、仕方がありませんが、IE11以外のIEに対応してくれと言ってくるような、セキュリティ意識の低い会社とは取引しないようにしましょう。~~

# IE対応って何するの？
IE対応とは、もちろんIEでWEBアプリケーションを動くようにすることなのですが
実際には、何をしたらIE対応をしたことになるのか、考えてみましょう。
そうすると、IE対応では以下の2つのことをすればよいことがわかります。

* IEにはない機能を追加すること。
* IEと他のブラウザで機能に差異がある部分を吸収する。

これを突き詰めていけばIE対応はもう怖くない！

## IEと他のブラウザで機能に差異がある

### デザイン崩れを調整する

IEで表示すると、デザインが崩れてしまうことがあります。
実はこれが一番面倒で、対応もまちまちになってしまいます。
主に、flexboxを使おうとしたときにデザイン崩れが起こりがちです。
IE対応の必要なアプリケーションを作成する際にflexboxを使用する場合は、早い段階でIEでデザインを確認するようにしたほうがよいでしょう。

### User-Agentによって、処理を変える

特にプレフィクスつきの機能に多いのですが、Chromeなどのモダンなブラウザと挙動が違うものがあります。
この場合、User-Agentを見ることで、処理を変えるのが妥当でしょう。
もしも、現存の機能だけで、再現するのが難しい場合（暗号回りで使いたいアルゴリズムがないなど）はポリフィルを探してみるのもよいかもしれません。

### セキュリティ設定の罠

IEでは、セキュリティ設定を変えないと使用できない機能があります。
これを見逃すと、エラーが出ずに黙って処理が終わることもあるので、使う機能がセキュリティ設定によって、制限されていないか？はしっかり確認しましょう。場合によっては、IEのためにユーザマニュアルを書き換えないといけない場合もあるかもしれません。

ちなみに私はpostMessageを使用していて、ローカル開発環境は同ドメイン、共通開発環境は違うドメイン同士で通信させていたところ
共通開発環境のみで、機能が動作せずそれで半日ほど溶かしたました・・・

## IEにはない機能を追加する
IEは古いブラウザです。そのため、最新のブラウザには標準でついていても、IEにない機能がたくさんあります。
それらを追加することから始めましょう。

### ポリフィルを使う
ポリフィルとは、JavaScriptで使えない関数やオブジェクトをJavaScript自体で実装することによって、他のブラウザと同様に使用できるようにする手法です。
有名どころだと、Babel-polyfillやPolyfill.ioなどがあります。

ただし、最新の機能だと、上記のライブラリにまだ追加されていない関数やオブジェクトがある場合があります。
その場合、これらの既に出来上がっているポリフィルを使うほかに自分で実装する方法もあります。
大体以下のような実装になることが多いです。

``` JavaScript
// hogehogeという関数がObjectにない場合
if (Object.prototype.hogehoge === undefined) {
  Object.prototype.hogehoge = function () {
    /**
     * 実際の処理
     */
  }
}

// Fugaというオブジェクトが存在しない場合
if (window.Futa === undefined) {
  Fuga = function () {};
  Fuga.prototype.toString = function () {
    return "[Object Fuga]"
  }
  /**
   * 他の機能
   */
}
```

自分で実装することになった場合、MDNで情報をしっかり読み仕様を把握したり
Chromiumのソース上に（Chromeにその機能があるなら）実装があるはずなので、探してどんな処理を行っているのか見てみるのがよいでしょう。

### トランスパイルする

トランスパイルはIEで使えないJavaScriptの構文を使える形に変換する手法です。（他の使われ方もしますが）
IEのJavaScriptでは最新の構文（スプレッド構文やasync await）は使用できないうえに、パーシングの時点でエラーが出てしまうので
別の記法に置き換えなければならないのです。
（スプレッド構文であれば、Object.assign async await であれば、単純なコールバックなど）
よく使用されるのは、Babel-polyfillです。

### 代替の実装を行う

WebSQLや、新しいCSSプロパティなどのIEでは使用できない機能が元のアプリケーションで使われていた場合、代替の実装を行うことを考えましょう。例えばWebSQLであれば、localStorageなどのWebStorageを使用することができますし、CSSであれば、古いプロパティの組み合わせで新しいプロパティをできるだけ再現することで対応ができます。

### そもそも、これIEじゃ不可能なのでは？

ここでは、例としてNotification APIに関して考えてみます。
Notification APIはブラウザがOSに対して通知を送るための機能です。ところが、IEではこの機能は実装されていませんし、ブラウザ上のJavaScriptだけではこれを再現することは不可能でしょう。
こういったときは、IEで対応することをあきらめるか、どうしても必ず必要なんだ！という場合は、別のクライアントアプリを作成し、通知を受け取らせるしかありません。
設計段階で、これを考慮していないと致命傷になります。
使用しそうな機能が本当にIEに存在しているかは、対応することが決まっているのであれば、必ず確認しましょう。
着せ替え時の名前衝突を避けるためだけのリネームスクリプト

（追記）[githubリポジトリ](https://github.com/hibit-at/ObjectRenamer)

　知り合いが必要そうだったので。
　後で余裕があれば解説とか書きます。

```C#
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;

public class MenuItemTest : MonoBehaviour
{
    [MenuItem("CustomMenu/Rename %t", false, 1)]
    static void OutputConsole()
    {
        Transform[] transformArray = Selection.activeGameObject.GetComponentsInChildren<Transform>();
        foreach (Transform e in transformArray)
        {
            if (e.name == Selection.activeGameObject.name) continue;
            e.name = e.name + "_" + Selection.activeGameObject.name;
        }
    }

    [MenuItem("CustomMenu/DoubleCheck %u", false, 1)]
    static void OutputConsole2()
    {
        List<string> check = new List<string>();
        Transform[] transformArray = Selection.activeGameObject.GetComponentsInChildren<Transform>();
        foreach (Transform e in transformArray)
        {
            if (check.Contains(e.name) == true)
            {
                e.name = e.name + "_1";
            }
            check.Add(e.name);
        }
    }
}
```

　以下、追記

#使用例（なにをするスクリプトか）1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/51f78832-3398-f4dd-9f2d-0e2fead890f5.png)

　ヒエラルキーの先頭を押した状態で`Ctrl + T`を押すと、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/65fb78b5-e61d-7877-5005-8008d35feca9.png)

　こうなります。

#使用例（なにをするスクリプトか）2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/31ae4df8-d0fc-2e2b-60cb-b20caaf001fe.png)

　ヒエラルキーの先頭を押した状態で`Ctrl+U`を押すと、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/3e4681d1-c9ef-8272-38d9-0edea323dc08.png)

　こうなります。

#理由（なぜこれが必要か）
　VRMをエクスポートする際、ヒエラルキーに同じ名前のオブジェクトがあるとエラーになってしまいます。一方、あるモデルに別のモデルを組み合わせるには、つまり服を着せ替える場合がほとんどなのですが、着せ替え先のボーンと、着せ替え元の対応するボーンを親子関係にする方法が一般的です。この結果、両者が同じボーンの名前（`Neck`とか`Chest`とか）を持っていた場合、上に述べたエラーを引き起こしてしまいます。これを防ぐには、オブジェクトの名前を変える必要がありますが、リボンや髪などは時に数十個のボーンが設定されていることがあるため、中々の手間になります。そこで、リネームだけを一括して行うスクリプトを作成しました。

#方法
　プロジェクトのAssets内に適当に`C# Script`を作って、上のコードをコピペしてください。エディタに戻って、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/aa43d779-d535-ebbe-6c8c-0dbad7194b0f.png)

　このようなメニューが表示されていれば適用成功です。後は`Ctrl+T`や`Ctrl+U`を押せばスクリプトが実行されます。

#お世話になったページ

[UnityのEditorを拡張して自前のメニュー項目を表示する](https://gametukurikata.com/customize/editor/menuitem)
[Unity 直下の子供を取得 / 直下以下の子供を再帰的に取得 方法](https://peroon.hatenablog.com/entry/2014/12/11/221001)
Webサーバ(Apache 2.4系）へのHTTPアクセスをHTTPSにリダイレクトさせる設定

# Webサーバ(Apache 2.4系）のHTTPアクセスをHTTPSにリダイレクトさせる設定
 Apache 2.4 で構築したWebサーバで、Webページを公開しており、そこにhttpアクセスがあった際に httpsへリダイレクトさせる設定を行います。常時SSL化が最近のデフォルトなので、httpアクセスをさせる意味もないですしね。
# 前提条件
 [Amazon EC2(Linux)で構築したWebサーバ(Apache)のSSL設定](https://qiita.com/u-bayashi/items/dfe440ae07d5eee1d2f6)の設定まで完了している、もしくは同様の状態であること。
要するにSSLサイト化されていることが前提となります。 

# 実際にやってみた
 /etc/httpd/conf/httpd.conf に以下を追記するだけ

    RewriteEngine on
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# おまけ
 IPアドレスを直アクセスも拒否したい場合は以下の設定を行います。

 /etc/httpd/conf.d/ssl.conf に以下を追記

    <VirtualHost *:443>
    ServerName any
    <Location />
    Order deny,allow
    Deny from all
    </Location>
   </VirtualHost>

 続いて59行目、60行目付近の以下の行の先頭#を消して、修正
　DocumentRoot "/var/www/html"
　ServerName "サーバ名"

# 参考にしたページ
[ApacheでIP直打ちのHTTPSアクセスを拒否したい](https://teratail.com/questions/232309)
[Apacheのリダイレクト（転送）設定、httpからhttpsとか](https://qiita.com/matsu_qiita/items/67558d36a6b825d80645)
AP試験ーAIの機械学習手法

応用情報技術者令和元年秋期 午前問4
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/fd8138be-d8d0-81e9-003a-b4857ce9d66d.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/09fd5232-1548-5643-e3e2-cd3fe0dc2667.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/c8c99923-f4de-d462-e8c5-0d3f34e50a61.png)


参考：
https://www.ap-siken.com/kakomon/01_aki/q4.html
文字列内の数字を指定し、計算をする方法

PHP学習中の駆け出しエンジニアです。
文字列から数字だけを取り出して計算をするときの方法を備忘録として残します。

例えばこんな文字列があったとする。

```
$string = '123456789';
```

###ここから4と7だけを取り出して足した計算結果を出力したい場合を考える。

調べていると文字列の一部分を返すsubstr関数なるものを発見！
https://www.php.net/manual/ja/function.substr.php

substrを用いることで、指定した変数から、０から始まる指定した文字列を返すことができる。その際、指定した文字列からいくつ返すのかを指定できる。

例えばこんな感じで返してくれる。
計算を行うため文字列からの変換を忘れずに

```
$number５ = (int) substr($string, 4, 1);
echo $number5;
//出力結果 ５

$number234 = (int) substr($string, 1, 3);
echo $number234;
//出力結果 234
``` 

###ここから4と7だけを取り出して足した計算結果を出力するならば...

```
$number4 = (int) substr($string, 3, 1);
$number7 = (int) substr($string, 6, 1);
// $number7 = (int) substr($string, -3, 1);でも上と同じように数字を返してくれます。

echo $number4 + $number7;
//出力結果 11
```

このように計算を行うことができます。

もちろん、文字列から指定した文字を返してくれる関数なので、上記のような計算以外使うことも可能ですし、むしろそっちがメインだと思います、、、

他にもっと良い方法があるかもしれないので、ご教授いただければ幸いです。
We recommend using useRef() or createRef() instead. Learn more about using refs safelyというエラーが表示された場合の解決方法　[react]

#このエラーが表示される理由
以下のコードのように、DOMを参照する時にrefsを使った時にタイトルのエラーが出た。

```index.js
 componentDidMount() {
    const config = {
      delay: 150,
      duration: 2000,
    }

    ScrollReveal().reveal(this.refs.parallax, config)
  }

// このDOMを参照している
<div className="container" ref="parallax>
```

和訳するとrefs代わりにuserRef()やcreateRef()を使ってや〜という意味。

調べると、refsでDOMを参照するとその要素のDOMの構造を触った時などバグになりやすいから
使わないようにしてとのことだった。

#解決方法
以下のコードで解決した。

```index.js
constructor() {
    super()
    this.containerRef = createRef()
  }

  componentDidMount() {
    const config = {
      delay: 150,
      duration: 2000,
    }

    ScrollReveal().reveal(this.containerRef.current, config)
  }

 <div className="container" ref={this.containerRef}>
```

解説すると、
 this.containerRef = createRef()でreact参照を作成し、
それをcontainer要素に渡している。
これでcontainerクラスを参照することができるようになった。

this.containerRef.currentにはcontainerのDOMがある。

#参考サイト
https://blog.logrocket.com/a-guide-to-react-refs/
統計検定3級

2020年7月5日に統計検定3級を受験しました。
一応、合格したので記事を書いておきます。
少しでも次受ける方の参考になれば幸いです。
※G検定受けて翌日に統計検定受けたので疲れました。

## 受験理由
■１ 統計に関しての理解を深めるため。

## 感想
■１ 過去問（紙媒体の過去問）とCBT（Computer Based Testing）方式で傾向が違いました（あくまで私の主観ですが）。また、自分はCBT方式が物凄く苦手なため、過去問よりも点数がかなり下がりました。
■２ 電卓が苦手な方は、面倒な計算以外、頭の中で計算してしまった方が早いです。卑怯ですが、とりあえず、問題をざっと見るときに全解答にチェック（例えば、１にチェックするとか）をいれて、解いた方が精神的に安定した状態で問題が解けます。計算問題は焦れば、焦るほど解けなくなりますので、落ち着いて解けるのは重要だと思います。
■３ 確率苦手な私の主観が入っているかも知れませんが、CBT方式は過去問よりも確率の問題が多めに出たと思います。確率が苦手な方は、確率の勉強を重点的にした方が良いと思います。
	
## 学習教材
■１ 日本統計学会公式認定 統計検定 3級・4級 公式問題集 2016〜2018年（日本統計学会 (編), 2019, 実務教育出版）
・・・ 過去問：解いた方がよいですが、CBTとは少し傾向が違います（あくまで私の主観です）。
■２ 改訂版 日本統計学会公式認定 統計検定3級対応 データの分析（日本統計学会 (編), 2020,  東京図書）
・・・ 統計検定3級の公式テキスト：結構よいです。2級ダメだった方はここから勉強してもよいかもしれません。

## 学習方法
■１ 過去問を解く。
・・・私は時間がなく1年分しか解けませんでした。
■２ 公式テキストを読む。
・・・こちらも時間がなく、パラパラとページをめくり、苦手な箇所や知らない箇所のみ読みました。CBTは確率の問題が多く出るという認識でしたので、確率のページのみ読みました。

## 反省点
■１ とにかく勉強する時間がとれなかったので、もっと勉強してから受験したかった。

## 試験前にやっておいてよかったこと等
■１ 確率の問題を当日に確認した。たぶんこのおかげで受かったと思う。
firebaseのapiKeyは公開しても良いのか

こういうやつ

```js
  // Your web app's Firebase configuration
  var firebaseConfig = {
    apiKey: "168aaAABcdDeEfFggGIImMOppPRssSUvxXyYzZZ",
    authDomain: "foobar.firebaseapp.com",
    databaseURL: "https://foobar.firebaseio.com",
    projectId: "foobar",
    storageBucket: "foobar.appspot.com",
    messagingSenderId: "012233455679",
    appId: "1:012233455679:web:0011112233445677889aff",
    measurementId: "G-0099BEPSVV"
};
```

## 結論

公開されても良い

## 何故

適切にセキュリティルールが組まれていれば漏れても大したことは出来ない

そもそも、firebase HostingでWebサイトを公開すると `/__/firebase/init.js` で勝手に公開される

https://firebase.google.com/docs/hosting/reserved-urls#sdk_auto-configuration
ログイン画面作成（備忘録）　section72(完)

次に　書き直し機能　を追加する
書き直すためにindex.phpに戻ると記入した値がリセットさせてしまう。

これを防ぐために「書き直し」のリンクを作って値が残るように記述していく。
ここで問題になるのが、index.phpを呼び出した際に、
初めて呼ばれたのか、書き直しリンクから呼ばれたのか分からないので
「URLパラメータ」を使って実装していく。
![スクリーンショット 2020-07-19 20.21.05（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614211/38832c56-a896-4f10-5b2d-77495ff2e2a1.png)

書き直しの場合は、URL後半で action=rewrite という状態になっているので
こちらを利用することにする。

index.phpのエラーチェックコードの下に以下を記述していく。

```
if($_REQUEST['action'] == 'rewrite' && isset($_SESSION['join']){
	$_POST = $_SESSION['join'];
}
```
`$_REQUEST['action'] == 'rewrite'`は「もしURLにURLパラメータ（今回はrewrite）が付いていれば、、」
且つ
「'$_SESSION['join']'に値が入っていれば、、、」
という記述となる。

index.phpが呼ばれた時にURLパラメータが付いていれば、
`$_SESSION['join']`の値を$_POSTに代入する
正規表現置換メモ

# ページ名と表示名が異なるWikiリンクをつける
## 正規表現
```regex:find
\|([sS]?(\d)-\d+)\|
```

```regex:replace
|[[$1>$2章/$1]]|
```

## 適用サンプル
```wiki:適用前
|1-2|
|4-10|
|S5-3|
```

```wiki:適用後
|[[1-2>1章/1-2]]|
|[[4-10>4章/4-10]]|
|[[S5-3>5章/S5-3]]|
```
No such module'Realm Swift'のエラー解消

まずはcocoaPodsでxcodeのバージョンにあったRealmを入れているか確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521125/4d4ec152-145d-60a5-c63c-6e840eab8acb.png)
画像の「Calendar]のところ→Manage Schemes→RealmSwiftの全部チェックを外してclose→
メニューバーのproduct→Scheme→New Schemeで新しいRealmを追加→クリーンビルド