OmniAICreator/Qiita-1.07M huggingface dataset:
WPF の DataGrid で動的にカラムを追加する

WPF の DataGrid で実行時にカラムの数や名前が確定するような動的なデータを扱いたいとおもったとき、DataTable を使うと実現することができます。

## つくるもの
データとカラムを追加できる DataGrid をつくります。
https://github.com/ishida722/DataTableSample

![datatable.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676126/96638955-88fa-42ca-d430-aec6d649785f.gif)


## View をつくる
まず DataGird を配置して、ItemsSource をバインドします。今回は DataTableView というプロパティにバインドしました。

```MainWindow.xaml
<DataGrid ItemsSource="{Binding DataTableView}" />
```

## DataTable をつくる
ViewModel をつくります。まずテーブルデータを保持する DataTable オブジェクトをつくります。これは直接外部に公開しないので private にします。

```DataTableViewModel.cs
private readonly DataTable dataTable = new DataTable();
```

この dataTable オブジェクトにデータを追加していきます。カラムを追加する場合は以下のようにします。

```DataTableViewModel.cs
dataTable.Columns.Clear();
dataTable.Rows.Clear();
dataTable.Columns.Add("ID");
dataTable.Columns.Add("Name");
```

これでIDとNameというカラムが追加されました。次にデータを追加します。

```DataTableViewModel.cs
var row = dataTable.NewRow();
row[0] = 0;
row[1] = "Jhon";
dataTable.Rows.Add(row);
```

IDが0のJhonというデータが追加できました。

## View に通知する

作成した DataTable を DataGrid に表示するためには DataView を使います。具体的には以下のようなプロパティを用意します。

```DataTableViewModel.cs
public DataView DataTableView => new DataView(dataTable);
```

DataTableView は View の DataGrid にバインドされています。このプロパティを読みだす度に、dataTable から DataView が作成されます。

DataTable は ObservableCollection ではないのでコレクションの変更を通知してくれません。なので自分で手動で変更を通知する必要があります。

```DataTableViewModel.cs
private void NotifyTableUpdate()
{
    OnPropertyChanged(nameof(DataTableView));
}
```

テーブルを変更するたびに、NotifyTableUpdate() を実行する必要があります。
Lightning メールテンプレート + Apex でメール自由送信

#背景
・送信機能自動化
・複数オブジェクトから情報を抽出して送信情報を作成する
・あるレコードの関連ファイルをメールに添付して送信したい

#１．Lightning メールテンプレート作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/2a63286b-4198-4df3-8cdb-bbd90d7d6383.png)

#２．Apex実装
```java
/**
 * parameter：
 *   ・取引先責任者：contactId
 *   ・contentDocumentId：関連ファイル
 */
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

// 「メール：組織のアドレス」に登録したメールアドレスを取得
ID orgWideEmailAddressId = [SELECT Address FROM OrgWideEmailAddress WHERE DisplayName = 'XXXXXX' LIMIT 1].Id;

// 送信元設定
mail.setOrgWideEmailAddressId(orgWideEmailAddressId);

// 送信先設定(取引先責任者から取得する)
Contact contactInfo = [SELECT Id, Name, Account.Name FROM Contact WHERE Id=:contactId];
mail.setTargetObjectId(contactInfo.Id);

// メールの添付ファイルを設定
ContentVersion cVer = [SELECT Title, FileExtension, FileType, VersionData FROM ContentVersion WHERE ContentDocumentId = :contentDocumentId AND IsLatest = true];
List<Messaging.Emailfileattachment> fas = new List<Messaging.Emailfileattachment>();
Messaging.Emailfileattachment fa = new Messaging.Emailfileattachment();
fa.setFileName(cVer.Title + '.' + cVer.FileExtension);
fa.setBody(cVer.VersionData);
fas.add(fa);
mail.setFileAttachments(fas);

// メールテンプレートからメール送信内容を設定する
EmailTemplate et = [SELECT Id, Subject, Body, HtmlValue FROM EmailTemplate WHERE name = 'XXXXXX'];
et.Subject=et.Subject.replace('#Subject#', 'Subject詳細内容');
et.HtmlValue=et.HtmlValue.replace('#ContactName#', 'お客様の名前');
et.HtmlValue=et.HtmlValue.replace('#FileName#', cVer.Title);
mail.setSubject(et.Subject);
mail.setHtmlBody(et.HtmlValue);

// 送信
try {
    Messaging.sendEmail(new List<Messaging.SingleEmailMessage> { mail }, true);
} catch (Exception e) {
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'メール送信失敗しました。'));
    return ;
}
```
[解決済み] gpg: can't connect to the agent: IPC connect呼び出しに失敗しました

WSL1のUbuntuでパッケージ更新しようとしたところ、エラーとなったので対策経過のメモ。

"sudo apt update"実行時に以下の内容のメッセージ

```bash
$ sudo apt update
(略)
エラー:1 http://dl.google.com/linux/chrome/deb stable InRelease
  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 78BD65473CB3BD13
(略)
パッケージリストを読み込んでいます... 完了
W: GPG エラー: http://dl.google.com/linux/chrome/deb stable InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 78BD65473CB3BD13
E: リポジトリ http://dl.google.com/linux/chrome/deb stable InRelease は署名されていません。
N: このようなリポジトリから更新を安全に行うことができないので、デフォルトでは更新が無効になっています。
N: リポジトリの作成とユーザ設定の詳細は、apt-secure(8) man ページを参照してください。
$
```

