OmniAICreator/Qiita-1.07M huggingface dataset:
ネットワークプログラミングのメモ

# C言語を使ったネットワークプログラミング
Cを使ったネットワークプログラミングを始めたのでそのメモ

## socketとは
ソケットは、ネットワークを超えてプロセス同士が互いに通信を行うことを可能にするもの。
参考:
「 https://qiita.com/Michinosuke/items/0778a5344bdf81488114 」
「 http://chokuto.ifdef.jp/advanced/function/socket.html 」
### 実装
```C
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main () {
    int sockets;

    sockets = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (sockets < 0) {
	    printf("socket failed\n");
	    return 1;
    } else
    {
        printf("socket success\n");
	    return 0;
    }
}
```

## TCPを用いた通信の実装
server sideのプログラム

```C
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int
main()
{
 int sock0;
 struct sockaddr_in addr;
 struct sockaddr_in client;
 int len;
 int sock;

 sock0 = socket(AF_INET, SOCK_STREAM, 0);

 addr.sin_family = AF_INET;
 addr.sin_port = htons(12345);
 addr.sin_addr.s_addr = INADDR_ANY;
 bind(sock0, (struct sockaddr *)&addr, sizeof(addr));

 listen(sock0, 5);

 len = sizeof(client);
 sock = accept(sock0, (struct sockaddr *)&client, &len);

 write(sock, "HELLO", 5);

 close(sock);
 close(sock0);

 return 0;
}
```
client sideのプログラム

```C
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int
main()
{
 struct sockaddr_in server;
 int sock;
 char buf[32];
 int n;

 sock = socket(AF_INET, SOCK_STREAM, 0);

 server.sin_family = AF_INET;
 server.sin_port = htons(12345);
 server.sin_addr.s_addr = inet_addr("127.0.0.1");

 connect(sock, (struct sockaddr *)&server, sizeof(server));

 memset(buf, 0, sizeof(buf));
 n = read(sock, buf, sizeof(buf));

 printf("%d, %s\n", n, buf);

 close(sock);

 return 0;
}
```
【活性化関数】SwishがReLUより精度が良い

2017年に発表されたSwish。ReLUより性能が良いと言う記事を見かけたので、論文を読んでみることに


<h1>結論</h1>
最初から結論をいうと、知りたかったなんでReLUより性能が良かったかという理由はあまり記載されてなかった。関数のsmoothnessが大切だという記載はあったが。
「ランダムに活性化関数を実験ベースでReLUと比較して精度が良かったのがSwishだった」という内容の論文だった。



<h1>実験の結果</h1>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/15c3fc2a-eda0-7bd3-2d6a-7026be7c20c9.png)

Mobile NASNet-AではSwishが一番結果が良いことが分かる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/13c21c42-700a-367d-a0db-47f86d846187.png)

さらに複数モデルで比較した場合に、Swishは他の活性化関数よりほとんどの場合outperformしてる事が分かる。
モデルによっても多少差があるようだ。




<h1>参考文献</h1>
SEARCHING FOR ACTIVATION FUNCTIONS
https://arxiv.org/pdf/1710.05941.pdf
[Chrome80以降] document.cookie によるCookie生成時のSameSite属性について

# 課題
Chrome 80 以降、CookieのSameSite属性がデフォルトで**Lax**になる。
> [Chrome 80が密かに呼び寄せる地獄 ～ SameSite属性のデフォルト変更を調べてみた](https://qiita.com/ahera/items/0c8276da6b0bed2b580c)

しかし、Chrome 80 以降で、\<script> タグ内等の 

```js

document.cookie="test=123"
``` 

によって生成されたCookieを Developer Tools で確認してみても、SameSite属性が**Lax**扱いとなっていないように見える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287824/884fc40e-f94b-5cf0-a733-954111b89524.png)

実際のCookieの挙動が **None** 扱い か **Lax** 扱いかわからない。

# 結論


**見た目SameSiteが指定されていないように見えても、Laxが付与されたCookieと同じ挙動をする**ようになっているとのこと。**※1**

**※1** 言質取ってきた: https://github.com/GoogleChromeLabs/samesite-examples/issues/42#issuecomment-709240567

# まとめ
公式のdocumentが分かりづらいので修正を打診する。
> https://github.com/GoogleChromeLabs/samesite-examples
ServiceNow - 添付ファイルを別ServiceNowインスタンスのレコードに追加する

#概要
インシデントレコードの添付ファイルを別ServiceNowのインシデントレコードに添付するスクリプトです。
ServiceNowフォーラムに挙げられていた質問です。

```
var user=<user>;
var pwd =<password>;
var instance = <ServiceNow instance>;
var fromTablename = 'incident';
var fromIncidentNumber = <incident number to copy attachments from>;

var toTablename = 'incident';
var toIncidentNumber = <incident number to attach file to>;

try {
	var sysRequest = new sn_ws.RESTMessageV2();
	sysRequest.setRequestHeader("Accept","Application/json");
	sysRequest.setRequestHeader("Content-Type","Application/json");
	sysRequest.setBasicAuth(user, pwd);
	sysRequest.setHttpMethod('get');
	sysRequest.setEndpoint('https://' + instance + '.service-now.com/api/now/table/incident?sysparm_query=number%3D' + toIncidentNumber + '&sysparm_fields=sys_id&sysparm_limit=1');
	var sysResponse = sysRequest.execute();
	var sysHttpResponseStatus = sysResponse.getStatusCode();
	if (sysHttpResponseStatus == 200) {
		var jsonObj = JSON.parse(sysResponse.getBody());
		var toTableRecordSysId = jsonObj.result[0].sys_id;

		var grFromTable = new GlideRecord(fromTablename);
		grFromTable.addQuery('number', fromIncidentNumber);
		grFromTable.query();
		while(grFromTable.next()) {
			try {
				var fromIncidentSysId = grFromTable.sys_id;

				grFromAtt = new GlideRecord('sys_attachment');
				grFromAtt.addQuery('table_name', fromTablename);
				grFromAtt.addQuery('table_sys_id', fromIncidentSysId);
				grFromAtt.query();
				while(grFromAtt.next()) {
					var filename = grFromAtt.file_name;
					var fromIncidentSysId = grFromAtt.sys_id;
					var contentType = grFromAtt.content_type;

					var request = new sn_ws.RESTMessageV2();
					request.setRequestHeader("Accept","Application/json");
					request.setRequestHeader("Content-Type", contentType);
					request.setBasicAuth(user, pwd);
					request.setHttpMethod('post');
					request.setEndpoint('https://' + instance + '.service-now.com/api/now/attachment/file?table_name=' + toTablename + '&table_sys_id=' + toTableRecordSysId + '&file_name=' + filename);
					request.setRequestBodyFromAttachment(fromIncidentSysId);
					var response = request.execute();
					var httpResponseStatus = response.getStatusCode();
				  
					gs.info("http response status_code: " + httpResponseStatus);
				}       
			}
			catch (ex) {
				gs.info(ex.message() + ' ' + response.getErrorMessage());
			}
		}
	}
} catch(ex) {
	gs.info(ex.message() + ' ' +  sysResponse.getErrorMessage() );
}
```
Nuxt.jsとFirebaseでログインとログアウトと維持「個人メモ」

Googleでログイン、返ってきた値をstoreで。

```
    const provider = new firebase.auth.GoogleAuthProvider();
    firebase.auth().signInWithPopup(provider).then(function(result) {
```

現在のサインインしてる状態を確認
https://stackoverflow.com/questions/37873608/how-do-i-detect-if-a-user-is-already-logged-in-firebase

```
var user = firebase.auth().currentUser;
```


サインアウトして画面移動
https://stackoverflow.com/questions/54593785/how-to-redirect-to-home-page-after-logout-in-nuxt

```
export default {
  name: 'HeadeAfterLogin',
  methods: {
    LogOut() {
      localStorage.removeItem('token')
      this.$router.push('/')
    }
  }
}
```
Jupyter Notebookをコード非表示にし改ページ入れてPDF出力する

調べて一旦落ち着いたやり方を、ここにまとめておきます。

#目的
- 簡易な報告の場でJupyter Notebookで分析したアウトプットをそのまま見せたい（Power Pointに貼り付けて加工したくない）
- コードを非表示にしてスッキリ見せたい
- 配布用にNotebookをPDF化する際、改ページくらいの体裁は整えたい

#動作環境

下記の環境で動作確認しています。

* OS : Windows10
* ブラウザ : Chrome
* jupyter core     : 4.6.1
* jupyter-notebook : 6.0.2
 
#実装

(1) custom.cssに下記を追記（C:\Users\ユーザ\\.jupyter\custom\custom.css）

```
@media print {
  div.inner_cell {display: block}
}
```

(2) Notebookの改ページしたいところに下記をマークダウンセルとして追加
※セルは存在していますが書いたコードは見えなくなるのでご注意下さい。
（[ここ](https://github.com/jupyter/nbconvert/issues/607)を参照しました）


```html

	<p><p style="page-break-after:always;"></p>
	<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
```

(3) Notebookの最後の方に下記をコードセルとして追加
（[ここ](https://stackoverflow.com/questions/27934885/how-to-hide-code-from-cells-in-ipython-notebook-visualized-with-nbviewer)を参照しました）

```html

from IPython.display import HTML

HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Show/hide code"></form>''')
```
(4)「Show/hide code」ボタンを押下することでコード表示/非表示を切り替えできます。

(5) 一旦htmlファイルとして保存し、htmlファイルを開く。
Jupyter Notebookのメニュー（File－Download as－HTML）から保存する。
![downloadashtml.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186585/afb5867d-eedc-6d10-3747-1b484a23aaca.jpeg)


(6) PDFファイルとして出力する際は、Chromeブラウザの印刷－送信先を「PDFに保存」に設定する（Show/hide codeボタンを表示したくなければボタンの手前に改ページを入れて最後のページ番号を印刷ページから除く）

他によい方法などありましたらぜひ教えて下さい。
Git checkout無しでリモートブランチの名前を変更する方法


## 1.古いブランチから新しいブランチを作成する

```
git push origin origin/old_branch:refs/heads/new_branch
```

## 2.古いブランチを削除する

```
git push origin :old_branch
```


## リモートブランチの名前が変更できたか確認するには以下のコマンドを使用する

```
git branch -r
```
Keras Functional APIでXORを実装してみる

#はじめに
本格的にKerasを始めようと思い、まずはXORの予測モデルを構築するコードを書いてみた。将来的にGraph Convolutional Networksなど複雑なモデルも作りたいと思っているため、Functional APIから始めてみる。

#ソース
こんな感じ。
BatchNormalizationをつけないと、局所解に陥りやすかったのでつけている。最終層はlinear層にしている事例が多かったが、0, 1のクラス分類問題であり、納得がいかなかったので、sigmoid関数とした。中間層2層のユニット数は、それぞれ8としてみた。

```sample.py
import tensorflow as tf
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Dense, Input, Dropout, BatchNormalization

import numpy as np


def main():
    x_input = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
    y_input = np.array([[0], [1], [1], [0]])

    input_tensor = Input(shape=(x_input.shape[1]))
    # x = Dense(units=32, activation="tanh", kernel_initializer='random_normal')(input_tensor)
    x = Dense(units=8, activation="relu", kernel_initializer='random_normal', use_bias=True)(input_tensor)
    x = BatchNormalization()(x)
    x = Dropout(0.1)(x)
    x = Dense(units=8, activation="relu", kernel_initializer='random_normal', use_bias=True)(x)
kernel_initializer='random_normal', use_bias=False)(x)
    output_layer = Dense(units=1, activation='sigmoid', kernel_initializer='random_normal', use_bias=False)(x)
    model = Model(input_tensor, output_layer)

    model.compile(loss='mse',  optimizer='sgd', metrics=['accuracy'])
    model.summary()

    # 学習
    model.fit(x_input, y_input, nb_epoch=2000, batch_size=2, verbose=2)

    # 予測
    print(model.predict(np.array([[0, 0]])))
    print(model.predict(np.array([[1, 0]])))
    print(model.predict(np.array([[0, 1]])))
    print(model.predict(np.array([[1, 1]])))


if __name__ == "__main__":
    main()
```

# モデル概要

```
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_1 (InputLayer)         [(None, 2)]               0
_________________________________________________________________
dense (Dense)                (None, 8)                 24
_________________________________________________________________
batch_normalization (BatchNo (None, 8)                 32
_________________________________________________________________
dropout (Dropout)            (None, 8)                 0
_________________________________________________________________
dense_1 (Dense)              (None, 8)                 72
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 8
=================================================================
Total params: 136
Trainable params: 120
Non-trainable params: 16

```

#予測結果
```
[[0.09092495]]
[[0.9356866]]
[[0.90092343]]
[[0.08152929]]
```

#おわりに
今回手始めにやってみたが、パラメータチューニング、可視化など色々試してみたい。
Twitter API with PHP + WordPress の Tips

[Twitterまとめのまとめ](https://twitter-mm.com)サイトを作りました ([2ちゃんねるまとめのまとめ](https://2chmm.com/)を参考にしています)。このサイト作りから得たTipsをまとめます。

## Twitter API 関連

#### Twitter APIの始め方 (WordPress/PHP環境)

別途、[こちらの記事](
https://takumablog.com/wp/twitter-api-%e3%82%af%e3%82%a4%e3%83%83%e3%82%af%e3%82%b9%e3%82%bf%e3%83%bc%e3%83%88/)を参照ください (別サイトです)。

#### Twitter検索+時間指定
検索ワードにsinceとuntilを併せて指定することで、時間指定をかけたTwitter検索ができます ([参考](https://qiita.com/kai_kou/items/336a9d1290c13abba7e2))。
下記の例では、現時刻から8時間前までのツイートを検索しています (9時間引いているのは、日本時間から協定世界時へ調整するためです)。

```
$dateImmu = new DateTimeImmutable();
$until = $dateImmu->modify('-9 hours')->format('Y-m-d_H:i:s') . '_UTC';
$since = $dateImmu->modify('-17 hours')->format('Y-m-d_H:i:s') . '_UTC'

$connection = getToken($consumerkey, $consumersecret, $accesstoken, $accesstokensecret);
$tweets = $connection->get("search/tweets",
                           ["q" => "since:" . $since . " until:" . $until,
                            "result_type" => "recent",
                            "lang" => "ja",
                            "count" => 100]);
```

## PHP 関連

#### 文章から最後のhttpsリンクを取り除く
下記のように、文章の最後にhttpsリンクがくっついているものを考えます。

> 【ニュース】『スマブラSP』に参戦した『マイクラ』スティーブの「股間」に注目集まる。ソレにしか見えない人々 https://t.co/XtIRzKfHpQ

このhttps表記だけを、文章から取り除きます。

> 【ニュース】『スマブラSP』に参戦した『マイクラ』スティーブの「股間」に注目集まる。ソレにしか見えない人々

```
$t = explode('https://t.co/', $text);
if (count($t) == 1) {
  $t = $t[0];
} else {
  $t = implode(array_slice($t, 0, count($t)-1));
}
```

## WordPress / HTML 一般

#### フォルダの場所
WordPressの「外観→テーマの編集」のファイルが入っているフォルダは、`/home/[サーバーID]/[独自ドメイン名]/public_html` (Xserverの場合)。

functions.phpを直接編集したい、なんて思ったときに。

```
<?php
echo getcwd() . "\n";
?>
```

#### サーバー上ファイルの編集方法
SCPでサーバー上のファイルをローカルにコピーをして、編集後にそれをSCPコマンドでサーバーへ返すことができる。SCPを使うためには、SSHが利用可能でないといけない。準備方法は[こちら](https://takumablog.com/wp/functions-php-%e7%b7%a8%e9%9b%86-tips/) (別サイトです)。

viが嫌いな人向け。

これでサーバー→ローカルへのコピー。

```
scp -i [xxx.key] -P 10022 [サーバーID]@[ホスト名]:/home/[サーバーID]/[独自ドメイン名]/public_html/wp/wp-content/themes/[テーマ名]/functions.php ./
```

これでローカル→サーバーへのコピー。

```
scp -i [xxx.key] -P 10022 ./functions.php [サーバーID]@[ホスト名]:/home/[サーバーID]/[独自ドメイン名]/public_html/wp/wp-content/themes/[テーマ名]/functions.php
```

#### 画面遷移なしの検索フォーム
`form`で自ブロック内の`id`を指定して上げれば、擬似的に画面遷移なしで検索ができる。

```
<h2> <a id='search'> 検索ポイント </a> </h2>
<form action = "#search" method = "get">
<input type = "text" name = "query" class="textbox">
<input type = "submit" value ="検索" class="btn-submit">
</form>

<?php	
if(isset($_GET['query'])){
  echo "You searched " . $_GET['query'];
        
} else {
  echo "No Input";
}
?>
```
Twitter の障害情報を調べようとしてつまずいた話

**この記事の内容は私が独自に調査したものであり、障害の真因を示すものではありません。**
**情報の取り扱いには十分ご注意ください。**

## 出来事

2020 年 10 月 16 日、朝起きて Twitter を見ようとしたら・・・あれ、見れない。
最新のタイムラインと通知が見られない。トレンドはなぜか知らないが見ることができる。

## AWS とかの障害？と予測したものの

~~Twitter 使えねぇとか言う前に~~ どっかのサーバに障害が起こったのかな？と思って、 `AWS 障害` とか `GCP 障害` とかでググってみる。
そうすると、 AWS も GCP も障害情報が Twitter に発信されているということが分かった←
これじゃなにもわかんないｗ

## 素直に検索してみる

素直に `twitter 障害` と検索すると、何やら手掛かりとなるサイトを発見した。

[Twitterの機能停止マップ。 Downdetector](https://downdetector.jp/shougai/twitter/mappu/)

`Downdetector` というサイトで Twitter の障害情報が閲覧できるらしい。
Twitter 以外にも、私たちが利用している身近なサービスなどの障害情報を、 `Downdetector` に提出されたレポートや他のデータソースから検出して報告する仕組みとなっている。

そして私が Twitter を閲覧する前日から障害が起こっていたらしいということもわかった。

ちなみに App Store と Google Play でもアプリ版が配信されている。

## アプリで見てみるとさらなる事実が

アプリで見てみたところ、 Twitter と AWS で朝に報告が増えているのが見えた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486784/959ab2f2-2068-d2c0-a54c-70f1b505f0eb.png)

AWS の報告件数が少ないので断定はできないが、おそらく AWS に何らかのトラブルがあったのではないかと推測される。

他にも Amazon や Apex Legends など同時間帯に報告が増えているのが確認できた。

## まとめ

**情報源やソースが複数存在していることは重要**
AWS さんは障害情報を Twitter に報告していたが、今回 Twitter に障害があったため、私は状況を確認するのに非常に苦労した。
でも情報源が複数あったので、一部に障害があっても他の情報源で確認できた。
これは「バックアップに助けられた」という見方ができるかもしれない。
自社サービスなどで顧客データのバックアップを取っていなかった場合に障害などでデータが消失した場合、データを取り戻すことができず、お客様に多大な迷惑（では済まない）がかかってしまう。
そうならないように、何事にも最悪の事態を想定して取り組みたいと思った。

## エンジニアになってから思うこと

スマホアプリとか Web サービスが一時的に使えなくなったときに、以前は原因がわからずムズムズして ~~このゲームクソとか言って~~ いたが、エンジニアになって、現在配信されているサービスの多くがサーバ環境をこういった外部サービスに頼っていることを知ってからは、う～がんばれ Twitter ! って心から思えるようになった。
また、外部サービスに頼るサービスを開発・提供する場合、今回のようなリスクがあるということを忘れず認識しておきたい。
そして、不具合の起こっているサービスを頭ごなしにけなす人が減ることを切に願う。

# それにしても AWS はすごい、いつもありがとうございます🙇‍♀️🙇‍♂️
DMZ ってなに？

## 勉強前のイメージ

セキュアでもない、外部でもない中間地点

## 調査

### DMZとは

DeMilitarized Zone の略。日本語では非武装地帯と呼ばれます。
データを参照しながら外部に向けてサービスを行わないといけない場合、外部ネットワークと内部ネットワークをファイアウォールで分離し
さらにその中間に確保した「外部との通信を直接行うネットワーク領域」(DMZ)を、設けることが一般的である。
外部ネットワークや内部ネットワークからDMZへの通信は許可されるが、DMZから内部ネットワークへの通信は許可されない。


![スクリーンショット 2020-10-15 21.57.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/85bb469d-cd64-9af0-3250-b95021c42c1f.png)


よくある構成であれば、
webサーバやDNSサーバ、メールサーバがこのDMZの環境にいることが多いです。

### DMZを設けるメリット

DMZを設ける理由としては、セキュリティ強化のためです。
外部公開用ネットワークと内部ネットワークを隔離することで、不正アクセスやサイバー攻撃を防止してシステムへの不正侵入や機密データの漏洩を阻止します。

### DMZを設けるデメリット

上記の画像で言うと、外部ネットワーク・内部ネットワーク・DMZとセグメントがあり、設定がややこしくなります。
また、内部ネットワークへの攻撃は防げますが、DMZの領域への攻撃は完全に防げません。


## 勉強後のイメージ

外部からアクセスできる箇所を制限することで、攻撃を防ぐというやり方。

## 参考

- [5分でざっくりわかる「DMZ」、役割や構築方法をやさしく解説](https://www.sbbit.jp/article/cont1/37677)
- [DMZ（DeMilitarized Zone）とは](https://www.atmarkit.co.jp/ait/articles/0401/01/news053.html)
- [DMZとは？メリットやデメリット、構築時のポイントなど広く解説](https://locked.jp/blog/what-is-dmz/)
MNISTの行列表示




python==3.7.9
Keras==2.2.4
tensorflow==1.13.1

#mnistを画像表示する


```python

import urllib.request
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np


#prox = urllib.request.build_opener()
#urllib.request.install_opener(prox)


from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()


plt.imshow(x_train[0])
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a6a1291f-bd0f-9f8a-8ddc-1a899cf54402.png)

#行列で表示

通常のprintではmatrix形式が省略されてつぶれてしまうが
linewidthに一行に表示する文字数を指定することで見やすくする


```python
np.set_printoptions(linewidth = 115, precision = 1)

print(x_train[0])
```


スペースを含み115文字で表示できる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/373e1230-7531-c024-7e7c-64c23c4f6674.png)


#以上
ThymeleafでJavaScriptを生成する

## 概要
ひょんなことからThymeleafでJavaScriptを触ることがあったので備忘録です。

## 環境
OpenJDK 11.0.2
SpringBoot 2.3.4
Thymeleaf 3.0.11

## TemplateEngine設定
```java:AppConfig.java
@Configuration
public class AppConfig {

    @Bean
    public TemplateEngine scriptTemplateEngine() {
        final TemplateEngine templateEngine = new TemplateEngine();
        templateEngine.setDialect(new SpringStandardDialect());
        templateEngine.setTemplateResolver(scriptTemplateResolver());

        return templateEngine;
    }

    private ITemplateResolver scriptTemplateResolver() {

        final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
        templateResolver.setPrefix("/templates/scripts/");
        templateResolver.setSuffix(".js");
        templateResolver.setTemplateMode(TemplateMode.JAVASCRIPT);
        templateResolver.setCharacterEncoding("utf-8");
        templateResolver.setCacheable(false);
        templateResolver.setCheckExistence(true);

        return templateResolver;
    }
}
```

## テンプレートファイル作成
```javascript:resources/templates/scripts/sample.js
'use strict';

(() => {

    const rawData = [# th:text="${rawData}" /];
    const jsonData = [# th:text="${jsonData}" /]; 

    console.log(rawData);
    console.log(jsonData);

})();
```
2つの変数を渡す形にします。

## コントローラ設定
```java:SampleController.java
@Controller
@RequiredArgsConstructor
public class SampleController {

    private final TemplateEngine scriptTemplateEngine;
    private final ObjectMapper objectMapper;

    @GetMapping(value = "/app.js", produces = "text/javascript")
    @ResponseBody
    public String sample() throws JsonProcessingException {

        String path = "sample";

        Map<String, Object> map = new HashMap<>();
        map.put("id", 1);
        map.put("name", "Takeshi");
        List<Map<String, Object>> list = new ArrayList<>();
        list.add(map);

        Context ctx = new Context();
        ctx.setVariable("rawData", list);
        ctx.setVariable("jsonData", objectMapper.writeValueAsString(list));

        return scriptTemplateEngine.process(path, ctx);
    }
}
```
sample()の方でデータを作成し、先ほどの変数名と同じ名前でそれぞれデータそのものとJSON文字列に変換したデータをprocessメソッドに渡し返却します。
注意したいのがthymeleaf-spring5の依存性を追加すると、自動でViewを返却するためのBeanがtemplateEngineという名前で作成されます。
設定ファイルで作成したBeanを使用する場合はその際に使用したBean名でDIする必要があります。

## 結果
アプリを起動し/app.jsにアクセスしてみます。
![Screen Shot 2020-10-16 at 6.36.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469184/53acac40-fae3-30e2-5f41-db46fc6e003c.png)

無事作成できました。
動的にJS作成する機会はそうそうないとは思いますが参考まで。

Thymeleafのアップデートは2年ほどないみたいですね。
開発止まったのですかね。
[Swift] 初心者がCocoaPods導入でつまづいた事&導入手順

#今回の題
初めまして、swiftの学習を初めて２週間ちょっとの人です。
利用したいライブラリがあり、パッケージ管理にCocoaPodsを導入しようとしたところ、何箇所か詰まった箇所があったのでそれをメモしておきます。
エラー解消しながら導入手順も載せてます。
何か間違い等あればお手数ですが、コメントにお願いいたします。

#環境
macOS Catalina 10.15.6
xcode 11.1

##CocoaPodsのインストール
ターミナルを起動して以下のコマンドでcocoapodsをインストールします。

```terminal
sudo gem install cocoapods
```

が、早速ここで以下のようなエラーが出ました。

```
ERROR:  Loading command: install (LoadError)
    dlopen(×××××××××/.rbenv/versions/2.5.0/lib/ruby/2.5.0/x86_64-darwin16/openssl.bundle, 9): Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
  Referenced from: ×××××××××/.rbenv/versions/2.5.0/lib/ruby/2.5.0/x86_64-darwin16/openssl.bundle
Reason: image not found - ×××××××××/.rbenv/versions/2.5.0/lib/ruby/2.5.0/x86_64-darwin16/openssl.bundle ERundefined method `invoke_with_build_ar
```

このエラーの解決策が[こちらの記事](https://qiita.com/suzukalight/items/1fd68258c4134ad7fc48)にある、

```terminal
$ rbenv uninstall 2.5.0
$ rbenv install 2.5.0
```
を行う事で解決できました。
バージョンはエラー内容にある自分の環境のものに置き換えてください。
私の場合は、エラー内容に`2.5.0`とあったのでそれを指定して行いました。

そしたらもう一度インストールを実行。

```terminal
sudo gem install cocoapods
```
今度は成功しました。

##設定

ライブラリの情報をセットアップ。

```terminal
pod setup
```

そうしたらプロジェクトまで移動します。
私はここで、
プロジェクトってどの階層だ？
ってなったのですが、`プロジェクト名.xcodeproj`がある階層をさしているそうです。
間違えて更にその下の階層に行くとこでした汗

##Podfileの作成
以下のコマンドを実行すると、今いる階層(プロジェクト)に`Podfile`というファイルが作成されます。

```terminal
pod init
```

##Podfileを編集

初期状態で以下のようになっています。

```terminal
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'UIMenuItem' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for UIMenuItem

end
```

今回私は、FloatingPanelというライブラリを使いたかったので、以下のように編集します。

```terminal
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'UIMenuItem' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for UIMenuItem
  pod 'FloatingPanel'  # 追記

end
```

`pod 'FloatingPanel'`を追記しました

編集が終わったらファイルを保存し閉じます。

##ライブラリのインストール
以下のコマンドを実行する事でPodfileに記述に従ってライブラリがインストールされます。

```terminal
pod install
```

##ライブラリを使ってみる

ここで少し勘違いをして詰まりました。

これまで、
`プロジェクト名.xcodeproj`
というファイルを開いて作業してきたのですが、そこだとライブラリが使用できませんでした。

調べてみると、CocoaPods導入後は、
`プロジェクト名.xcworkspace`というファイルで作業することになります。
同じ階層に作られているので間違えずにこちらを開いてください。

ライブラリをimportします。

```swift:ViewController
import UIKit
import FloatingPanel // ライブラリをimport


class ViewController: UIViewController {
    // 略
```

ここで終わっている記事が多かったのですが、私の場合、

`No such module 'FloatingPanel'`

というエラーが出ました。
このエラーの解決策が[こちら](https://stackoverflow.com/questions/31065447/no-such-module-when-i-use-cocoapods)です。
stackoverflowのかなり古い質問ですが、そのまま試したらスルッとエラーが消えました。

手順を書いておきます。

まず、以下の画像を参考に`Manage Schemes...`を見つけ出してクリックしてください。
![スクリーンショット 2020-10-16 3.42.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/7fa75105-cb59-7e7d-350b-e17c954b0d57.png)


下記のようなメニューの中にライブラリ名があるのでチェックをつけてください。
これでエラーが消えます。
![スクリーンショット 2020-10-16 3.48.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/639c5be6-c799-fb06-5fbf-b30c49cadac4.png)


以上です。
SQLアンチパターン　インプリシットカラム

# インプリシットカラム

検索時のワイルドカード記号やインサート時の列名省略などクエリを省略することにより弊害が起こる場合がある。

# 目的：タイプ数を減らす

以下のようなユーザー情報があった際に全ての列を取得するにはどのような取得方法をするか。

***User***

|user_id|user_name|user_email|tel|
|:---:|:---:|:---:|:---:|
|1|TEST|test@example.com|000-1111-2222|

おそらく多くの人は

```SQL
SELECT 
  user_id,
  user_name,
  user_email,
  tel,
FROM
  User;
```

ではなく、

```SQL
SELECT * FROM User;
```

で、取得するかたが多いのではないでしょうか？
また、「User」テーブルの全列にデータを格納する際はどうするでしょうか。

```SQL
INSERT INTO
  Users(user_id, user_name, user_email, tel) 
VALUES
  (2, "TEST2", "test2@example.com", "111-2222-3333");
```

上記のように全列名を記載しますか？？
それとも以下のように列名を省略しますか？？

```SQL
INSERT INTO
  Users
VALUES
  (2, "TEST2", "test2@example.com", "111-2222-3333");
```

暗黙的に列名を指定できる際は列名を省略することも多いのではないか。
列名の多い場合やどうせ全列取得、挿入するなら手間だと感じ省略することもあるかと思う。

# リファクタリングによる問題

|user_id|user_name|user_email|tel|
|:---:|:---:|:---:|:---:|


先ほどのUsersテーブルに「age」列を追加することになった。

|user_id|user_name|user_email|tel|<font color="Red">age</font>|
|:---:|:---:|:---:|:---:|:---:|

テーブルに列が追加されたことを知らない場合、先ほど同様に以下のクエリにてデータを挿入しようとしたらエラーを返すようになった。

```SQL
INSERT INTO
  Users
VALUES
  (2, "TEST2", "test2@example.com", "111-2222-3333");
```

このようにリファクタリングによって予期しない値が挿入される場合等ある。
また、列を削除して新たに追加した場合や、新たに追加した後に別の列を削除した場合などでは型さえ一致していればエラーを返さず本来想定していない列に別の列にの値を知らず知らずに挿入してしまうなども考えられる。

また、列が削除されている場合エラーを返すが明示的に列を指定していた方が原因究明がしやすい。

# 不要な列のみ除去

SQLには「指定した一部の列のみ除去した全ての列」を取得することができない。

* 前列をワイルドカードで取得する
* 明示的に必要な列のみ指定する

の２つの方法しかない。

# アンチパターンを使用しても良い場合

* テストや検証で素早くクエリを発行したい場合

# 解決策

## 列名を明示的に指定する

ワイルドカードや暗黙的な列指定をせず、必要な列名は明示的に指定する

### 謝りの防止

列名を明示的にすることで致命的なミスを防ぐことが目的。

* テーブル定義の列の順番が変わっても明示的に指定していれば結果は一緒
* INSERT時に予期せぬ列に挿入されることを防げる
* テーブルから列が削除された際にしっかりとエラーで落ち、原因究明がしやすい

明示的に列名を指定することで誤った挿入や予期しない列順でのデータ返却がなくなり、エラー時の原因究明やメンテナンス性向上につながる。

### それは多分、必要ない (YAGNI: You Ain't Gonna Need It)

YAGNIを簡単に説明すると、

* ***必要になりそう***なコードを書かない
* ***必要になったら***書く
* 必要だと思ったものは案外使われない

と、言う意味らしいです。(知らなかった)

使うかどうかわからないものを書いてパフォーマンスの影響が出たり、リスクが増す可能性があるなら必要最低限の列を指定しようと言うこと。


# まとめ

***必要な列だけを指定するようにしよう***

# 参考文献

[SQLアンチパターン](
https://www.amazon.co.jp/SQL%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Bill-Karwin/dp/4873115892/ref=sr_1_1?adgrpid=104444684056&dchild=1&gclid=CjwKCAjw4_H6BRALEiwAvgfzqy-f83NTsyQkauo7gn6ysgAPmJvKyvuI5FaXFnxFmhVfCzCRRACsaBoCY-oQAvD_BwE&hvadid=447984765572&hvdev=c&hvlocphy=1009332&hvnetw=g&hvqmt=e&hvrand=13417269104929133208&hvtargid=kwd-335484809678&hydadcr=27264_11561110&jp-ad-ap=0&keywords=sql%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3&qid=1599934568&sr=8-1&tag=googhydr-22)

![参考文献.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257405/b46d45ab-75ec-a620-eeb2-a422f6b1e659.jpeg)
kylekatarnls/business_dayライブラリのdiffInBusinessDaysメソッドの挙動について

Carbonに組み込んで利用できるPHPライブラリ、[business-day](https://github.com/kylekatarnls/business-day)についてです。

`diffInBusinessDays` という、日数の差を取得するメソッドの境界について調べました。

各サンプルコードは、READMEにあったものをちょちょいと書き換えたものです。

## 0日と数時間のずれが生じるパターン

ドキュメントにあった、00:00:00 と 23:59:59 を比較するパターンです。
1日の差として計算されます。

```
$days = Carbon::parse('2019-06-10')->diffInBusinessDays(Carbon::parse('2019-06-10')->endOfDay());
echo "If you ask to leave from 2019-06-10 to 2019-06-10, it will cost to you $days days of paid vacation.\n";

> If you ask to leave from 2019-06-10 to 2019-06-10, it will cost to you 1 days of paid vacation.
```

## 完全一致パターン

時刻が完全に一致する場合は、0日と計算されます。

```
$days = Carbon::parse('2019-06-10')->diffInBusinessDays(Carbon::parse('2019-06-10'));
echo "If you ask to leave from 2019-06-10 to 2019-06-10, it will cost to you $days days of paid vacation.\n";

> If you ask to leave from 2019-06-10 to 2019-06-10, it will cost to you 0 days of paid vacation.
```

## 0日と数時間のずれが生じるパターン（負の方向）

ズレが負の方向、-1日などの方向に振れる場合についても確認します。
方向が正でも負でも、絶対値で日数が取得されることがわかります。

```
$days = Carbon::parse('2019-06-11')->diffInBusinessDays(Carbon::parse('2019-06-10')->endOfDay());
echo "If you ask to leave from 2019-06-11 to 2019-06-10, it will cost to you $days days of paid vacation.\n";

> If you ask to leave from 2019-06-11 to 2019-06-10, it will cost to you 1 days of paid vacation.
```

## 境界値を探る

時刻が一致する場合は差分としての日数はインクリメントされず、時刻が少しでも大きくなった場合に、日数がインクリメントされるようです。

つまり、境界線は以下のようになります。

```
-2 <= x < -1    : 2
-1 <= x < 0     : 1
0               : 0
0 < x <= 1      : 1
1 < x <= 2      : 2
```

図にすると以下のようになります。

```
2   1   0   1   2
|---|---|---|---|
≦  ≦  =   ≦  ≦
```

**Carbonの `diffInDays` メソッドとは境界が異なるようですので、注意しましょう。**

```
$days = Carbon::parse('2019-06-10')->diffInDays(Carbon::parse('2019-06-10')->endOfDay());
echo "If you ask to leave from 2019-06-10 to 2019-06-10, it will cost to you $days days of paid vacation.\n";

> If you ask to leave from 2019-06-10 to 2019-06-10, it will cost to you 0 days of paid vacation.
```

## 時刻に関係なく、カレンダー上の日数を比較したい場合は

単純にカレンダー上の日数の差を取得したい場合は、各日時の時刻を合わせて比較すると混乱がなくてよいです。
この方法に気づいてから、日時の比較において考えなければいけないことがグッと減りました。

```
$from_day = Carbon::parse('2019-06-10');
$to_day = Carbon::parse('2019-06-11')->endOfDay();
$days = (clone $from_day)->setTime(0,0,0)->diffInDays($to_day->setTime(0,0,0));
echo "If you ask to leave from 2019-06-10 to 2019-06-10, it will cost to you $days days of paid vacation.\n";

> If you ask to leave from 2019-06-10 to 2019-06-10, it will cost to you 1 days of paid vacation.
```

元の時刻が変わってしまうと不都合があるケースが多いので、クローンしたオブジェクトを操作しています。
[Unity]新しいスクリプトファイルの作成場所をScriptsフォルダに変更にしたい

UnityのInspectorのAdd Componentで新しいスクリプトファイルを作成するとプロジェクト直下にファイルが作成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731232/9ec0ca1d-615c-a02d-f4be-c898950c1be3.png)


これをScriptsフォルダに自動作成されるように設定できないか調査した。

## 方法

https://answers.unity.com/questions/614348/change-default-script-folder.html

UnityのQAサイトで調べたところ、スクリプトの追加をInspector > Add Componentではなく、フォルダを右クリックして作成すればScriptsフォルダにファイルが作成されるようだ。

1. Scriptフォルダを右クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731232/19a0697c-e037-4012-4529-c63ef6bcded1.png)
2. Create > C# Script を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731232/0978cef9-fc45-de99-1ae4-88e550f38039.png)
3. Scriptsフォルダ直下に新しいファイルができた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731232/4f17a400-14eb-1cbb-aefe-37877050e037.png)

今後はこの方法で新規スクリプトファイルを作っていこうと思う。
deviseユーザー登録

# 1  deviseをインストール

##ユーザー登録機能を実装するためには、deviseというgemをインストールします。

 1.   Gemfileで　gem 'devise'を追加

 2.  ターミナルでbundle install

 3.  ここでrails s でサーバー起動しないと反映されない

 4.  rails  g  devise:install  で設定ファイルを作成

 

 
# 2 ユーザーモデル＋テーブルを作る

ここで注意したいのが普通のモデルを作る時と同じではないということです。

 

### モデル作成

- ターミナルで　rails  g  devise  user  と入力(この時ルーティングが自動設定され、マイグレーションファイルも生成される)

- db→migrate→2020〜のファイルにてテーブルに追加するカラムやカラムの型を記載する。

```ruby
class DeviseCreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name, null: false
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
```


 

### テーブル作成

- ターミナルでrails  db:migrate　コマンドでテーブル作成




#3  サインアップ(新規登録)

 
サインアップ時に入力する情報はパラメーターとしてサーバーに送信される。
 通常コントローラーのストロングパラメーターで受け取るパラメーターを制限しているが、deviseの時は書き方が違う。

### devise_parameter_sanitizerメソッド
deviseのUserモデルに関わる「ログイン」「新規登録」などのリクエストからパラメーターを取得できる。
下の記述は、サインアップの時にニックネームというキーのパラメーターを許可する記述。実際ニックネームの後にも新規登録時に必要な項目が追記される。ここでのpermitの中の引数は普通のパラメーターの時と違うので注意！ 

```ruby

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
  end
end
```


初めのbefore_actionはdeviseによる処理であればconfigure_permitted_paramatersメソッドを実行するという設定。丸々必要なのだが、この辺は調べると出てくるので丸々覚える必要はない

 

これにより新規登録時の情報がテーブルに保存できている。
plotlyで描画したgraphを既存のwebアプリに実装してみました。


## 概要

- Dash plotlyを、既存のweb applicationに組み込む方法がわからず四苦八苦していた
- そんな中、plotly.jsの存在を知り、「jsサイドでplotly呼び出して使えばいいじゃん」となり、flaskのtutorialとplotly.jsを組み合わせて使ってみました。
- 既存のweb applicationに組み込むのは、simpleにデータをクライアント側に送って、jsにレンダリングさせるのが一番楽そうだなと思いました。



以下、flaskで作成したweb applicationに sample graphをレンダリングするコードを紹介いたします。

(Plotly Dashも別に組み込めるよ、などの有識者のご意見お待ちしております。)


## コード


server側でデータを送信する関数を用意する。

```py
@bp.route("/get_sample_data", methods=("GET",))
def get_sample_data():
    # import pdb; pdb.set_trace()
    out = {"y": [0, 14, 3, 17]}
    return out
```


```html:index.html
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

...中略...

{% block graphs %}


<button id="get_data_button"></button>
<div hidden class="result"></div>

<!-- 1. plotly.jsの内容を`#graphDiv`の要素にレンダリングする。 -->
<div id="graphDiv" class="graph">Plotly test</div>

<script>
  var data = [{
  x: [1999, 2000, 2001, 2002],
  y: [10, 15, 13, 17],
  type: 'scatter'
}];
//ボタンが押されたらAJAXで非同期通信を実行し、サーバサイドからデータを取得する。
  $(function(){
    $("#get_data_button").on("click", function(){
      $.ajax({
        url:'/get_sample_data',
        type:'GET',
      })
      .done((res) => {
        $('.result').html(res);
        console.log(res);
          data.push({
          x: [1999, 2000, 2001, 2002],
          y: res.y, // res == {"y": [0, 14, 3, 17]} in get_sample_data function in blog.py
          type: 'scatter'
          });
          Plotly.newPlot(graphDiv, data, layout);
      }) // check arrow function
    }).fail((res) => {
      $('.result').html(res);
        console.log(res);
    })
  }
  )
  var graphDiv = document.getElementById('graphDiv')

var layout = {
  height: 500,
  title: 'Sales Growth',
  xaxis: {
    title: 'Year',
    showgrid: false,
    zeroline: false
  },
  yaxis: {
    title: 'Percent',
    showline: false
  }
};
Plotly.newPlot(graphDiv, data, layout);
</script>

{% endblock %}
```


<!-- CODEPENを実行する。 -->
## ざっくり解説
一つ一つ分解して説明します（随時更新予定）

1. plotly.jsの内容を`#graphDiv`の要素にレンダリングする。

2. `#get_data_button`を`id`にもつ`<button>`を押すと、flask applicationにAJAXでGET通信から`get_sample_data()`を実行してデータを返す。
3. データを取得して、`data` listに`push(res)`し、再度`Plotly.newPlot(graphDiv, data, layout);`を実行する。
4. y =[0, 14, 3, 17]の時系列データが追加されていることを確認する。（下記画像オレンジ色の直線）
![スクリーンショット 2020-10-16 2.45.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179708/5ee71265-ddd6-72a2-5059-1eb8251880c4.png)




## tutorialで詰まったところ、
- Plotly.jsでは、rendering先を`<div>`タグにしないと読み込んでくれないようです。([<canvas>を使ってもplotly.jsが描画してくれない。](https://stackoverflow.com/questions/63028881/plotly-graphs-not-at-all-rendering-in-my-html-webpage))

- 出力されるグラフのCSSに関して
    - `#graphDiv`に関してサイズを変更するようにコーディングしてたが全くサイズ変更されず、とても困った。
    - `Plotly.newPlot(graphDiv, data, layout);`でlayoutにheight, widthキーを追加してあげればOKでした。
    - （単純にCSSの知識が足りないなと思いました...）

## 参考文献

1. [Plotly.jsのサンプルコード](https://plotly.com/javascript/uirevision/)
ネストしたtypeにreadonlyを適用させる

## はじめに
typescriptの型にはreadonlyというパラメータがあります。
こいつをつけることでコードの途中でその値を変更することができなくなります。

```typescript
type personalInfo = {
 name: string
 salary: number
 readonly girlFriend: string
}

const updateInfo = (info: personalInfo) => {
 info.salary += 10000000 // これはreadonlyついてないから実行できる
 info.girlFriend = "広瀬すず" // ここでコンパイルエラー
 return info
}

```

上の例では、readonlyのついていないsalaryは変更できますが、readonly属性の付されているgirlFriendは変更ができず、コンパイルエラーが起きます。いやしかし、給料は一千万円あげることができても、彼女を有名女優にすることはできません。なんと悲しい仕様でしょうか。

しかし、ほとんどのtypeにはreadonlyをつけるべきと言えます。immutableな実装を行う上では欠かせません。
readonlyをつけないのは、言ってしまえば直接変更しない変数の宣言をconstではなくあえてletを使うようなものです。
極力つけたほうがいいね。

## Readnly
上記の例では要素の一つにつけるだけだったため、そのように実装しましたが、全要素に付したい場合はもっと楽に実装できます。
Readonlyというtypescriptに組み込まれたものを使います。

```typescript

type personalInfo = {
 name: string
 salary: number
 girlFriend: string
}

const updateInfo = (info: Readonly<personalInfo>) => {
 info.salary += 10000000 // ここでエラー
 info.girlFriend = "広瀬すず" 
 return info
}

```

Readonlyを使えば、型引数として与えられたtypeに対して、その全ての要素にreadonlyを付すことができます。
やってることは多分こんな感じ。

```typescript
 type Readonly<T> = {
 readonly [t in keyof T]: T[t]
}
```

## typeがネストするケース
だが、Readonlyだと、次のようにネストした要素にまでreadonlyをつけたいケースで問題になります。

```typescript
type personalInfo = {
 name: string
 salary: number
 girlFriend: {
  name: string
  job: {
   jobName: string
   position: string
   workPlace: string
  }
  age: number
 }
}

// type Readonly<personalInfo> は、
{
  readonly name: string
  readonly salary: number
  readonly girlFriend: {
   name: string // ネストした中身にはreadonlyが適用されない
   job: {
    jobName: string
    position: string
    workPlace: string
   }
   age: number
  }
}

// 本当はこうしたい
{
  readonly name: string
  readonly salary: number
  readonly girlFriend: {
   readonly name: string 
   readonly job: {
    readonly jobName: string
    readonly position: string
    readonly workPlace: string
   }
   readonly age: number
  }
}
```
はいはい、どーせ別の組み込みのDeepReadonly的なやつあるんでしょ, ... ないんです。
だから自分で実装するしかない。

てことで実装。いろいろ自分で試行錯誤したり、調べていていくつでも方法はありそうだったが、あまりに美しい実装を見つけました。

```typescript
type DeepReadonly<T> = keyof T entends never ? T : {readonly [t in keyof T]: DeepReadonly<T[t]>}
```
？？？て人のために。personalInfoを例に。
1. personalInfoはkeyを持つからfalse
2. name, salary...とマッピングされて処理
3. name,salaryのvalueはstringやnumberだからDeepReadonly<string>,DeepReadonly<number>となり、つまりstring or number
4. girlFriendはkeyとvalueを持つ型だから、二週目のはじめの分岐もfalseに入る。
5. 繰り返し

って感じで見事にマッピングされるような処理が入っていく。

## 他への応用
もちろんこれはreadonlyだけじゃなくてPartialとかにも使えそう。
こんな感じかな。

```typescript
type DeepPartial<T> = keyof T entends never ? T : {[t in keyof T]?: DeepPartial<T[t]>}
```
## 終わりに
Typescriptの型は奥が深いので、これからもっと極めたい。
Macでlocateコマンドを使う

locateコマンドはビルド済みのデータベースを使用して高速にファイル・ディレクトリ検索を行うコマンドです.
locateコマンドをmacで使用するためには,ターミナル内で以下を入力します.
```
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist
```

次に,検索元となるデータベースを最新のもにアップデートします.

```
sudo /usr/libexec/locate.updatedb
```

locateコマンドでは定期的に検索元となるデータベースをアップデートする必要があります.
linuxでは,updatedbというコマンドでデータベースのアップデートを行うことができますが,macでは上記のコマンドを毎回打たなければなりません.

エイリアスにupdatedbというコマンド名でコマンドを追加しておきます.
```
echo "alias updatedb='sudo /usr/libexec/locate.updatedb'" >> ~/.bash_profile
```
```
source ~/.bash_profile
```

これでlocateコマンドを使用する際にデータベースのアップデートはupdatedbコマンドで行うことができます.
[CodeIgniter]バリデーションで独自バリデーションに引数を2つ以上渡す方法

#はじめに
実務でCodeIgniterを使用する機会があり、バリデーションの処理で独自バリデーションに引数を2つ以上渡すのに苦戦し、その時に解決した方法をまとめました。


#解決方法
__手順1__　独自バリデーションに渡したい値をJSON形式で変数に格納

```
// 今回は送信されたデータ4つを渡したい
$json_param = [
    'user_id"   => $this->input->post('user_id'),
    'user_name' => $this->input->post('user_name'),
    'password'  => $this->input->post('password'),
    'email'     => $this->input->post('email')
];
```

__手順2__　`user_name_check`ルールを作成し、独自バリデーション`callback_user_name_check`を作成する

```
// callback_user_name_checkの引数に1で作成した$json_paramを指定
$this->form_validation->set_rules('user_name', 'ユーザ名', 'callback_user_name_check['.json_decode($json_param).']');
```

__手順３__　独自バリデーション先でパラメータを受け取る

```
public function user_name_check($user_name, $json_data) {
    // JSON⇒オブジェクト型に変換
    $data = json_decode($json_data);

    // キーにアクセスし、変数に格納
    $user_id  = $data->user_id;
    $password = $data->user_name;
    $email    = $data->email;
}
```
`user_name_check`メソッドの第1引数を`$user_name`に指定しているのはCodeIgniterの仕様上で、第1引数は必ず検証ルールで作成したフィールドのデータが渡されるからです。

#参考
[CodeIgniter公式](https://codeigniter.jp/user_guide/3/libraries/form_validation.html)
pgAdmin 4でPostgreSQL使ってみるか

[前回の記事](https://qiita.com/nizu708/items/3aae16eb07c09c57e0b9)では`PowerSchell(管理者)`使ってPostgreSQL始めてみるって感じだったけど、
pgAdmin 4使ってもPostgreSQLは動かせる（PostgreSQLインストールすると一緒に入ってくる）からそれ使ってSQL文実行する方法をまとめておきます（ホント最初のとこだけね）。
とは言っても結局はSQLの中身わかってないと混乱を招くだけだと思うからどっちからやるのがいいかなって感じだけど（こっち使うとコードの保存が便利か）。

まずはpgAdmin 4を起動しなくてはいけませんが、ショートカット作ってないならWindowsボタン押して「PostgreSQL」のフォルダまで行ってください。その中にあるはずです。象さんマークのアイコン。

起動すると「Servers」というのが左側に表示されると思うので、そこを開いてください。
ここでパスワードが必要になりますので最初に設定したパスワードを入力してください。
うまくいくとPostgreSQLが出てくるはずなのでそれも開いてください。ここでもパスワードが求められるかな。入力してください。

そしたら下の画面のように、データベースの部分で右クリック。
![pg01.PNG.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543442/8562452a-b063-2dc9-9434-f8e51e74ffa3.jpeg)

作成（もしくはCreate）が出てくるはずので作る予定のデータベースの名前を入力する。
（日本語化はあとで）
前回の記事でcarというデータベースを作っていたらすでにあるはずなので、それを使ってくれてもよいです。
いずれにせよ、SQLを入力したいデータベースをクリックしたら、上の方にある再生ボタン付きのアイコンをクリックしてください（クエリツールもしくはQuery Tool）。画像にあるものでわかるかしら。
![pg02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543442/5b07ade3-e248-3344-319a-7d0d9811e0b8.jpeg)

これで終わりです。
あとはSQL文を書いて再生ボタンを押せば（F5でもOK）SQLが実行されます。
![pg03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543442/955f23dd-806f-9e7a-e1d4-0f0867adecd2.jpeg)

作成したクエリを保存するにはフロッピーディスクのアイコンをクリックすると、
![pg04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543442/3244e204-dfb7-1b57-dcee-3dbc3b733378.jpeg)
こんな感じになるので、保存したい場所まで移動し、画面上で言えば「C:\Users\user\」と書いてある部分にそのまま続けてファイル名を入力して下の「作成」ボタンを押せばよいです。
これでコードも保存されます。

あとはおまけ。
日本語化は「File」の設定から「Language」を選んで`Japanese`にすればOKです。

次は元にもどって`SELECT`文とか演算子の使い方とかまとめようと思います。では。
MySQL　error　pid file warning 


　　mysql　ハマった　流れ

　・homebrewでmysqlをインストール
　・テーブルの作成
　・放置期間（３週間）
　・mysqlworkbenchでテーブル作成
　・ターミナルでコマンドで作成を新たに試みる（３週間前作ったのを忘れる）
　・cleat しようとするとエラーがでる
　・とりあえず一回消そうと安易に考えてアンインストール
　・brew doctor でwarning
　・aplle deveroper でCommand　line ほにゃを　Xcodeインストールせずにインストール
　
　・Error　何種類かみた
　多いのはThe server quit without updating PID file(
-----
)

・ls -al /usr/local
・ls -al /usr/var

ファイルが無かったので


mkdir /usr/local/var/mysql
からの
chomod 775/usr/local/var/mysql
からの
mysql.server start

エラーー

ps　aux|grep mysql 
からの
warning:The post-install  step did not complete successfully

全部のファイル消せてるか不安だったので
powerMyMacでsql関連のファイルと思われるもの全て削除
アンインストール　mac再起動

ERROR:The server quit without updating PID fileーーー

からの

https://motomichi-works.hatenablog.com/entry/2016/03/02/103207
この記事参考にbash.profile作成した後
https://qiita.com/akiko-pusu/items/aef52b723da2cb5dc596
でアンインストールとインストールしたら再起動に成功した

１２時間ほどerrorとwarningループ楽しかった
アンインストールして
関連物消して
bashプロファイル作って
再起動して
インストールして立ち上げたらいけました

♯mysql
投稿の練習　（最近ビックリした事）

REST API　での
JSONのレスポンスで
3～4000行の応答が返るって一般的なのでしょうか？
通信キャリア向けのシステム中心に携わってきた私には
一回のAPIコールでこんな大量のレスポンスが返ってくる経験が無かったので
少々ビックリしています。
オブジェクト指向という考え方について１

Railsの勉強をやり直し始めたのでアウトプットとして残します。

オブジェクトとは、単純に翻訳すると「対象物」です。決して特殊なものではなく、世の中で皆さん自身も含めて皆さんがやり取りするもの全てがオブジェクトに当たります。オブジェクト指向とは、コンピューターの世界の全ての処理をオブジェクトを中心に取り扱う考え方です。

■オブジェクト（対象）とは、

●ある目的の振る舞いと、名前などの特徴となる固有の値とを持つ
●必要な時に呼び出される振る舞いを通し、固有の値を利用して目的とする処理を行う

ものだと言えます。少し硬い表現になりますが、この意味を理解することが重要です。

■オブジェクト指向プログラミングとは
何かのイベントを行う時、一般的に「式次第（プログラム）」を用意します。式を滞りながら運営するためには、この手順がしっかりできていることが重要です。なんらかの目的を持ったコンピュータプログラムを作ること（プログラミング）も、作業の手順（ロジックまたは手続き）をその目的に従って組み立てることになります。
従来、プログラミングは「全ての手順を一連のロジックで組み立てる」という方法で行われてきました。一方、オブジェクト指向は、

●オブジェクトというものを設定する
●オブジェクトに必要なロジックをそれぞれのオブジェクト内に閉じ込めて、必要な時にオブジェクトに指示して呼び出す。

という形で処理を組み立てていく方法です。Rubyは、「オブジェクト指向を完全に実現したプログラミング言語」と言われます。その理由はRubyで扱う全てのものがオブジェクトだからです。Rubyの中で取り扱う「数値」「文字の連なり（文字列）」「情報のかたまり」など、全てがオブジェクトとして扱われます。
　以上のことを認識することがRubyのオブジェクト指向を習得Railsを理解していく第一歩です。

某プログラミングスクールを卒業しただけでまだまだ理解が浅いのでこれからも頑張ります！！🔥
ありがとうPrestissimo、そしてさようなら

# Composer2.0は並列ダウンロードができる
[Prestissimo](https://packagist.org/packages/hirak/prestissimo)といえば、Composerにほぼ必須といってよいくらいの高速化ツールです。
しかしComposer2.0で[ついに並列ダウンロードが実装](https://github.com/composer/composer/pull/7904)され、お別れの時がやってきました。
[Prestissimo制作者のhirakさんが作られたプルリクエスト](https://github.com/composer/composer/pull/5293)は4年越しに実質的にマージされてクローズされることになりました。おめでとうございます。

# Composer2.0にアップデートする前にPrestissimoは消しておこう
PrestissimoはComposer2.0では動きません。そのため、Composer2.0へバージョンアップする前に忘れずに消しておく必要があります。~~現在Composer2.0はRCリリースですが、2020年10月末までに正式リリース予定となっています。~~
追記：2020年10月24日に正式リリースされました。
2.0でインストーラーが変わるとかはなく、いつものように`composer self-update`すると2.0に更新されますので、`composer global require hirak/prestissimo`しているところがあれば削除しましょう。特にCIやデプロイスクリプトで自動的に`composer self-update`している環境では突然失敗するようになるためご用心ください。

# 知らない間にComposer2.0に更新されないようにしたい
こんな感じで`--1`引数をつけると、1.0系列で最新のパッケージに更新されます。

```
$ composer self-update --1
```

composer-setup.phpを使った新規インストールの時は`--version=`引数で1.0系列のバージョンを指定してください。

```
php composer-setup.php --version=1.10.15
```
【JavaScript超初心者】Chromeコンソールパネルで改行するには

# はじめに
ChromeのコンソールパネルでJavaScriptを実行するときに、改行の仕方がわからず```Enter```をクリックしてはエラーが発生し困ったので、**改行の仕方**をシェアしたいと思います。
# コンソールパネルで改行
```console:consoleパネル
Shift + Enterキー
```

こうすることで今までに書いたコードが実行されることなく改行することができます。


### 【おまけ】 
ディベロッパーツールは```⌘ + option + C```のショートカットキーで表示することができます。
左手だけで表示できるので、二本指でタップして検証を選択するよりもとても楽です！
ショートカットキーを使ったことがない方はぜひお試しください！
# 参考URL
・[it-swarm-ja.tech](https://www.it-swarm-ja.tech/ja/javascript/chrome%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%82%A6%E3%82%A3%E3%83%B3%E3%83%89%E3%82%A6%E3%81%A7%E6%96%B0%E3%81%97%E3%81%84%E8%A1%8C%E3%82%92%E9%96%8B%E5%A7%8B%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%EF%BC%9F/834598846/)
[Delphi] 10.4 移行で TakePhotoFromLibraryAction を使ってると落ちる罠

# 10.4.1

みなさん！Delphi 10.4.1 は楽しんでますか！
Community Edition が出てないから楽しめないって！？
わかる～
早く出してくれることを祈りましょう。

# TakePhotoFromLibraryAction

さて、僕は 10.4.1 を楽しんでいるのですが、**Android** で、ちょっとした問題にぶつかりました。

それは、[TakePhotoFromLibraryAction](http://docwiki.embarcadero.com/Libraries/Sydney/ja/FMX.MediaLibrary.Actions.TTakePhotoFromLibraryAction) を使っていると、10.4 に移行したときにアプリが落ちてしまうという問題です。

TakePhotoFromLibraryAction はデバイスの写真を取ってくるアクションですが、ここで写真を選択して、アプリに戻ると直後に落ちます。

## 対処

10.4.1 で新規に作ったアプリでは落ちないので 10.3.3 から持ってきたファイルで 10.4.1 と何が違うのか diff を取ってみたところ原因がわかりました。

10.4 で新規に作った AndroidManifest.Template.xml には application タグの最後に

```xml
android:requestLegacyExternalStorage="true"
```

が挿入されていました。
そこで、10.3.3 から持ってきた AndroidManifest.Template.xml の application タグの最後に

```xml:AndroidManifest.Template.xml
    <application android:persistent="False" 
        android:restoreAnyVersion="False" 
        android:label="Project1" 
        android:debuggable="True" 
        android:largeHeap="False"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme"
        android:hardwareAccelerated="true"
        android:resizeableActivity="false"
        android:requestLegacyExternalStorage="true"> ←ここ！
```

追加したところ、写真を選んでも落ちなくなりました。

# 対象範囲別外部ストレージアクセス

Android 10 から「対象範囲別外部ストレージアクセス」（Scoped Strage）という機能が入りました。
これによりメディアファイル（写真や動画）などの取得方法が変りました。

写真を端末から選ぶ操作は普通は Scoped Strage の影響を受けないのですが、TakePhotoFromLibraryAction は受け取った写真データを**一旦ファイルに保存**し、後でそれを [TBitmap.LoadFromFile](http://docwiki.embarcadero.com/Libraries/Sydney/ja/FMX.Graphics.TBitmap.LoadFromFile) を使って読み出す、というロジックになっています。

一旦ファイルに保存した時点で Scoped Strage の影響を受けることになり、TBitmap.LoadFromFile が例外を吐いて落ちていました。

## requestLegacyExternalStorage

今回追加した requestLegacyExternalStorage は、旧式の外部ファイル管理方式を使うフラグで、これを付けると Scoped Strage は無効化されるため、上記の TakePhotoFromLibraryAction が動作します。

ですが、この救済措置が使えるのは Android 10 (API Level 29) までです。
TargetSDKVersion を [Android 11 (API Level 30)](https://developer.android.com/preview/behavior-changes-11?hl=ja) にすると無視されます。

Delphi 10.4.1 は正式には Android 11 に対応していないため、現状はこの解決方法でも良いですが、次に出る 10.4.2 は Android 11 に対応して欲しいものです。

See also: [サポートされているターゲット プラットフォーム](
http://docwiki.embarcadero.com/RADStudio/Sydney/ja/%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%82%BF%E3%83%BC%E3%82%B2%E3%83%83%E3%83%88_%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0)

# 最後に

ちょっとした問題と書きましたが、いくつか要因を排除するために数日かかっています。
これが皆さんの移行の手助けになれば幸いです！
【Unity】WebGLにビルドする方法 画像付き

## 始めに
unityroomにアップロードしたいと思い、自分のつくったUnityのゲームをunityroomにあげるまでの方法を備忘録として残しておきます。
実際に上がったゲームはこちら
https://unityroom.com/games/2d_side_scroll_action

※Unityのバージョンは2019.1.5f1

## 方法
###① File > Build Settingsを選択
自分の作りたいゲームがUnityで完成したら、画面右上のメニューからBuild Settingsを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308839/639eb976-da7d-5e8e-f1d3-2dce3090f77c.png)

### ② WebGLを選択し、Switch Platformを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308839/f45a39ee-83e7-0c22-5d5e-c55594b0a001.png)
WebGLの横にUnityのアイコンがつけばSwitch完了です。

※Switch Platformが選択できない場合
自分の場合、Switch Platformが半透明になっており選択ができませんでした。
その場合、Unity HubからWebGLのモジュールのインストールが必要になります。

### Unity HubからWebGLのモジュールをインストールする
Unity Hubの画面から Installsから作成したゲームのバージョンのアイコンの右上縦3つの点をクリックし、「Add Modules」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308839/a364ecef-0d8f-9020-f4af-1f1a56dfc212.png)

「WebGL Build Support」をチェックし、DONEをクリック。
するとインストールが始まると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308839/7528ff1c-51fc-0d3f-0c76-40f8888355dd.png)
インストールが完了したら②の画面に戻りましょう。
戻ってもSwitch Pratformが選択できな場合はUnityを一度終了し、もう一度起動してみてください。

### ③Buildを選択
保存場所を聞かれるので、任意の場所を選択してください。
そこにBuildのフォルダーができれば完了です。
※数分かかる可能性があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308839/c5608859-cb39-649e-831c-2dc3c6311be1.png)


### unityroomへのアップロード方法
こちらが大変参考になりました。
https://blog.naichilab.com/entry/how-to-upload-unityroom

### 参考記事
【unity】WebGLビルド方法
https://blog.naichilab.com/entry/2017/04/29/125527

Unity WebGLビルド
https://pgintro.net/unity/build/webgl/#anchor_unity_hub_install
Mac で Wifi接続しようとしても一覧に何も見つからない場合の対処方法

なんか急に、Mac で Wifi接続しようとしても一覧に何も見つからなくなりました
試行錯誤したら直ったのでメモしておきます。

# やったこと（無意味だったこと）

・WifiのON/OFF
・システム再起動
・システム終了→起動
・NVRAMリセット
・SMCリセット

これだけやってもダメで絶望した

# 今回ご紹介したい手順

![スクリーンショット 2020-10-16 0.07.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40994/066bca14-d0f5-8877-8d17-34e1066d15c0.png)

ネットワーク環境：自動　に、なってるとこを押す

![スクリーンショット 2020-10-16 0.07.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40994/a5267cf3-4468-b9ec-c055-07df49cbfc3d.png)

ネットワーク環境を作成できるやつがでるので、＋を押して「ダミー」を新規作成

![スクリーンショット 2020-10-16 0.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40994/0f784ce7-b267-f929-7a11-ea7a2d2cc9d2.png)

一度ダミーに設定を変える

![スクリーンショット 2020-10-16 0.07.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40994/ca861740-5dc4-9549-fb01-d81b9b1f22e0.png)

また自動に戻す

するとなんと！　Wifiの一覧が出るようになりました！　やった！

たまたまかもしれませんが、一応メモしておきます。

２時間無駄にしたし眠い・・・