公開鍵が使えていないとのことなので["Google Linux Software Repositories"](https://www.google.com/linuxrepositories/)を参考に公開鍵を追加。

```bash
$ wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
gpg: can't connect to the agent: IPC connect呼び出しに失敗しました
gpg: can't connect to the agent: IPC connect呼び出しに失敗しました
$
```

失敗していることはわかるので、とりあえず、「IPC connect呼び出しに失敗しました」をキーワードにGoogleで検索すると["gpg: can't connect to the agent: IPC connect call failed"](https://stackoverflow.com/questions/46673717/gpg-cant-connect-to-the-agent-ipc-connect-call-failed)という記事を発見。
記事内容に従って作業してみる。

```bash
$ sudo apt-key remove gpg
(略)
$ wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
OK
$ 
```
(※ログがきちんと残っていなかったので、ここでは省略していますが、"apt-key remove gpg"を実行するとパッケージがいくつか削除される動作のようなので、モジュールが古くなってたのかな？とか考えていますが、詳細については勉強不足)

この時点で"apt-key list"で確認すると、きちんと"Google Linux Package Signing Key"が入っている。

```bash
$ apt-key list
/etc/apt/trusted.gpg
--------------------
pub   (略)
 フィンガー・プリント = (略)
uid                  Google, Inc. Linux Package Signing Key <linux-packages-keymaster@google.com>
sub   (略)

pub   (略)
 フィンガー・プリント = (略)
uid                  Google Inc. (Linux Packages Signing Authority) <linux-packages-keymaster@google.com>
sub   (略)

(以下略)
$
```
再度、"sudo apt update"を実行。

```bash
$ sudo apt update
取得:1 http://dl.google.com/linux/chrome/deb stable InRelease [1,811 B]
ヒット:2 http://security.ubuntu.com/ubuntu focal-security InRelease
ヒット:3 http://archive.ubuntu.com/ubuntu focal InRelease
取得:4 http://dl.google.com/linux/chrome/deb stable/main amd64 Packages [1,117 B]
ヒット:5 http://archive.ubuntu.com/ubuntu focal-updates InRelease
ヒット:6 http://archive.ubuntu.com/ubuntu focal-backports InRelease
1,117 B を 3秒 で取得しました (410 B/s)
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
アップグレードできるパッケージが 19 個あります。表示するには 'apt list --upgradable' を実行してください。
$ 
```
エラーはなく正常にパッケージリストが更新されたようなので、引き続き、"sudo apt upgrade"を実行。

```bash
$ sudo apt upgrade
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
アップグレードパッケージを検出しています... 完了
(以下略)
$
```
エラーはなく正常に更新できたようなので、(とりあえず)完了。
Thunderbird(サンダーバード)で、コマンドラインからメールの下書きを作る



##基本

```
"C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe" -compose to='a@hoge.com',subject="タイトルテスト",body="本文テスト"
```

##複数to、cc、添付ファイル

```
"C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe" -compose to='a@hoge.com,b@hoge.com',cc='a@fuga,com,b@fuga.com',subject="タイトルテスト",body="本文テスト",attachment="C:\temp\a.txt,D:\temp\b.pdf"
```


##差し出し人を変えるには`preselectid`でIDを指定する

```
"C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe" -compose to='a@hoge.com',subject="タイトルテスト",body="本文テスト",preselectid=id2
```

##preselectidの調べ方
ツール→オプション→一般→設定エディタ→「useremail」で絞り込み



##参考
http://kb.mozillazine.org/Command_line_arguments_%28Thunderbird%29


## bodyに改行を入れる

上記をバッチファイルに落として、実行する際、本文テキストに改行を含むと、ハマる。

バッチファイルで改行を扱えないから。

```
setlocal enabledelayedexpansion
set MYARG=-compose to='a@hoge.com',subject="タイトルテスト",body="本文$テ$ス$ト"
"C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe" !MYARG:$=^

!
```
とする。
LateBindingで、渡すときに$を改行に置換すると動く。メンドクセ。

参考
https://teratail.com/questions/190411
Macbookをデュアルディスプレイに接続した状態でイヤホン接続できない

Macbook Pro 13インチをHDMIケーブルでデュアルディスプレイにつないだ状態でイヤホンを使用したいと思い、

イヤホンジャックにiphone付属のイヤホンを挿してみました。

すると、サウンド設定を調整すれば正常にイヤホンから音が聞こえるようになったものの、セカンドディスプレイの画面が消えてしまうという問題がありました。


解決方法としては、イヤホンを挿してからHDMIケーブルをつないでみるようにしたところ、上手く行きました！

繋ぐ順番の問題でした...
Rust言語の勉強を初めてみた。その4

# Functions

[https://doc.rust-lang.org/book/ch03-03-how-functions-work.html](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)

mainがプログラムの最初に実行される関数。
Rustの関数名はスネークケース(すべて小文字で、単語を"_"で区切る)が一般的。

```
fn main() {
    println!("Hello, world!");

    another_function();
}

fn another_function() {
    println!("Another function.");
}
```

関数はfnで始まり、関数名の後に()をつける。{}の中は関数本体を表す。
定義した関数は関数名()で呼び出す。

## Function Parameters

関数には引数を持たせることができる。

```
fn main() {
    another_function(5);
}

fn another_function(x: i32) {
    println!("The value of x is: {}", x);
}
```

引数には型注釈が必要。

カンマ区切りで引数を複数持たせることができる。

```
fn main() {
    another_function(5, 6);
}

fn another_function(x: i32, y: i32) {
    println!("The value of x is: {}", x);
    println!("The value of y is: {}", y);
}
```

## Function Bodies Contain Statements and Expressions

ステートメントは、値を返さないアクション。

```
fn main() {
    let x = (let y = 6);
}
```

let y = 6はステートメントで値を返さないため、xには値は入らない(ビルドエラー)

```
fn main() {
    let x = 5;

    let y = {
        let x = 3;
        x + 1
    };

    println!("The value of y is: {}", y);
}
```

x+1には;が無いため、

```
    {
        let x = 3;
        x + 1
    };
```

の部分が一つの式となり、その式を評価した結果(4)がyに入る。

## Functions with Return Values

関数は値を返すことが出来る。
矢印(->)の後に型を付ける。
関数の戻り値は関数本体のブロック内の最終式の値となる。
returnで任意の位置で戻ることも出来る。

```
fn five() -> i32 {
    5
}

fn main() {
    let x = five();

    println!("The value of x is: {}", x);
}
```

five()には5という数字しか無いが、Rustでは有効な関数。
five()はi32型の5という数字が返る。
これは

```
let x = 5;
```

と同じ。

```
fn main() {
    let x = plus_one(5);

    println!("The value of x is: {}", x);
}

fn plus_one(x: i32) -> i32 {
    x + 1
}
```

これは The value of x is: 6と出力される。
しかし、x + 1;と書くと、ビルドエラーとなる。
関数の戻り値の型がi32と示されているのに対し、ステートメント(x + 1;)は値を返さないため、型の不一致となる。
数学-三角関数-合成公式の導出

# 合成公式の導出

[戻る](12efd87e80b55fc0835f)

## 合成公式

[加法定理](12efd87e80b55fc0835f#%E5%8A%A0%E6%B3%95%E5%AE%9A%E7%90%86)より

```math
\begin{array}{ll}

\sqrt{a^2 + b^2}{\sin(x + \alpha)} &= \sqrt{a^2 + b^2}(\sin x \cos \alpha + \cos x \sin \alpha) \\
ここで、\\
\cos \alpha = \frac{a}{\sqrt{a^2 + b^2}} \\
\sin \alpha = \frac{b}{\sqrt{a^2 + b^2}} \\
とすると \\
\sqrt{a^2 + b^2}{\sin(x + \alpha)} &= \sqrt{a^2 + b^2}(\frac{a}{\sqrt{a^2 + b^2}} \sin x + \frac{b}{\sqrt{a^2 + b^2}} \cos x) \\
&= a \sin x + b \cos x \\
\\
\therefore a \sin x + b \cos x &= \sqrt{a^2 + b^2}{\sin(x + \alpha)} \\
\sin \alpha = \frac{b}{\sqrt{a^2 + b^2}} \\
\cos \alpha = \frac{a}{\sqrt{a^2 + b^2}} \\

\end{array}
```
アメリカのハッカーの悩み

# アメリカ 中国ハイテク製品使用企業との取り引き禁止 8月施行
<strong
1.輸入させない
2.使わせない
3.繋がせない
</strong>

##庭の水やりスプリンクラー/地下室に置いてある洗濯機/暖炉の制御
これら全部中国製部品ESP8266が使われている。
ESP8266は、手軽にwifi接続を実現できるデバイスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/98dd0910-cf51-b0fd-8883-f9d2c284a662.png)

携帯電話のIFTTT経由で制御できる家電製品は、ほとんどこれを使っている。

この$5ディバイスは、話題になる。
アメリカ全土の工業実習で使われ、制御やプログラミングを勉強した学生も多い。もちろんこの製品を用いた、爆弾も多く発見されている。ドラマに出てくるスマートフォンからの爆破シーンを見ると小道具さんがUCLAの学生アルバイトに発注したことがわかる。例の赤きるか?黒きるか?のシーンは、30年変わってないのだ。

##こんな製品、TDKや村田製作所に作ってもらえば簡単に500円でできる。
#変なGoto トラブルキャンペーンするよりもMade in Japanに予算を使ってほしい。
#エンジニアの所得減税を!(士農工商制度の廃止)
Pythonで差分計測用のStopWatchを作る


すでに多くの記事でPythonを使った処理時間計測方法が提示されているので、詳しい内容は割愛。
自分で使いやすいように、下記の通りStopWatchを作ってみる。

PCで及びPython処理時間計測する事自体にあまり精度が期待できないので、ある程度自分が信じる精度を決めておけば今後の計測において役にたつかなぁと思い、何度か実験しましたが ms 程度の精度で十分な気もするので少数第4位くらいまでで経過時間を戻す仕様としてみました。
何点か同時に測定できるように、識別子付きのStopWatchとなっております。

```Python:StopWatch.py
import time

class StopWatch():
    def __init__(self, name=None):
        self.name = name
        self.start_time = 0
        self.stop_time = 0

    def start(self):
        self.start_time = time.perf_counter()

    def stop(self):
        self.stop_time = time.perf_counter()
        tm = self.stop_time - self.start_time
        return(round( tm, 4))

    def clear(self):
        self.start_time = 0

    def isName(self):
        return self.name


if __name__ == "__main__":
    sw1 = StopWatch("A")
    sw2 = StopWatch("B")    
    sw1.start()
    time.sleep(1)
    
    print(sw1.stop())
    sw2.start()
    for i in range(1000000):
        i=i+0.01
    print(sw1.name + ":" + str(sw1.stop()))
    print(sw2.name + ":" + str(sw2.stop()))
Next.jsのdockerコンテナでホットリロードされないときの解決法

# 解決法

プロジェクトルートにnext.config.jsを作成する

```next.config.js
module.exports = {
  webpackDevMiddleware: config => {
    config.watchOptions = {
      poll: 800,
      aggregateTimeout: 300,
    }
    return config
  },
}
```

# 実行環境

- win10
- docker-machine

# ソースコード

```
.
├─ .next
├─ node_modules
├─ pages
│  └─ index.js
├─ docker-compose.yml
├─ Dockerfile
└─ package.json
```

```docker-compose.yml
version: '3.3'

volumes:
  node_modules:

services:
  app:
    build: .
    container_name: next
    ports:
      - '80:3000'
    restart: always
    volumes:
      - '.:/app'
      - 'node_modules:/app/node_modules'
    tty: true
    stdin_open: true
```

```dockerfile
# Dockerfile
FROM node:12

WORKDIR /app

COPY ./package*.json ./

CMD bash -c "npm install && npm run dev"
```

```package.json
{
  "name": "nextjs",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "next": "^9.4.4",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
  }
}
```

```pages/index.js
const Index = () => (
  <div>
    <p>Hello Next.js</p>
  </div>
)

export default Index
```
数学-三角関数-和積の公式の導出

# 和積の公式の導出

[戻る](12efd87e80b55fc0835f)

## 和積の公式

```math
x + y = a \\
x - y = b \\
として、x, y を a,b で表すと \\
x = \frac{a + b}{2} \\
y = \frac{a - b}{2} \\
```

[加法定理](12efd87e80b55fc0835f#%E5%8A%A0%E6%B3%95%E5%AE%9A%E7%90%86)より

```math
\\\
\begin{array}{ll}

\sin(x + y) = \sin x \cos y + \cos x \sin y \\
\sin(x - y) = \sin x \cos y - \cos x \sin y \\
\\
\\
両辺を足すと、\\
\sin(x + y) + \sin(x - y) = 2 \sin x \cos y \\
上記の関係から、\\
\sin a + \sin b = 2 \sin \frac{a + b}{2} \cos \frac{a - b}{2} \\
\therefore \sin x + \sin y = 2 \sin \frac{x + y}{2} \cos \frac{x - y}{2} \\
\\
両辺を引くと、\\
\sin(x + y) - \sin(x - y) = 2 \cos x \sin y \\
\therefore \sin x - \sin y = 2 \cos \frac{x + y}{2} \sin \frac{x - y}{2} \\
\\
\\
同様に、\\
\cos(x + y) = \cos x \cos y - \sin x \sin y \\
\cos(x - y) = \cos x \cos y + \sin x \sin y \\
\\
\\
両辺を足すと、\\
\cos(x + y) + \cos(x - y) = 2 \cos x \cos y \\
\therefore \cos x + \cos y = 2 \cos \frac{x + y}{2} \cos \frac{x - y}{2} \\
\\
両辺を引くと、\\
\cos(x + y) - \cos(x - y) = -2 \sin x \sin y \\
\therefore \cos x + \cos y = -2 \sin \frac{x + y}{2} \sin \frac{x - y}{2} (マイナスに注意)\\

\end{array}
```
WSLでWindows側とLinux側のパイプの使い分けについて

# はじめに

WSLを使うと、コマンドウィンドウからLinuxのコマンドが簡単に使えて大変便利です。昔はちょっとしたコマンドを使うのに**msys**などの環境をインストールしていましたが、今どきはWSLだけで事足ります。しかし、WSL環境ならではのパイプの扱いに慣れていないと、期待する結果が得られません。しばらく使っていないとすぐに忘れてしまうので、ワンライナー的なメモにして残すことにしました。

# 要点

* Windows側のパイプを使う場合は、普通に書けば大丈夫です。  
  `type a.txt | wsl cat | findstr "."`
* Linux側のパイプを使う場合は`^`でエスケープします。  
  `type a.txt | wsl cat ^| awk '1' ^| python -c "import sys; sys.stdout.write(sys.stdin.read())"`
* 上記をWindowsのパイプで処理させる場合：  
  `type a.txt | wsl cat | wsl awk '1' | wsl python -c "import sys; sys.stdout.write(sys.stdin.read())"`

# 注意点

* WSL(Linux側)で処理された結果は、Linux側のコード体系になります。WSLのデフォルトはUTF-8なので注意してください。
* `findstr "."`は空行を削除するので、`cat`の代用にはなりません。

# おわりに

これが初めての投稿です。至らない点があればご指摘をお願いします。
UnityEditor上でgitのヒストリーを表示させるUniGitHistoryViewerを作りました

非エンジニアが絡むUnityプロジェクトで、トラブルの原因を見つけやすくするためのツールを作りました。

## 経緯

チーム開発をしていると作業ファイルごとのgitの履歴を知りたくなる事があります。

特に**非エンジニアがUnityプロジェクトに対して画像の追加やPrefabの修正などをした時**です。

ソースコードであればRiderなどのエディタに**履歴閲覧機能が備わっている場合がある**ので問題はありません。
しかし画像などのバイナリファイルを調査する時は少し時間がかかります。

- シェルからgit logコマンドを実行して調査
- SourceTreeなどのGUIツールからgit log相当の機能を実行して調査

など

Riderでもバイナリファイルのgit履歴は調査可能ですが、Riderがインストールされていない非エンジニアは困ります。非エンジニアにgit logさせるのもハードルが高め。。。

理想はUnityEditor上からgitの履歴をサクッと確認できる事です。

ということで**非エンジニア向け**の「**[UniGitHistoryViewer](https://github.com/baobao/UniGitHistoryViewer)**」というものを作りました。

## UniGitHistoryViewerとは

**UniGitHistoryViewer**とはUnityEditor上でサクッと任意のファイルまたはディレクトリのgit履歴を閲覧するエディタ拡張です。


### 使い方

`Tools > UniGitHistoryViewer`から開きます。

プロジェクトウィンドウでファイルまたはディレクトリを選択して`Check History`ボタンをクリックします。
すると履歴が以下のgif動画のようにリストアップします。

![unigithistoryviewer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/4bafad24-7a4c-a5a2-11c1-62067fd1c630.gif)

表示内容は以下です。

- commit日時(年-月-日)
- author
- コミットメッセージ

Countに最大表示履歴数を設定でき、また、左端の**Cボタン**をクリックするとコミットハッシュをクリップボードにコピーする事ができます。


## インストール方法

**Unity2019.3.4f1以降**[^1]の場合はUnityPackageManagerでインストール可能です。

- UnityPackageManager(以下:UPM)からインストール
- manifest.jsonを書き換えてインストール

**Unity2019.3.4f1未満**の場合は従来のunitypackageをインポートしてインストール出来ます。

- unitypackageをインポート

このどれかを選んで頂ければと思います。

### UPMからインストールする方法

![](https://user-images.githubusercontent.com/144386/87669945-d11d9a00-c7a9-11ea-8a21-aff2cb8117f8.png)
`Add Package Git URL`を選択します。

![](https://user-images.githubusercontent.com/144386/87670057-0de99100-c7aa-11ea-8555-12587b9fe646.png)
以下のパッケージURLを入力します。
`https://github.com/baobao/UniGitHistoryViewer.git?path=Assets/UniGitHistoryViewer`を入力してAddボタンをクリックします。するとインストールが完了します。

### manifest.jsonを書き換えてインストールする方法

UPMを使わない場合はmanifest.jsonのdependenciesに以下を追加してインストールしてください。

```json
"info.shibuya24.uni-git-history-viewer": "https://github.com/baobao/UniGitHistoryViewer.git?path=Assets/UniGitHistoryViewer"
```

### unitypackageをインポートしてインストールする方法

Unity2019.3.4f1未満の環境の場合は[unitypackage](https://github.com/baobao/UniGitHistoryViewer/releases)を[Releaseページ](https://github.com/baobao/UniGitHistoryViewer/releases)からダウンロードできますので、そちらをインポートしてインストールしてください。


## UniGitHistoryViewerを使うメリット

このツールを使うメリットは**複数の非エンジニアメンバーがUnityを触る場合**に生まれます。
非エンジニア同士、誰がどのファイルを触ったかという事実は重要で、何かトラブルが発生した際に、非エンジニアメンバーのみで**安全に**調査できる情報(ここでは履歴情報)が増える事で、エンジニアが介入することなく原因の特定をする可能性が上がります。

僕はエンジニア、非エンジニアがそれぞれ並列して仕事できている状態がベストだと考えています(時と場合にもよりますが)。
その状態を促進させるツールの1つになれば良いなと思っています。


## 最後に

よろしければ使って頂きバグがあればPR、issueをお待ちしております。
https://github.com/baobao/UniGitHistoryViewer

[^1]: Unity2019.3.4f1以降でないとPackage URLのクエリパラメータに対応していないため
Vue CLI 

#おさらい

### vue.jsとは
vue.jsは、Webアプリケーションのユーザインターフェースを効率的に構築するのに適したjavaScriptのフレームワークです。


### SPA
SPAは、基本部分が単一のページで構成されるWebアプリケーションです。
JavaScriptでサーバと通信してDOMを操作することでコンテンツを切り替えます。

### DOM（Document Object Model)
JavaScriptからHTML文書やXML文書の要素を操作する仕組みです。
Vue.jsはリアクティブなフレームワークであり、JavaScript側のVueインスタンス内のデータとHTMLを基本としてテンプレート構文に記述した内容がバインドされデータを変更すると、それがすぐDOMツリーに反映されWEBブラウザの表示が更新されます。

# Vue CLI

Vue CLIは、大規模なVueアプリケーションを効率的に作成するためのツールです。
Node.jsやVueRouterなどと連携していくことにより、シングルページアプリケーション（SPA）を効率的に開発できます。


#vue-cliでプロジェクト作ってみた
```
vue create hello
```
```
cd hello
```


### シングルファイルコンポーネント
拡張子が「.vue」で、javascript,html,cssがひとまとまりになったもの。
(ES2015のモジュール機能を使用している）

### Helloしてみた
```Hello.vue
<template>
  <div>
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
  name: "Hello",
  props: {
    msg: String
  };
</script>

<style scoped>
h1 {
  color: red;
}
</style>
```

やっぱり、VueCLIよりVueを先に勉強しよう。
なので一旦こちらは休憩します。
ちょうかんたんStyle Transfer。AppleのCreate MLで

#画像を選ぶだけ！お手軽ディープ・スタイル変換
画像のスタイル変換はディープラーニングのおもしろ技術です。
AppleのCreateMLというツールを使うことで、とてもかんたんに試せます。
<img width="858" alt="スクリーンショット 2020-07-22 10.25.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/c22f84fa-ae9e-3df0-b5c8-5f01514c78e0.png">


#CreateMLを起動
XcodeをControllキーを押しながらクリック、そしてOpenDeveloperTools、CreateMLを選択。
<img width="660" alt="スクリーンショット 2020-07-21 5.27.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/82085c35-1846-6687-77e9-018412e7f78c.png">
CreateMLのメニューからStyle Transferを選びます。
<img width="832" alt="スクリーンショット 2020-07-22 10.35.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/f6fac256-f3f4-3814-db98-32d01aae1b51.png">
それから、好きなプロジェクト名を入力します。
#スタイル画像とコンテンツ画像を選ぶ
好きなスタイルと、そのスタイルを適用したいコンテンツ画像を選びます。
スタイルは１枚、コンテンツ画像は複数枚選びます。
Training Stylize ImageとContents ImagesとValidation Imageの＋ボタンをクリックして、用意した画像（コンテンツ画像は複数枚なのでフォルダ）を指定します。
**今回はスタイル画像にひき肉を用意しました。**
<img width="857" alt="スクリーンショット 2020-07-22 10.17.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/2522bd25-59f1-648b-c917-c6bfd54f4fb9.png">

**コンテンツ画像**
<img width="718" alt="スクリーンショット 2020-07-22 10.14.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/5bfec8ba-589a-fcbe-a0d0-1b2a5f3001fb.png">

**トレーニング中に確認するためのValidation Imageも１枚必要です。**

計算回数とスタイル適用の強度（Strenth)と密度（Density）を指定できます。
今回はデフォルトを採用しています。
#トレーニングする
それから、▶️Trainボタンを押すと学習が開始されます。
計算ステップ５
<img width="859" alt="スクリーンショット 2020-07-22 10.18.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/65c72e4e-b988-e3b9-0f27-5813c880cab5.png">
計算ステップ２５０
<img width="857" alt="スクリーンショット 2020-07-22 10.21.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/456f5302-8e71-4d79-d7b4-e206910e68a9.png">
計算ステップ５００
<img width="858" alt="スクリーンショット 2020-07-22 10.25.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/aa8ee883-8c0e-8817-5d73-cca1b508c68c.png">
10分ぐらいでトレーニングは終わります。
トレーニングが終わったら、Previewページに好きな画像をドラッグ＆ドロップしてスタイルを適用できます。
<img width="855" alt="スクリーンショット 2020-07-22 10.26.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/62d3ddb4-37dd-0ed1-63fd-8fbe3ef15ecc.png">

OutputページでGetボタンを押して、CoreMLモデルを入手できます。
<img width="859" alt="スクリーンショット 2020-07-22 10.26.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/360746c1-caa5-1709-0d94-9341e1114fd4.png">
入手したmlmodelをXcodeにドラッグ&ドロップして、iOSアプリで使えます。

ね、かんたんでしょ？

・・・

ぼくのTwitterをフォローしてください。お願いします。
https://twitter.com/JackdeS11

お仕事のご依頼をこのメールにお願いします。
rockyshikoku@gmail.com

あと、Looks Good For Me(わるくないね）、押してください。
　　　　　　　　ここです　↓
チャオ🐣！
node+nodemonのdockerコンテナ

node + nodemon の開発用コンテナを作成した。実行環境はwin10とdocker-machine

 

```
.
├── app.js
├── docker-compose.yml
├── Dockerfile
├── package-lock.json
├── package.json
└── node_modules
```

```dockerfile
#Dockerfile

FROM node:12

WORKDIR /app

# ホストのpackage.jsonとpackage-lock.jsonを
# コンテナの/appにコピー
COPY ./package*.json ./

CMD bash -c "npm install && npm run dev"
```

```docker-compose.yml
version: '3.3'

volumes:
  node_modules:

services:
  app:
    build: .
    container_name: node
    ports:
      - '80:8081'
    restart: always
    volumes:
      # ホストのdocker-compose.ymlがあるディレクトリを
      # コンテナの/appマウントする
      - '.:/app'
      # ただしnode_modulesだけ除外するためnode-mudulesボリュームを
      # コンテナの/app/node_modulesにマウントする
      # コンテナ内でnpm install してもホストのnode_modulesは空のまま
      - 'node_modules:/app/node_modules'
    # 下２行はdocker run コマンドの-itオプションに相当する
    # 無いとコンテナが停止してしまう
    tty: true
    stdin_open: true
```

```package.json
{
  "name": "hoge",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "start": "node ./app.js",
    "dev": "nodemon -L ./app.js"
  },
  "dependencies": {
    "express": "^4.16.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.4"
  },
  "author": "",
  "license": "ISC"
}
```

以下のようにしてDockerfileで`npm start`するとnodemonは機能しなかった。`start`キーではダメ。さらに-Lオプションが必要。

```
 "scripts": {
    "start": "nodemon ./app.js"
  }
```


# 起動コマンドなど

### コンテナ起動

```bash
docker-compose up -d
```
node_modulesボリュームは自動で作成される。project_node_modulesという名前になる。docker-machineのIPアドレスでブラウザからnodeサーバーにアクセスできる

#### nodemonが機能してることを確認する

```bash
docker-compose logs -f
```

または

```bash
docker logs node -f
```

### コンテナ削除

```bash
docker-compose down --rmi all
```
--rmi all でイメージも削除される

### node_modulesボリュームを削除

```bash
docker volue rm project_node_modules
```

### ボリューム名を確認

```bash
docker volume ls
```

### docker-machineのIPを調べる

```bash
docker-machine ls
```

または

```bash
docker-machine ip
```

```bash
docker-machine ip default
```
非公開ディレクトリを使えないサーバでLaravelを設置する

#はじめに
公開フォルダーの上位フォルダーにアクセス権が無い例としては、レンタルサーバーにお名前.comサーバが該当しますが、普通にはLaravelをインストールできないです。
公開フォルダでシステムファイルをさらすことに。

そこで、公開フォルダーにLaravel用にフォルダーを作ってそこに入れてしまいます。


#フォルダー構造

公開フォルダー/
　├ .htaccess
　├ index.php
　├ /system ←ここにLaravelを沈める
　│　├ .htaccess
　│　├ /app
　│　├ /config
　│　├ /database
　│　├ /resources
　│　├ /routes
　│　├ /storage
　│　└ /vendor
　│　　
　└ favicon.ico


##index.phpの中身のパスを編集する
フォルダー構造を変えたので、パスを変更します。


```index.php
<?php

/**
 * Laravel - A PHP Framework For Web Artisans
 *
 * @package  Laravel
 * @author   Taylor Otwell <taylor@laravel.com>
 */

define('LARAVEL_START', microtime(true));

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/

require __DIR__.'/system/vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/

$app = require_once __DIR__.'/system/bootstrap/app.php';

/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);


```


##systemフォルダーの.htaccessを忘れずに
.htaccessを作成して中身をDeny from allを書いてsystemフォルダーに保存します。

```.htaccess

Deny from all
```

##最後に

できれば、公開フォルダーにシステムを入れる事は避けたいです。
依頼者のサーバを変えれないような場合、
この方法で、設置しておけば、消しちゃ駄目なフォルダーと分かりやすいと思います。
メンテナンス作業やりやすいと思います。

こんな感じで参考になれば。
ありがとうございます。
文系卒だけどいきなりRuby on Railsの勉強をはじめてみた #12 パスワードの再設定

前章からキャッチアップが難しくなってしまい、おそらく本章も本質的な理解は難しいのではという懸念を抱えつつ挑む。
1周目から完璧に理解できる人がいるとしたら、それを天才と呼ぶのだろう...。

本章では、パスワードの再設定の機能を実装する。
Railsチュートリアルでは新機能を実装する前にモックアップが掲げられているのでこれからなにをつくるのかは理解しやすい。

#12.1 PasswordResetsリソース
最初にパスワード再設定用のコントローラを作成する。

>上のコマンドでは、テストを生成しないというオプションを指定していることにご注目ください。これはコントローラの単体テストをする代わりに、今回は11.3.3から統合テストでカバーしていくからです。

とあるが、「単体テスト」と「統合テスト」の違い、それどころかそれぞれのテストの意味は忘却の彼方へ...。

パスワードリセットにおいても、`users`テーブルにカラムを追加するらしい。
`rest_digest`や`reset_sent_at`などだ。
ということは、複数回リセットした場合は`reset_sent_at`はどうなるんだろう？

#12.2 パスワード再設定のメール送信
この節は短い。
コードコピペしてたら終了したが、主にviewnに関するところを実装したっぽい。

#12.3 パスワードを設定する
パスワードを変更する際は次のケースに留意する必要がある。

1. パスワード再設定の有効期限が切れていないか
2. 無効なパスワードであれば失敗させる (失敗した理由も表示する)
3. 新しいパスワードが空文字列になっていないか (ユーザー情報の編集ではOKだった)
4. 新しいパスワードが正しければ、更新する

これらのロジックはどうやらコントローラーに実装するらしい。
[C#] Injectionのライフサイクル

開発メモ

下記は、Startup.csにて外のクラスをインジェクトする際のコードになります。


```csharp

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    services.AddScoped<IMyDependency, MyDependency>();
    services.AddTransient<IOperationTransient, Operation>();
    services.AddScoped<IOperationScoped, Operation>();
    services.AddSingleton<IOperationSingleton, Operation>();
    services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));

    // OperationService depends on each of the other Operation types.
    services.AddTransient<OperationService, OperationService>();
}
```

ここで、 AddScoped, AddTransient, AddSingletonの違いをメモ

こちらを参照しました
https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1


# AddTransient


> 有効期間が一時的なサービス (AddTransient) は、サービス コンテナーから要求されるたびに作成されます。 この有効期間は、軽量でステートレスのサービスに最適です。
要求を処理するアプリでは、一時的なサービスが要求の最後に破棄されます。



# AddScoped

> 有効期間がスコープのサービス (AddScoped) は、クライアント要求 (接続) ごとに 1 回作成されます。
要求を処理するアプリでは、スコープ付きサービスは要求の最後で破棄されます。


# AddSingleton

> 有効期間がシングルトンのサービス (AddSingleton) は、最初に要求されたときに作成されます (または、Startup.ConfigureServices が実行されて、サービス登録でインスタンスが指定された場合)。 以降の要求は、すべて同じインスタンスを使用します。 アプリをシングルトンで動作させる必要がある場合は、サービス コンテナーによるサービスの有効期間の管理を許可することをお勧めします。 クラス内のオブジェクトの有効期間を管理するために、シングルトンの設計パターンを実装してユーザー コードを提供しないでください。
要求を処理するアプリでは、ServiceProvider がアプリのシャットダウン時に破棄されたとき、シングルトン サービスが破棄されます。
CakePHP3.8 と Laravel7.x の「書き方」の違い ~ORM周りその1~

# CakePHP3.8 と Laravel7.x の「書き方」の違い ~ORM周りその1~

前: [設定周り](https://qiita.com/yokocho-comachi/items/7395faf51bd02da9dc76)

## Model の作成・設定

* CakePHP は bake すれば設定など諸々自動で設定される(CakePHP の 命名規則に従っている限り)  
https://book.cakephp.org/3/ja/quickstart.html#id5
* laravel は make することはできるが、設定などは自分の手である程度書く必要がある  
https://readouble.com/laravel/7.x/ja/eloquent.html

## クエリの要約

* CakePHP

[カスタムファインダーメソッド](https://book.cakephp.org/3/ja/orm/retrieving-data-and-resultsets.html#custom-find-methods)で実装する

**メソッド名を find〇〇 にし、 Query インスタンスを return する必要がある**

```php
    public function findHyphen(Query $query, array $options)
    {
        return $query->where(['favorite' => 'KAT-TUN']);
    }

    public function findArasick(Query $query, array $options)
    {
        return $query->where(['favorite' => '嵐']);
    }

    public function findVeteran(Query $query, array $options)
    {
        return $query->where(['fan_career >' => '5']);
    }
```

使うときは `Table::find()`, `Query::find()` にファインダー名を渡す

```php
$usersTable = TableRegistry::getTableLocator()->get('Users');
$query = $usersTable->find('hyphen')->find('veteran');
```

* Laravel

[ローカルスコープ](https://readouble.com/laravel/7.x/ja/eloquent.html#local-scopes) で実装する

**メソッド名を scope〇〇 にし、 Builder インスタンスを return する必要がある**

```php
    public function scopeHyphen(Builder $query)
    {
        return $query->where('favorite', '=', 'KAT-TUN');
    }

    public function scopeArasick(Builder $query)
    {
        return $query->where('favorite', '=', '嵐');
    }

    public function scopeVeteran(Builder $query)
    {
        return $query->where('fan_career', '>', '3');
    }
```

使うときは `Model`, `Builder` からスコープ名の関数を呼び出す

```php
$users = Users::hyphen()->veteran()->get();
```

## Iterable 問題(名前は勝手につけた)

ORM はそれぞれ、CakePHP => Query, Larabel => Builder だが、Iterable (簡単に言うと foreach できること)かどうかに違いがある。 

* CakePHP

```php
$query = $usersTable->find('hyphen')->find('veteran');
foreach ($query as $entity) // foreach されるタイミングで SQL が発行・fetch され、レコードを foreach することができる
```

* Laravel

```php
$builder = Users::hyphen()->veteran();
foreach ($builder as $property) // iterable ではないので、普通のプロパティ参照のようになってしまう
```
【初心者でもわかる】:hoverとcursor: pointer;でボタンのホバー時の動きをいれる方法

# どうも、7noteです。一般的なボタンの動きを実装していきます。
どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/pointer/
VBA：「条件付き書式」を特定列を条件として範囲に設定

# 目的

- 「A2：G100」の範囲に対して条件付き書式を設定する。条件と書式は次の通り。
- 「A2」を開始セルとする列が空白の場合、対象行を赤色にする。
- ※条件付き書式を範囲に設定することで、**ループせず**に行の書式を変えられる。

# コード

```vb
Sub setFormatCondition()

  'A2:G100の範囲に条件を設定
  With Sheet3.Range("A2:G100")
    ' Typeは数式（xlExpression）。
    '「$A」で列全体を指定
    'Fomula1で空白の場合の条件を設定。
    .FormatConditions.Delete
    .FormatConditions.Add Type:=xlExpression, Formula1:="=$A2="""""
    .FormatConditions(1).SetFirstPriority
    With .FormatConditions(1).Interior
        .PatternColorIndex = xlAutomatic
        .Color = 255
        .TintAndShade = 0
    End With
  End With

End Sub
```
# 結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/81703c76-7a14-1cf0-5e69-ea22a74b3d75.png)
STIパターンでtweet機能を作った学習記録

この記事の内容は現在レビュー待ちなので変更あるかもです！
##STI（単一テーブル継承）とは
文字通り一つのテーブルを親クラスから子クラスに継承させる事！
今回の場合、親`Tweet`→　子`Mediatweet`　`Texttweet`になります。それぞれメディアツイートとテキストツイート用のクラスです！

といっても、テーブルが同じなので、親も子も全てのクラスが同じカラムを持ってます。
なので`Mediatweet`にも`content`カラムがありますし、**`Texttweet`にも`img`カラムがあります。**

```db/schema.rb
  create_table "tweets", options: hogehoge
    t.text "content"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "img"
    t.integer "user_id"
    t.string "type"
  end
```
##何故そうするのか
モデル事に差分を書き分けやすくなります。
例えば空欄無効のバリデーションをtexttweetにだけ書くと、画像はテキスト無しのツイートが可能になります。
でもほぼ同じ内容なので、テーブルは共有できちゃうSTIが良いのでは、というわけです。
##実装方法

１、しれ〜っと`db/schema.rb`に既にありましたが、親クラス(テーブル)に`type`カラム（string型）を持たせます。
２、各モデルを作ります。親モデルは`rails g model `などで作って子モデルなどは`app/model/`に直接作ります

```models/tweet.rb
class Tweet < ApplicationRecord
end
```

```models/mediatweet.rb
class Mediatweet < Tweet
end
```
```models/texttweet.rb
class Texttweet < Tweet
end
```

とりあえずこれだけでSTIの実装は終わりです。あとは、自動でやってくれます。
例えばこれで`Mediatweet.create`等でデータベース登録すれば`type`カラムに`Mediatweet`とデータが入ったレコードが追加されます。

##form_withで取得したparamsの内容でモデル振り分け
メディアデータがあるかどうかで自動的にモデルを振り分けたいので下記のように実装しました。

```index.html.erb
<%= form_with model: @tweet, url: tweets_path do |form| %>
  <%= form.text_area :content %><br>
  <%= form.label "画像をアップロード" %><br>
  <%= form.file_field :img %>
  <%= form.submit '投稿' %><br>
<% end %>
```
今回は、indexにそのまま投稿フォームがある投稿兼一覧ページです。
画像のアップローダーについては`carriewave`で実装しています。そこについては割愛します。
上記フォームからsubmitして送られるパラメータは

```
{
"authenticity_token"=>"hoge", 
"tweet"=>{"content"=>"hoge", "img"=>"hoge"}, 
"commit"=>"投稿"
}
```
こんな感じの二重構造（{}の中に{}がある構造）のパラメータが取得できます。

*ちなみにですが
form_withで model: を指定するとこのような構造になり、url:のみ指定すると二重構造になりません。
僕はこれがわかってなくてかなりハマってました、、、*

そしてコントローラーのcreateアクションへ自動でマッチします

```tweets_controller.rb
  def create
    @tweet = tweettype_class.new(tweet_params)
    if @tweet.save
      redirect_to("/tweets")
    else
      @tweets = Tweet.all.order(created_at: :desc)
      render("index")
  #レンダリングで元の投稿件一覧ページに戻りますこの際、form_withのurlを指定していないと、
  #form_withのルートが子モデルに引っ張られてエラーになります（例)元teets_path　レンダリング後→texttweets_pathでno muchになる。
    end
  end
  private

  def tweet_params
  #requireでキーがtweetの部分だけ抽出してます({"content"=>"hoge","img"=>"hoge"})
    params.require(:tweet).permit(:content, :img).merge(user_id: @current_user.id)
  end
  #[:img]のデータの有無でモデルを振り分けています
  #二重構造なのでキーも二重に指定しないと正しく値がとれません
  def tweettype
    case
    when params[:tweet][:img].present?
      'mediatweet'
    when params[:tweet][:img].blank?
      'texttweet'
    end
  end
  #もらった文字列をキャメルケースに変換して,さらに定数名に変換しています
  #（例）mediatweet.cmelize=>Mediatweet.constantize=>Mediatweet(id: integer, content: text, created_at: datetime, hogehoge.... )
  def tweettype_class
    tweettype.camelize.constantize
  end
```

こんな感じで、画像がアップロードされたかどうかで自動でモデルを振り分けてみました。

こうすることで、それぞれのモデルで役割を書きわけやすくなりました！
（備忘録）🗃【npm】cpio: readが出たらパッケージを再ダウンロードする

## 環境
CentOS 7.4.1708

## やりたいこと
```shell
sudo rpm -iv --force gmp-4.3.1-13.el6.x86_64.rpm
warning: gmp-4.3.1-13.el6.x86_64.rpm: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Preparing packages...
gmp-4.3.1-13.el6.x86_64
error: unpacking of archive failed on file /usr/share/doc/gmp-4.3.1/COPYING.LIB;5ef16eb0: cpio: read
error: gmp-4.3.1-13.el6.x86_64: install failed
```

「cpio: read」って表示されるのを解消し、rpmファイルをインストールする

## やったこと
単純にファイルが破損して読み込めないだけだった
↓
wgetにて対象ファイルを再ダウンロードし、
再度rpm実行でインストール成功
arXivのtexソースコードを展開する

arXivはother formatsからSourceをダウンロードすることができます．


> Delivered as a gzipped tar (.tar.gz) file if there are multiple files, otherwise as a PDF file, or a gzipped TeX, DVI, PostScript or HTML (.gz, .dvi.gz, .ps.gz or .html.gz) file depending on submission format.

なんていう記載がありますが，微妙に展開するのに引っかかったのでメモ．

```bash
tar -xvf (ダウンロードしたファイル名)
```

`tar -zxvf`ではないんですね．あと，tarの性質上そのディレクトリ内に大量のファイルが展開・作成されるので注意．
NuGetのキャッシュをすべてクリアする

NuGetを利用していると、たまにキャッシュが「悪さ」をすることがあります。
手動（CLI）で消すこともできますが、キャッシュは複数あるのですべてを消すのはちょっと面倒です。

そこで、Visual StudioのGUI上からすべてのキャッシュを一括で削除する方法を紹介します。

まずは「ツール」→「オプション」を開きます。

![SnapCrab_【NIT-03】帳票識別 - Microsoft Visual Studio_2020-7-22_8-40-43_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99262/2bcd6b64-14bf-aaa2-7388-d64686fe6e3b.png)

つづいて「NuGetパッケージマネージャー」→「全般」を選択し、「すべてのNuGetキャッシュをクリア」をクリックしてください。

![SnapCrab_【NIT-03】帳票識別 - Microsoft Visual Studio_2020-7-22_8-41-0_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99262/f4b96c88-d417-b3a5-f1b0-6597be651003.png)

以上です。
【Docker】 データの”保存”する仕組みについて理解した話

# 1. はじめに
dockerやdocker-composeを使って、チームで使うサービス(re:dash）を運用したら、
バージョンアップとかガンガンできるだろうし、バックアップもリストアも自由自在ヒャッハーできるしょ！
と思って使いはじめたが、やりたいことができずきハマった、データ保存先について整理した記事です。

”保存”に特化しているため、dockerがほかの仮想マシンと比較してどうかなどの、メリットとデメリットなどを記載はしません。だって面倒くry。

この記事を読むと、dockerのデータを”保存”しているのか、イメージを理解できようになります(たぶん)。

# 2. dockerがデータを"保存"するモノとは

データを”保存"する「イメージ」「ボリューム」「コンテナ」の概念について、まとめます。
概念が違うものなので、並べることが適切ではないかもしれませんが、保存を理解するためには必要なので、並べて書きます。

※ Dockerfile, docker-compose.yml と記載したものは設定ファイル名の例です。
　実際には変更が可能なため、正しくありませんが便宜的に上記表現で記載しています。

## 2.1 イメージ
Dockerfileで定義された、「docker image」で管理される領域、またはDocker Hubなどのサービス可能に登録されたものです。
どのような構成、何をインストールしておくか、といったことを”保存”できます。


## 2.2 ボリューム
データを"保存"するデータ領域のことを指します。ボリュームといっても、コンテナ内部(Dockerfile volumeコマンドなど）と外部マウント(docker run -v xxx:yyyy）の２つのことが混同されて記述されている記事があるため、注意が必要です。

外部マウントのボリュームは、dockerサービス内で定義されたボリューム(docker volume createや他のコンテナのボリュームなど）と、dockerのホストのデータ領域の、いずれかを指定することができます。

簡単な図にまとめると、以下のようなイメージです。
![docker-volume.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281608/726f87f9-026d-49f1-5660-d5d880a520d5.png)
※注意 正確にはボリュームをマウントする指示をせずに実行した場合には、dockerのvolumesに実体が作られ、--rmオプションなどがついてると自答削除できるので、図ではわかりやすさのため、コンテナ内にあるように歪曲して記載しています。

## 2.3 コンテナ
イメージに対して「docker run」を実行して作られる、コンテナとよばれるインスタンスのことを指します。
このインスタンスには、起動中、停止中の状態をもち、docker start, docker stopなどで、開始、停止をコントロールできます。
起動中の場合に、イメージで作ったサービスが利用できるようになります。

起動時に、マウントする先を明示的におこなっていない場合、コンテナで作成されたボリュームは、起動したコンテナが削除されるまで”保存”できます。その状態で、うっかり、「docker rm コンテナ」としてしまうと、
保存されたデータが削除され、泣くことができます。

#3 データの保存先について（考察）
サービスとして提供するのであれば、dockerのボリューム領域（docker volume createで作った領域）か、ホストのデータ領域を使うのが賢明だと思います。

ただし、dockder for windows (desktop 2.3.0.3, engine 19.03.8, compose 1.25.5)では、
ボリュームに対して権限を設定しようとするとうまくいかない不具合があるため、アプリによっては、dockerのボリューム領域を使う必要があります(postgresの公式イメージのdataフォルダなど)。

そのため、現状でバックアップまで考えた運用については、ホスト領域とdockerのボリューム領域をマウントして、コピーするだけの仮想コンテナを作ってあげるなど工夫が必要そうです。
※ 実はそれでも権限周りはいけてなく、現状ではlinuxの上に構築するほうが無難です。

#4 おわりに
dockerについて勉強をはじめて、1か月たたない初心者なので、もし間違いがあったら、指摘をお願いします。
git branch と tag の使い分け

git の branch と tag の使い分けが気になったので、Kubernetesプロジェクトを例に、整理してみた。プロジェクト毎の決め事だと思うので、必ずしもこの方法が正しいという訳ではない。一つの参考として見做して欲しい。

## branch とは

[ブランチ](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%A8%E3%81%AF
)とは、開発の本流から分岐し、本流の開発を邪魔することなく作業を続ける機能


## tag とは

[タグ](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-%E3%82%BF%E3%82%B0)とは、歴史上の重要なポイントに印をつける機能です。よくあるのは、この機能を (v 1.0など) リリースポイントとして使うこと。

## Kubernetesプロジェクトでの branch と tagの使い分け

このプロジェクトでは、全てのリリースの中で最新のコードが、masterにある。そして、各リリースで保守されている最新コードが、release-x.xx にある。例えば、`git clone http://https://github.com/kubernetes/kubernetes` や `git clone -b release-1.19 http://https://github.com/kubernetes/kubernetes` として ローカルにクローンしてビルドしても、動作するバージョンをビルドすることはできない。つまり、開発途上のコードだからである。

tagは、v1.18.4 や v1.18.5 など、それぞれの マイナーバージョンの下のパッチバージョンに対して、tag が設定される。この tag を利用してクローンするには、`git clone -b <tag名>  http://https://github.com/kubernetes/kubernetes`  としてクローンされる。　または マスターをクローンした後、`git checkout -b v1.18.4` などとすることで、タグが付与された時点のコードを使用できる。これによって、リリースされた時点のコードを取得できる。

ブランチのリストを表示した様子

![s-branch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42829/74df1711-dec2-ac88-51d9-2e7a0e7eebbe.png)

タグのリストを表示した様子

![s-tag.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42829/b4ed936d-2ea9-2df3-293b-f79211653dc3.png)


## まとめ

branchは、その名の通り、分岐を意味する。そのため、branch を作成した後、branch に対して、更新を続けていくことができる。一方、tag を指定して branch のようにクローンやチェックアウトができても、しかし、tag に更新を加えることは出来ない、いわゆる スナップショットのような存在とみなせる。

## 参考資料
* Gitを使った分散開発管理7 – ブランチとタグを使う, https://dev.classmethod.jp/articles/git-branchtag/
極・初心者、初学者向けプログラミング学習に挫折しないコツ

何度も挫折した、プログラミング初学者だった昔の自分に向けて。


コツは３つ
１．急がない
２．目標を時間に設定する
３．人と比べない

#急がない
1つ目のコツは急がないこと。プログラミング学習は単純な暗記のように目に見える実績が出るわけでもない。一日考えて「できない！」となると、投げてしまいがち。急いではいけない。
何日考えてもいい。一度自分でクリアした課題は、同じようにつまづくことは二度とない。
とにかく、自分でできることを1つずつ、着実に積み上げること。

#目標を時間に設定する
プログラミング学習をする目的はなんだろうか？
と考えた時、転職だったり副業だったりすると思う。
そうすると逆算して、「このぐらいのレベルのものを作らなきゃ！」という気持ちになる。
さらに「このレベルにならなきゃいけないのに自分はまだまだだぁ！！！」と悲観的になって挫折する。

独学で一人前になるためには2000時間の学習時間が必要と言われている（らしい）。
周りに教えてくれる環境がある場合(仕事など）は、1000時間が1つの目安だと（らしい）。だいたい半年ぐらい。

・・・と考えると、あなたはどのくらいの時間勉強しただろうか？
僕はToggleというアプリを入れて時間を計測するようにしたけど、まだ500時間くらい。
まだぜんぜん一人前じゃない。

たったの数時間で一人前になろうとはしてないだろうか？
まずは100時間ぐらいを目指して、その次は300、そして500時間と勉強時間を目標にするのは個人的には効果があった。

##余談
某スクールに通っていた。広告の流れる有名なところだ。
そこでは通学中に180時間の学習時間を目安にしているらしい。
学習時間が全然足りないと思う。なので挫折率高めなのかな、と。

#人と比べない
「初学者は挫折しないように」みたいにTwitterでつながる人がいる。もちろん僕もその一人だった。初心者エンジニアとつながりた、のタグとかでツイートしたりイイねしたりした。

ただ、入ってくる情報を取捨選択できないので止めた。
自分より成長の早い人がいっぱいいるからだ。
他人と比べても仕方ない。「プログラミング学習始めました！」とうたう人の中には、時間を持て余しポテンシャルにあふれている大学生などがまぎれていたりしる。彼らの情熱と勉強量にはかなわない。比べてもしかたない。とにかく自分でコツコツと続ける一択。
[SwiftUI] allowsHitTestingを利用してGestureの活性・非活性をコントロールする

# iOS14で動作しません
iOS14で動作しなくなっていたので、対応を下記ブログにまとめました。
https://kentaro.app/posts/fix-swiftui-allows-hit-testing-sample

## 概要
`allowsHitTesting()` を利用すると、「○○な時はGestureで何かしたいけど、xxなときはGesture効かないようにしたい」みたいなことが実現可能です。
簡単なサンプルを作ったので、それをもとに説明します。

## サンプル
* `allowsHitTesting` をON / OFFする `Toggle`
* `Toggle` がONのときはViewをダブルタップすると背景色が切り替わる
* `Toggle` がOFFの場合はViewをダブルタップしても何も起きない

### こんな感じ
![sample](https://user-images.githubusercontent.com/17519073/88113324-83ab8d80-cbec-11ea-97ce-b3647557536c.gif)

## ソースコード

```swift
import SwiftUI

struct ContentView: View {

    @State private var allowsHitTesting = true
    @State private var isDark = false

    var body: some View {

        VStack {
            Toggle(
                "allowsHitTestingのON / OFF",
                isOn: $allowsHitTesting
            )

            Divider()

            Text("allowsHitTestingがONのときは、ダブルタップで背景色が変化します。")
                .frame(
                    maxWidth: .infinity,
                    maxHeight: .infinity
                )
        }
        .contentShape(Rectangle())
        .padding()
        .foregroundColor(
            Color(isDark ? .systemBackground : .label)
        )
        .allowsHitTesting(allowsHitTesting)
        .gesture(
            TapGesture(count: 2)
                .onEnded {
                    self.isDark.toggle()
                }
        )
        .background(
            Color(isDark ? .label : .systemBackground)
                .edgesIgnoringSafeArea(.all)
        )
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

## 解説
### allowsHitTesting(_:)

> このビューがヒットテスト操作に参加するかどうかを設定します。

このメソッドに `Bool` を渡すとヒットテスト操作に参加する / しない が設定できます。

* `true`
    * `Gesture` 等の操作を受け付ける 
* `false`
    * `Gesture` 等の操作を受け付けない

https://developer.apple.com/documentation/swiftui/form/allowshittesting(_:)

サンプルコードでは `Toggle` の値を `allowsHitTesting（）` に渡して、 `Toggle` がONのときはViewのタップ操作を受け付け、OFFのときは何もしない、という動作を実現しています。

### disabled(_:) ではダメなのか？

```diff
+.disabled(!allowsHitTesting)
-.allowsHitTesting(allowsHitTesting)
```

↑でよさそうな感じもするが、 `disabled(_:)` だと `Toggle` も効かなくなってしまいます。

`disabled(_:)` で問題ないView構造の場合はdisabledを利用するのでOKかと思います :ok_woman: （そのようなケースのほうが多そう）

## サンプルコードのリポジトリ

* https://github.com/taguchi-k/swiftui-allows-hit-testing-sample

いじってみたい方はこちらからどうぞ。
Previewでも普通に動作確認できました。

## 環境
* Xcode 11.4
ConoHa で立ち上げた Laravel イメージだと ZipArchive が使えなかった。

## 状況
手元の Homestead 上では普通に使えてたので、気にせず開発していたのだけど、デプロイしたらエラー吐いたので困った。
とりあえず拡張を確認する。

```bash
$ php --ri zip
Extension 'zip' not present.
```
ないね。

### 環境
* ConoHa VPS Laravel イメージ
* PHP 7.2.16
* Laravel Framework 5.8.36
* CentOS Linux release 7.6.1810 (Core)
* yum リポジトリは remi-php72 と remi-safe が使える

## インストール

```bash
$ sudo yum install --enablerepo=remi,remi-php72 php-pecl-zip
```

### apache 再起動
```bash
$ sudo systemctl restart httpd.service
```

### 確認
```bash
$ php --ri zip

zip

Zip => enabled
Zip version => 1.19.0
Libzip headers version => 1.7.0
Libzip library version => 1.7.3
BZIP2 compression => Yes
XZ compression => Yes
AES-128 encryption => Yes
AES-192 encryption => Yes
AES-256 encryption => Yes
```
textareaで取得した値の改行が消えてしまった時に反映させる方法

textarea、inputで値を取得して、表示させる時に改行を含めて表示させる方法です。

## textareaで取得した値に改行が入らない

![スクリーンショット 2020-07-18 16.05.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/e11a1cee-f9af-f97d-d945-d590ecd121a0.png)

上記のようにデフォルトだと、textareに改行を入力しても、表示させる時に改行表示ができません。

## white-space:pre-wrapを指定する

```HTML
<p style="white-space:pre-wrap;"></p>
```
表示させるHTMLにwhite-space:pre-wrapを指定することで、改行も表示させることができます。

![スクリーンショット 2020-07-18 16.17.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/1be0a98b-b8be-43a3-a478-56053d61ac27.png)
jsでパイプライン演算子もどき7種

# javascriptでパイプライン演算子を使いたい
こういうやつ。

```javascript:
text = '{"0": "a", "1": "b"}';
text |> JSON.parse |> Object.entries |> (a=>new Map(a)) |> console.log;// これ
// console.log(new Map(Object.entries(JSON.parse(json)))); と同等
```
まだステージ1で使えないので、代替を考えてみる。
## 関数で実装
まずは素直に、初期値と関数を渡すと返り値を返すだけの関数を実装してみる。

```javascript:define.js
const chain = (start, ...fns)=>{
  let result = start
  for (const fn of fns) {
    result = fn(result)
  }
  return result
}
```
使ってみる。

```javascript:how-to-use.js
const result = chain(text,
  JSON.parse,
  Object.entries,
  a=>new Map(a)
)

console.log(result)
```
シンプルで見通しがいい。もうこれでいいんじゃないかな。

## メソッドチェーン(もどき？)
せっかくなので、別の方法でも実装してみる。

```javascript:define.js
const start = (val)=>{
  return {
    chain(fn) {return start(fn(val))},
    end() {return val}
  }
}
```
```javascript:how-to-use.js
const result = start(text)
.chain(JSON.parse)
.chain(Object.entries)
.chain(a=>new Map(a))
.end()

console.log(result)
```
これはこれで、分かりやすくて良いと思う。

## prototype拡張
直接メソッドチェーンしてみよう。

```javascript:define.js
Object.defineProperty(Object.prototype, '_chain', {
  configurable: false,
  enumerable: false,
  value: function(fn){return fn(this)}
});
```
```javascript:how-to-use.js
const result = text
._chain(JSON.parse)
._chain(Object.entries)
._chain(a=>new Map(a))

console.log(result)
```
Objectのprototypeを直接拡張するのは弊害が大きすぎるので、絶対やめましょう。prototype拡張を行うライブラリを読み込んでいる場合、名前がバッティングした時に死にます。
## prototype拡張 その2
symbolを使う方法。

```javascript:define.js
const chain = Symbol('chain');
Object.defineProperty(Object.prototype, chain, {
  configurable: false,
  enumerable: false,
  value: function(fn){return fn(this)}
});
```
```javascript:how-to-use.js
const result = text
[chain](JSON.parse)
[chain](Object.entries)
[chain](a=>new Map(a))

console.log(result)
```
symbolを用いてprototype拡張すれば、ライブラリ等とバッティングせずに済むため安全安心。
但し、使いやすくは…ない。

## Array.prototype.map()使用
一旦配列に入れると、配列操作系の関数を使うことができる。

```javascript:how-to-use.js
const result = [text]
.map(JSON.parse)
.map(Object.entries)
.map(a=>new Map(a))
[0]

console.log(result)
```
配列から取り出すために、最後に[0]を付ける必要がある。いつか書き忘れそうで怖い。
## Array.prototype.reduce()使用
reduceも使える。今度は関数の方が配列に入っているので注意。

```javascript:how-to-use.js
const result = [
  JSON.parse,
  Object.entries,
  a=>new Map(a)
].reduce((val, fn)=>fn(val), text)

console.log(result)
```
そろそろパイプライン演算子とは程遠くなってきている。
## Promise使用
Promiseのthen()の引数には関数を渡している。この仕様を、関数呼び出しのためだけに利用してみる。

```javascript:how-to-use.js
//返り値を使用しない場合
new Promise(r=>r(text))
.then(JSON.parse)
.then(Object.entries)
.then(a=>new Map(a))

//返り値を受け取る場合
(async function(){
  const result = await new Promise(r=>r(text))
  .then(JSON.parse)
  .then(Object.entries)
  .then(a=>new Map(a))

  console.log(result)
})()
```
返り値を使いたいときに.then()で繋げるか、async関数内でawaitする必要がある。
非同期処理と関係ないところにPromiseをいきなり使ったら混乱しそうだなとは思う。
Unityでのゲーム制作時、オブジェクトの移動処理が重い場合に行った事とその効果

筆者の環境：OS:Windows10, Unity 2019.3.5f1 使用言語：C#
利用Asset：DOTween,Destructible2D
筆者のプログラミング歴：2020年1月よりUnity上でC#の勉強を開始。

現在開発中のゲーム（2D）のメインが『落下してくるオブジェクトを切断する』といった内容なのですが、切断後に異常に動きが遅くなる現象が多発し、ゲーム性を著しく損なう為、対策を調べつつ対処した結果を、ざっくりではありますが、備忘録として残そうと思います。

まず、UnityのProfilerを起動し、どこの処理が重いのかを調べました。
結果、『Physics2D.FindNewContacts』という部分に多大な時間を取られていました(数百~千数百ms)。
調べてみると、どうやらRigidbody2Dが良くないようです。
しかし、色々と試しましたが、Rigidbody2Dを外したり、Kinematicにすると思った動きが出来なかった為、以下の事を試しました。
※筆者の環境で、効果が高かったと思われる順に表記。

●切断されるオブジェクトのSpriteのサイズを小さくした。
Spriteを選択した時のInspectorから、MaxSizeを小さく、Pixels Per Unitの値を大きくして調整しました。

●オブジェクトのGravity Scaleの値を小さくした。
これは、単純に動きが早すぎて切断し辛かったのでスピードを遅くする目的でやったのですが、カクカク感が軽減されました。

●Update関数をFixedUpdateに変更。
数値としては反映されているか分かりませんでしたが、見た目のカクカクを軽減する効果があったように感じました。

●Project SettingsのTime Fixed Timestepの値を”小さく”した。
処理を軽くする為には、値を大きくすべきだそうですが、大きくすると思ってもない動きをしたり、若干ワープしたような動きをするので、逆に小さくしてみると、スムーズに動くようになったので、小さくしてしまいました。

結果、目的がブレたような気もしますが、見た目のスムーズさは向上したのと、固まったかのような現象はほとんど起こらなくなったので、とりあえずはこのまま開発を進めようと思います。
新情報等見つけたら、再度試してこちらに追記します。

ここまで読んでいただき、ありがとうございました。