OmniAICreator/Qiita-1.07M huggingface dataset:
【GitHub】別のブランチで魔改造したファイルをmasterブランチに別名でマージする

# 環境

- GitHub
- Git
- VSCode

# 経緯(読む必要は特にない)

<details><div>

## CソースをLINEで(平文で)貰ってデバッグをすることに
しかし環境は以下のとおりだった!

- スマホ：LINEあり
- デスクトップ：LINEあり、コンパイラなし、Gitあり
- ノートPC：LINEなし、コンパイラあり、Gitなし(SourceTreeはある)

デバイス一つで解決しないという悲しみ…

## 解決方法
1. デスクトップにコンパイラを入れる
2. ノートPCにLINEを入れる
3. ノートPCにソースを移動する

あたりを思いついた。それぞれ面倒さがあったが…せっかくだしGitHub使ってみるか！
ってことで3.を選択。

## なんやかんやで解決
せっかくだしリファクタリングをすることに。
普通のバグを潰してGitHubに上げた後、ブランチを作成しリファクタリングを開始。

### しかし、よく見ると色々問題が…
- Gitの仕組みをよく分かっていなかったので、余計なフォルダまでGitHubに上がっていた
- それに対応したのがブランチを作成した後だったので、各々削除する羽目に
- ブランチで作成したファイルが原型を留めていなかったので、別ファイル名で保存したくなった

そんな中で格闘した結果を、使ったコマンドを含めてざっくりと残しておく。

</div></details>

# 今回の作業の流れ

1. GitHubにリポジトリを作成
2. GitHubにCソースをアップ(push)
3. 別のPCでGitHubからソースを取得(clone)
4. 修正をローカルのmasterブランチに反映(commit)
5. ローカルのブランチをGitHubに反映(push)
6. リファクタリング用のブランチを作成(branch)
7. リファクタリング、ブランチに反映(commit)
8. フォルダ構成の整理(省略)
9. リファクタリングしたファイルのファイル名を変更(mv)
10. **masterブランチにブランチのファイルをマージ**(本題)

本題以外も大変勉強になったが、とりあえず今回は本題についてのみ書いておく。

# 元は同じファイルを、別名でマージする方法
上記作業の流れの、9.まで終わっていると仮定する。
状況は下記のとおりとする。

- masterブランチ(現在のブランチ)
    - source.c
- refactoringブランチ
    - source_refactoring.c

## 普通にmasterブランチにマージしようとした場合
```
merge refactoring
```
と入力しても、ファイルが大きく変わっている為、コンフリクトとして拒否されてしまう。

## 新しいファイルとしてコミットすればよい
まずは、refactoringブランチから該当のファイルを取得する

```
git checkout refactoring -- source_refactoring.c
```

このファイルを新規ファイルとしてadd→commitしてやればよい

```
git add source_refactoring.c
git commit -m "ファイル追加" -m "リファクタリングしたファイルを別名で追加"
```

あとは煮るなり焼くなりGitHubにpushするなり

```
git push origin master
```

## 問題点

- 新規ファイルとして追加する為、masterブランチにこれまでの履歴が残らない
    - 今回はrefactoringブランチに履歴があるし、特にほしい履歴でもないのでどうでも良かった
    - もし履歴を残すなら、リファクタリングをする段階でコピーしたファイルをmasterブランチにて作成→refactoringブランチにて編集→masterブランチにマージだろうか

# 振り返り

ついさっきまでローカルで履歴管理ができる程度だったのが、GitHubを活用することでデバイスを跨いで管理できるようになった。
Gitについてかなり勉強になったと共に、今後も活用できそうだと自信が湧いてきた。
GoでLambdaを使う

#シンプルなGETをGoで送る方法
リクエストヘッダー(`func DumpRequestOut`)
レスポンスヘッダー(`func DumpResponse`)の内容を取得する

```main.go
package main

import (
  "net/http"
  "io/ioutil"
  "fmt"
  "net/http/httputil"
  "github.com/aws/aws-lambda-go/lambda"
)

type MyResponse struct {
  Message string `json:"end:"`
}


func get() (MyResponse, error) {
  url1 := "http://xx.xxx.xx.xxx"
　url2 := "/hoge"
  url := url1 + url2

  req, _ := http.NewRequest("GET", url, nil)

  dump, _ := httputil.DumpRequestOut(req, true)
  fmt.Printf("%s", dump)

  client := new(http.Client)
  resp, _ := client.Do(req)

  dumpResp, _ := httputil.DumpResponse(resp, true)
  fmt.Printf("%s", dumpResp)

  defer resp.Body.Close()


  byteArray, _ := ioutil.ReadAll(resp.Body)
  fmt.Println(string(byteArray))

  return MyResponse{Message: fmt.Sprintf("received!!")}, nil
}

func main() {
  lambda.Start(get)
}
```

#lambdaの実行結果
(関数から返されら結果)

```
{
  "end:": "received!!"
}
```

(ログ出力)

```
START RequestId: e2df642c-a6e5-4837-bdf6-3085b859a7d4 Version: $LATEST
GET /hoge HTTP/1.1
Host: xx.xxx.xx.xxx
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip

HTTP/1.1 200 OK
Content-Length: 216
Content-Type: text/plain; charset=utf-8
Date: Wed, 08 May 2019 06:16:43 GMT

*Response*

END RequestId: e2df642c-a6e5-4837-bdf6-3085b859a7d4
REPORT RequestId: e2df642c-a6e5-4837-bdf6-3085b859a7d4	Duration: 511.41 ms	Billed Duration: 600 ms 	Memory Size: 512 MB	Max Memory Used: 21 MB	
```

#デプロイ
rm Gopkg.*
dep init
GOOS=linux GOARCH=amd64 go build -o hello
zip handler.zip ./hello
aws s3 cp ./handler.zip s3://xxxx
Craft CMS で LiteSpeed Cache を使う方法

mixhost などでつかわれている LiteSpeed Cache
こちらの設定方法を参考にしてプラグインを使えば LiteSpeed Cache は有効になる。

> How to integrate LiteSpeed Cache into Craft 3 - Kualo Limited
> https://my.kualo.com/knowledgebase/109_litespeed-cache/1497_how-to-integrate-litespeed-cache-into-craft-3.html

軽く試したところキャッシュは有効になっていたが、管理画面のセッションがおかしくなってログアウトを繰り返した。
たまたまだったのかもしれないがとりあえずメモ。
（メモ）Jetpack ComposeデモアプリをWindowsでビルドする

手元にWindows10 Pro機しかないので、WSLでソースコードのチェックアウトとビルドだけ行った。

[公式サイトの手順](https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/ui/README.md)に従う。

# repoのダウンロード

ビルドツール[repo](https://gerrit.googlesource.com/git-repo/)を導入していない場合は必要。

["Downloading the Source"](https://source.android.com/setup/build/downloading#installing-repo)を参考にした。

```
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
```

# ソースコードのチェックアウト

["AOSP AndroidX Contribution Guide"](https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/README.md)を参考にした。

repo syncには時間がかかるのでその間コーヒーでも飲んでね:smile:とのこと。私の環境では一度失敗したのでもう一度同じコマンドを流した。

```
$ repo init -u https://android.googlesource.com/platform/manifest -b androidx-master-dev

...

repo has been initialized in /mnt/f/Android/JetpackCompose

$ repo sync -j8 -c

...

Syncing work tree: 100% (21/21), done.
```

# ビルド

WindowsのAndroid Studio 3.4ではdependenciesが解消しないが、build.gradle.ktsがよくわからないのでお手上げ。学習必須。

仕方ないのでビルドはコマンドラインで行った。

```
$ cd path/to/checkout/frameworks/support/ui/
$ ./gradlew :ui-demos:assembleDebug
```

path/to/checkout/frameworks/support/ui/ui-demos/build/outputs/apk/debug にapkが出力されるので、adb installでインストールする。

WindowsのAndroid Studioでもソースコード自体は読めるので、端末を触りながら該当コードを眺める。

![device-2019-05-08-151534.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21354/d6e3af54-5608-161d-0745-8827404484c5.png)　![device-2019-05-08-151630.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21354/80e64652-8598-3912-1f07-da657ad4966b.png)


Macがほしいですね…
#python #djago の pdb で pdb.set_trace() 的なデバッグをしたいけど 標準入出力の関係でうまく使えない場合 ( bdb.BdbQuit )

# ファイルから標準入力を与えてスクリプト実行する場合など

うまくゆかない。

```
$ python < eg.py

--Return--
> <stdin>(8)<module>()->None
(Pdb)
Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
  File "/Users/yumainaura/.pyenv/versions/3.7.3/lib/python3.7/bdb.py", line 92, in trace_dispatch
    return self.dispatch_return(frame, arg)
  File "/Users/yumainaura/.pyenv/versions/3.7.3/lib/python3.7/bdb.py", line 154, in dispatch_return
    if self.quitting: raise BdbQuit
bdb.BdbQuit
```

# python なら

コマンドオプションでファイル指定しよう。

```
$ python -m pdb eg.py
```

# django shell なら

標準入力を吸収してから tty とつなげてやれば良さそう。

```py
import pdb

lines = sys.stdin.readlines()
sys.stdin = open('/dev/tty')

pdb.set_trace()
```

# ref

[python - Use pdb.set_trace() in a script that reads stdin via a pipe - Stack Overflow](https://stackoverflow.com/questions/9178751/use-pdb-set-trace-in-a-script-that-reads-stdin-via-a-pipe)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1710








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
coveralls と parallel_tests を CircleCI で同時に使う

CircleCI で [coveralls.io] と [parallel_tests] を組み合わせたらハマったのでメモ

[coveralls.io]: http://coveralls.io
[coveralls-ruby]: https://github.com/lemurheavy/coveralls-ruby
[simplecov]:https://github.com/colszowka/simplecov
[simplecov-html]:https://github.com/colszowka/simplecov-html
[parallel_tests]:https://github.com/grosser/parallel_tests

# 問題

[parallel_tests] で実行したテストを [simplecov] でHTML出力して見ていたのだが、定期的に収集したくなって [coveralls.io] を導入した。そしたらHTMLの出力結果は正しく得られるが、 [coveralls.io] 上で表示される結果がHTMLのものより低く出て困った。

# 登場する RubyGems

- [lemurheavy/coveralls-ruby][coveralls-ruby]
    - [coveralls.io] の公式 Ruby サポート
- [colszowka/simplecov][simplecov]
    - [coveralls-ruby] が内部で依存してるカバレッジ計測ツール
- [colszowka/simplecov-html][simplecov-html]
    - [simplecov] のデフォルトの結果出力フォーマッター
- [grosser/parallel_tests][parallel_tests]
    - minitest とか Rspec を平行で実行するツール

# やったこと

## ❌ `Coveralls.wear!`

```ruby:spec_helper.rb
require 'coveralls'
Coveralls.wear!
```

これだと平行して走らせてるそれぞれのテストが終わるたびに [coveralls.io] に結果が送信され、はじめに送られたカバレッジのみが反映される。

## 🔺 `parallel=true` でリクエストする

[PARALLEL BUILDS WEBHOOK - coveralls.io](https://docs.coveralls.io/parallel-build-webhook) にかいてある方法。結果はマージされるけど、カバレッジレポートが毎回新しくなってしまい、カバレッジの増減をレポートできなかった。

コード見ると平行テストじゃなくて平行ビルドのサポートっぽく、一つのコンテナでビルドする時はparallel=trueにならないのでちょっと改造して検証した。

https://github.com/lemurheavy/coveralls-ruby/blob/4fdc3b7695fdb51bcaeba483a5321dfdaa680977/lib/coveralls/configuration.rb#L65

```ruby:lib/coveralls/configuration.rb
def self.set_service_params_for_circleci(config)
  ...
  config[:parallel]             = ENV['CIRCLE_NODE_TOTAL'].to_i > 1
  ...
end
```

この箇所をこうした

```ruby
config[:parallel]             = ENV['CIRCLE_NODE_TOTAL'].to_i > 1 unless config[:parallel]
```


## ⭕️ `SimpleCov.at_exit` で `ParallelTests`の実行状況をチェックする

結果的にこれで行けた。 [parallel_tests]のwikiに書いてあった方法。 [With simplecov -- by a grateful user - parallel_tests wiki](https://github.com/grosser/parallel_tests/wiki#with-simplecov----by-a-grateful-user)

```ruby:spec_helper.rb
require 'simplecov'
require 'coveralls'
require 'parallel_tests'

SimpleCov.start
SimpleCov.at_exit do
  # 今まで通りの出力
  SimpleCov.result.format!
  # 最後の平行テスト
  Coveralls.push! if ParallelTests.number_of_running_processes <= 1
end
```

[`SimpleCov.at_exit` を実行すると既存の動きが上書きされるので、](
https://github.com/colszowka/simplecov/blob/994dbff2780abe420f63036a7f674c296395b6c0/lib/simplecov/configuration.rb#L179-L183) `SimpleCov.result.format!` で今まで通り [simplecov] のHTMLフォーマットを出力しつつ、最後のテストが終わったときだけ [coveralls.io] に送信するようにしたら正しく結果が出るようになった。
553 error が出た(from設定変更時)

#メール設定 error
※本記事では、解決できていませんがご了承ください。m(_ _)m

---



from 設定変更後、本番環境のみ、メールが送れなくなったときの話
ログを見ると　553 Invalid email address のエラーが出た
![イラスト闇.png](https://qiita-image-store.s3.amazonaws.com/0/258033/d562c6f4-7360-c771-4330-8363cd06c31d.png)

##やりたいこと
email from を
```form: ho:hoge hoge@hoge.jp```
で表示させたい！！


##直面した問題
```yml:setting.yml
email: 'hoge@hoge.jp'
```

```ruby:mailer.rb
from: "ho:hoge <#{Settings.email}>"
```
##### :(コロン) をつけた場合の挙動
ローカル環境では正常にメールが送れる。
しかし、本番系の環境だと送信できなくなってしまった。

##### :(コロン) なしだとこのままで行ける



##解決策
```ruby:mailer.rb
from: "\"ho:hoge\" <#{Settings.email}>"
```
escape!!

これでいける！！
ローカル環境だと
```"ho:hoge"```
と""(ダブルクォーテーション)が出てしまうが
本番系の環境だと問題なく送信されて、""も消える![イラスト救世主.png](https://qiita-image-store.s3.amazonaws.com/0/258033/22526ab5-0e60-d86c-85e8-0ca1bbe8ad45.png)

##落とし穴
- キャリアメールだと一部おくられないことがあるみたい、、、
- 結局安全なのはダブルクォーテーションで囲むことみたいです。

##参考にしたもの

https://stackoverflow.com/questions/12874555/rails-3-actionmailer-mail-gem-from-address-is-being-over-ridden

http://kotaroito.hatenablog.com/entry/2016/09/23/103436



#最後に
はじめてQiitaを書いたので、至らない部分が多々あると思われるので、ご指摘のほどお願いしますm(_ _)m
特殊な事例ではありますが、少しでも参考にしていただければ幸いです。
　　　　　　　　　　　　　　![イラストやる気マン.png](https://qiita-image-store.s3.amazonaws.com/0/258033/a9fb96f8-245a-68e7-7499-425a41b1ddd5.png)
Nginx で Basic 認証

Nginx で Basic 認証をする方法です。

http://hostname/qiita に　Basic 認証をかけるとすると、

### 1. /etc/nginx/nginx.conf に追加

```text:/etc/nginx/nginx.conf
（省略）
        location /qiita {
                root   /var/www;
                index  index.html index.htm;
                auth_basic "Restricted";
                auth_basic_user_file /etc/nginx/.htpasswd;
                }
```

### 2. パスワードファイルの作成

```bash:pass_gen
#! /bin/bash
#
USER=scott
PASSWD=tiger123
printf "$USER:$(openssl passwd -apr1 $PASSWD)\n" >> .htpasswd
#
```

できたファイルを /etc/nginx に置きます。
この方法で作成したパスワードは、8文字までが有効です。

### 3. Nginx の再起動

```bash
sudo systemctl restart nginx
```

## 確認したバージョン

```text
$ nginx -v
nginx version: nginx/1.18.0 (Ubuntu)
$ openssl version
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
```
macでwebページをアプリケーションっぽく呼べるようにする

自分はmacでSpotlightをよく使う。ふと、よくアクセスするゲームとかそういったものも1つのアプリケーション/ウィンドウとしてspotlightから呼び出したいと思った。そこで過去に書いた記事:[JXAを使ってChrome&TwitterWebでツイート](https://qiita.com/yume_yu/items/a39d312ed96c52e5bef9#_reference-d1645f4b801d4de3b944)を応用してAutomatorでwebサービスをアプリケーションっぽくしてみた
#できたもの
Safariでシャニマスを開く shiny.app
![mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168044/967b28d4-f70f-b4d9-3151-484918ed762c.gif)

# JavaScriptを書く
作業としては以下

1. Safariをアクティブに
2. ツールバーやナビゲーションバーなしのウィンドウを作成
3. 必要に応じて経由したウィンドウを閉じる

できたのがこれ

``` script.js
function openAppWindow(obj){
	var scr = "window.open('"+(obj.url)+"', '"+(obj.name)+"', 'top= "+(obj.displayWidth-484)+", left="+(obj.displayHeight)+", width=820, height=484, menubar=no, toolbar=no, scrollbars=yes')";
	obj.app.doJavaScript(scr, {in:obj.app.windows[0].currentTab()});
}

var app = Application("Safari.app");
app.includeStandardAdditions = true;
app.activate();
var window;
var windowname;
var windowCloseFlag = false;
//現在開いているウィンドウがないときのみ、jsを実行するウィンドウを作成する
if(app.windows.length == 0){
	window = app.Document().make();
	windowname = window.name();//あとで破棄できるよう名前を控える
	windowCloseFlag = true;	
}

window = app.windows[0];

var obj = {app:app};
obj.url = "https://shinycolors.enza.fun/home";
obj.name = "shinycolors"
obj.displayWidth = app.doJavaScript('window.parent.screen.width', {in:window.currentTab()});
obj.displayHeight = app.doJavaScript('window.parent.screen.height', {in:window.currentTab()});

openAppWindow(obj);

if(windowCloseFlag){
	app.windows[windowname].close();//名前を控えたウィンドウを破棄する
}
```
これらを書くのにはScriptEditor.appを使うと⌘+Rですぐに試せていい感じ。ついでに⌘+Shift+Oで対応するアプリケーションの関数/変数の辞書を開くこともできる。見やすくはないけど。各ブラウザの操作と持っている変数の対応は前回同様「[JXAでSafari, Chrome, Firefoxを操作する際の違い](https://qiita.com/zakuroishikuro/items/194223d63b0f95ab7a63)」を参考にした。ブラウザごとに若干変数名やjsの実行の仕方が違うので注意。

# Automatorでアプリケーションにする
Automatorを起動して、新規作成→アプリケーションを選択。左側の「アクション」の一覧からユーティリティ→JavaScriptを実行をD&Dで右のフィールドへ。出てきたテキストボックスの中に作ったスクリプトをコピペする。
![スクリーンショット 2019-05-08 14.46.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168044/028920ef-0b52-0bba-0aa2-3c47d2cf3a60.png)
できたら右上の「実行」で正しく動くか確認して、好きな名前をつけて`/Application`以下に保存することで完成。`/Application`に置けばLaunchpad派の人もすぐ呼べるようになると思う。

### おまけ
作ったアプリケーションのアイコンを変えたい場合は以下の手順で変更できる。

1. アイコンにしたい画像をプレビュー.appで開き、メニューから編集→コピーする
2. アイコンを変えたいアプリケーションのディレクトリで対象を選択し情報を見る(⌘+i)
3. 「{ファイル名}の情報」ウィンドウのアイコン部分をクリックし、ペースト(⌘+v)する
Pythonコーディング規約 - PEP8/Flake8

## Pythonコーディング規約
##### `PEP8`
- 世界中のPythonプログラマーと共通のコーディング規約をPEP8として定めている
    - コードのレイアウト
    - インデント
    - 1行の長さ
    - import
    - 式や文中の空白文字 など
     
##### `Flake8`
- PEP8の一部やその他の項目をチェックできるPythonのソースコードチェッカー

```
$ flake8 sample.py
```
raty.jsで小数点以下まで星を表示する方法

entershareの大森です。
開発している中でratyを使うことがあり、小数点以下までmouse-onした時の値を表示したいことがあったのでその方法を書いておきます。

```html:raty.html
<html>
  <head>
  <script
    src="https://code.jquery.com/jquery-3.4.1.min.js"
    integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
    crossorigin="anonymous"
  >
  </script>
    <script type="application/javascript" src="./jquery.raty.js"></script>
    <script type="application/javascript">
      $(function(){
        $('#star_field').raty({ 
          target: '#star_input',
          targetType: 'number',
          targetKeep: true,
          precision: true,
          round : { down: .4, full: .6, up: .99 },
          half: true
        });
      });
    </script>
  </head>
  <body>
    <div id="star_field"></div>
    <div id="star_input" style="border: solid 1px; height: 1.5em; width: 2em;"></div>
  </body>
</html>

```

以上のコードの中で特に大事なのはこの部分です。

```javascript

targetType: 'number',
targetKeep: true,
precision: true,
```

このようにすることでtargetの中に表示する値が数字になり、mouse-onが解除された時もクリックされた値が保持されるようになります。
またprecisionをtrueにすることで小数点以下まで値が表示されます。
これがないと小数点以下は表示されません。

使う機会があり小数点以下まで値を取得したい時にはぜひ使ってみてください。

![raty.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249679/98e86beb-116f-120b-c6f9-cdca7ffbccce.gif)
PostgreSQLでDBの作成権限を持ったロール（ユーザ）を作成する

* いつも忘れて調べるので、自分用のメモとして投稿。
* PostgreSQLのインストールとセットアップは完了していることが前提。
* 実行環境は `macOS mojave 10.14.4` 

## ユーザ作成

```:ターミナル
# postgresでログイン
$ psql -U postgres

# ユーザの作成
postgresql=# CREATE ROLE [ユーザ名] WITH LOGIN PASSWORD '[パスワード]';
#=> CREATE ROLE
```

## データベース作成権限の付与

```:ターミナル
postgres=# ALTER ROLE [上記で作成したユーザのユーザ名] CREATEDB;
#=> ALTER ROLE
```

これで作成完了。

## コマンド一つで実行する

上記の手順では、用途に合わせて一つ一つコマンドを叩いたが、 
データベース作成権限を持ったユーザを作成するだけなら以下のコマンドで一発。

```:ターミナル
postgres=# CREATE USER [ユーザ名] WITH PASSWORD '[パスワード]' CREATEDB;
#=> CREATE ROLE
```
rbenvでrubyをインストールできなかったのでメモ

## はまったところ
Mojaveのアップデートした後にrbenvでrubyをインストールしようとしたら、うまくいかなかった

#### 環境
- macOS Mojave 10.14.4
- Xcode 10.2.1
- xcode-select version 2354
- rbenv 1.1.2

## エラー
```
$ rbenv install -v 2.6.3
ruby-build: use openssl from homebrew
/var/folders/gd/832wl82904162ggc23xtzjb80000gn/T/ruby-build.20190508142609.22790 ~
Downloading ruby-2.6.3.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.bz2
/var/folders/gd/832wl82904162ggc23xtzjb80000gn/T/ruby-build.20190508142609.22790/ruby-2.6.3 /var/folders/gd/832wl82904162ggc23xtzjb80000gn/T/ruby-build.20190508142609.22790 ~
Installing ruby-2.6.3...
ruby-build: use readline from homebrew
checking for ruby... /usr/bin/ruby
tool/config.guess already exists
tool/config.sub already exists
checking build system type... x86_64-apple-darwin18.5.0
checking host system type... x86_64-apple-darwin18.5.0
checking target system type... x86_64-apple-darwin18.5.0
./configure: line 3491: gcc-4.2: command not found
configure: error: clang version 3.0 or later is required
make: *** No targets specified and no makefile found.  Stop.

BUILD FAILED (OS X 10.14.4 using ruby-build 20190423)

```

## 対処法
XcodeとCommand Line Toolsはインストール済みでしたが、
念の為再インストール

```
$ sudo rm -rf /Library/Developer/CommandLineTools
$ xcode-select --install
```
これでも同じエラーだったので、`~./bash_profile`に以下を追加

```
echo 'export CC=/usr/bin/gcc' >> ~/.bash_profile
source ~/.bash_profile
```

#### 参考
- [rbenvでrubyをインストールできない](https://qiita.com/arks22/items/62237f378e15fded030f)
- [Command Line Toolsが古くないのに古いと言われた時の対処法](https://kkrs-blog.com/your-command-line-tools-are-too-outdated/)
プログラミング初心者が、iPhone個人アプリにReproを導入してみた感想

##0 はじめに
技術関係の仕事には就いていませんが、iPhoneアプリをリリースしてみたくて、Udemy,MENTA、プログラミングスクールなどで学習し、作成を始めて3ヶ月ほどでAppStoreにリリースすることができました。今回、アプリマーケティングツールのReproを利用してみた感想を書きたいと思います。

##1 Reproとは

<img width="500" alt="repro.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396666/91d41675-78d8-4c20-d34c-1e6e321bf6dc.png">

[Reproのホームページ](https://repro.io/jp/)にとても丁寧に説明してあるのですが、アプリの利用状況などの情報を収集、分析してくれるとても便利なツールのようです。国内シェアNo1、５９ヶ国、6000件以上の導入実績とあるので、確かな内容のものだと思いました。


##2 導入方法
とりあえず使ってみたいと思い、無料で導入できるようなので、設定してみました。まずは、アカウント登録です。

<img width="200" alt="touroku.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396666/fe9ba703-364b-fd4b-fc77-c0ddec0cf379.png">

煩わしい記入項目はなく、メールアドレス、パスワード、アプリ名のみの登録で始められます。実際のアプリへの導入方法はホームページの[導入のページ](https://docs.repro.io/ja/dev/sdk/getstarted/ios.html#ios)に詳しく説明してあります。

<img width="500" alt="導入.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396666/4a28f4d7-2a88-1d54-de88-dee9e7a9a83a.png">

もしここで、CocoaPodsを設定済みでしたら、変更する箇所は３行、５分程で終わります。拍子抜けするほど簡単です。以下の行をPofileに追加して



```ruby:
target 'YOUR-PROJECT-NAME' do
        pod "Repro"
end
```

下記のコマンドを実行します

```
$ pod install
```

次にプロジェクト内のファイルの規定の場所に,`import Repro`と`Repro.setup("YOUR_APP_TOKEN")`
を追記します。

```swift:AppDeligate.swift
import Repro

...

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    ...

    // Setup Repro
    Repro.setup("YOUR_APP_TOKEN")

    // Call the following methods to use Repro's features; they can be called in any desirable place within the app.

    ...
}
```

ここで`YOUR_APP_TOKEN`て何だろうと思ったのですが、Reproのホームページからログインして、管理画面の 設定 > アプリ設定 に記載されている Repro内で設定した値になります。
こちらもすぐにわかるので、実質、アカウント登録と３行を追記して実行することにより、データが取得できることになります。また、途中で躓いてもチャットですぐに質問できるので、驚くほど簡単に導入できました。

##3 データの取得結果
あまりに設定が簡単でデータが取れるか心配だったのですが、ほどなくして問題なくデータが取れていることが確認できました。画像はアクティブユーザー数だけですが、実際にはもっとたくさんのデータが取得できています。すぐに表示されなかったのでチャットで問い合わせた所、リアルタイムではなく６時間ごとにデータを管理画面に反映しているので、その時点では表示されていないが、データは取れているとの回答をもらいました。

<img width="500" alt="グラフ.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396666/10dbd8ad-578b-9839-50c4-621685e402ff.png">

##4 どんな利点や活用方法があるのか
活用方法については、ホームページに記載があるものに加えてチャットでも回答いただけたので、実務経験がない状況でも具体的にどのように活用していけば良いかイメージが持てました。
[イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.html#id1)という特定の条件を設定して、それに対してのデータを取得することにより、非常に有用なマーケティングができるようでした。
<img width="500" alt="event.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396666/ee0e180f-befc-8f8b-7a16-d4132162e288.png">

例えば具体例で言いますと、Amazonや、楽天で、買い物をすると、自分が見たり買ったりした商品が、"あなたにおすすめ"で表示されたり、一旦カートに入れて買わなかった商品に対してだけ20%offのクーポンが届いたり、というようなことが行われています。これがアプリでも実施できるようでした。特定の条件に一致したユーザーにのみ特定のアクションが取れることにより、マーケティング効率の向上が見込めるようです。これは、自分の通販の経験を振り返って、決定的に効果があることが理解できました。
他にも私が把握しきれていない、色々な機能があるようです。導入は無料ですし、チャットやメールで丁寧に相談に乗ってもらえるので、アプリのマーケティング効率を向上させたい方は導入を検討してみてもいいかもしれません。

##5 まとめ

・導入は、３行の追加で５分ほどで可能。そして簡単。
・実績もあり、サポート体制が充実しているので安心
・アプリの内容によっては分析やマーケティングにとても効果が見込める
Windowsでファイルの最終変更日時を変更する

# 概要
Google Photoで動画が10G以内ならOKで便利すぎる。昔の動画を載せようと、ファイルのコピーしたらファイルのタイムスタンプが変わってしまった(Google Photoでは日付はファイル最終変更日時が基準っぽい)。ということで、できるだけ **お気軽** にWindowsにてファイルの最終変更日時を変更したい。

# PowerShellの起動
エクスプローラー上で「Ctrl + L」を押して、カーソルを移動。powershellの起動はここから2通りあり

- powershellと打ってEnterを押す
- cmdと打ってEnterを押す。cmd.exeを起動して powershellと入力

# PowerShellにて最終変更日時の変更
sp(Set-ItemProperty)を使う。

```
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\suzuki> d:
PS D:\> cd .\test\
PS D:\test> sp .\20131006090535.mpg LastWriteTime $(Get-Date)
PS D:\test> $(Get-Date)

2019年5月8日 14:01:00

PS D:\test> sp .\20131006090535.mpg LastWriteTime "2013-10-06"
PS D:\test> sp .\20131006*.mpg LastWriteTime "2013-10-06"
```
ワイルドカードを使えば複数ファイルの変更も可能。linuxならtouchです

# 参考URL
https://www.atmarkit.co.jp/ait/articles/1809/13/news031.html
Windows の検証に VirtualBox を利用する

Mac で作業してる際の Windows の IE や Edge 用の検証に VirtualBox を利用します。
インストールが別途必要ですが全てのブラウザを検証できます。

- 詳細は [IE 確認用の仮想マシンの構築](https://qiita.com/aoi70/items/ba4012bfd15f327dede9)を参考
  - [VirtualBox](http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/)
  - [Windows virtual machines](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/)  
    └ VIRTUALBOX

## Tips

- パスワード： `Passw0rd!`
- ローカルホスト： http://10.0.2.2/  
  *e.g.* http://localhost:8080/ → http://10.0.2.2:8080/  
  from [VirtualBox guest OS accessing local server on host OS
](https://superuser.com/q/144453)

## 設定周り

- 日本語のキーボード配置対応  
  → [Windows10日本語版で英語配列キーボードを使用する](https://qiita.com/shimizu14/items/000cceb9e72a492b9176) を参考に。
- 自動シャットダウンはスナップショットを取って回避する（後述）  
    ~~以下を参考に切る (?)  
  → [How to fix Error 0xc004d307 to maximize allowed re-arms](https://whatvwant.com/fix-error-0xc004d307-miximize-allowed-re-arm/)  
  → [Answer at Super User](https://superuser.com/questions/479376/virtualbox-machine-auto-shutting-down-how-do-i-stop-it-from-auto-shutdown#answer-1238989)~~
- クリップボードの共有  
  [VirtualBoxでOS間のクリップボードを共有する方法 - PC設定のカルマ](https://pc-karuma.net/virtualbox-clipboard-share/)

### 自動シャットダウンについて

<blockquote>
<p>
These virtual machines expire after 90 days. We recommend setting a snapshot when you first install the virtual machine which you can roll back to later. Mac users will need to use a tool that supports zip64, like The Unarchiver, to unzip the files.
</p>

<p>
— <cite>
<a title="Before installing, please note" href="https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/">Virtual Machines - Microsoft Edge Developer</a>
</cite>
</p>
</blockquote>

**意訳：**
９０日経つと自動シャットダウンされるので、インストールしたら直ぐスナップショットを取りましょう。

- [スナップショットの作成・適用・削除 - Life.log](https://sazaijiten.work/virtualbox_snapshot/)

## Note

メモリの設定、8G の Macbook Pro で 3G 程度にしたらマトモに動いた。
PhotoScanな人体モデルへのライティング

Unityで、PhotoScanのスタジオで撮影して作られた人体モデルに対して、ライティングが必要な案件がありました。その時起きた問題と対処したことを書きます。

## 問題

フォトスキャンのスタジオで作られたモデルは、シェーダーをUnlitにしたときが一番いい感じになって実写のようにも見えるくらいなんですが、これではライトの影響を受けられません。
なので、standardシェーダーを使って、ライティングを試みたのですが、なんか不自然になっちゃって調整が難しかったです。


## 対処

そこでstandardのシェーダーを少し改造し、emissionを使って、standardとunlitの中間の値を探れるようにしてみました。 まあ陰影のコントラストを下げてるってだけですが、今回の案件ではこの調整で十分でした。

左:調整前(Albedo100%) 右:調整後(Albedo50%,Emission50%)


![A](https://i.gyazo.com/cd1d7c36ade45789cf3956619562abb8.gif)

```glsl

Shader "Custom/UnlitStandardMix" {
	Properties {
		_Color ("Color", Color) = (1,1,1,1)
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_BumpMap ("Normal", 2D) = "white" {}
        _BumpScale ("_BumpScale", Range(0,1)) = 0.0
		_Glossiness ("Smoothness", Range(0,1)) = 0.5
		_Metallic ("Metallic", Range(0,1)) = 0.0
		_Amount ("_Amount", Range(0,5)) = 0.0
		_Emission ("_Emission", Range(0,1)) = 0.5

	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Standard addshadow 
		#pragma target 3.0

		sampler2D _MainTex;
        sampler2D _BumpMap;

		struct Input {
			float2 uv_MainTex;
		};

		half _Glossiness;
		half _Metallic;
		fixed4 _Color;
		float _Amount;
        float _Emission;
        float _BumpScale;

		void surf (Input IN, inout SurfaceOutputStandard o) {

			fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

			o.Albedo = c.rgb;
			o.Metallic = _Metallic;
			o.Smoothness = _Glossiness;
			o.Alpha = c.a;

			o.Albedo = c.rgb * (1-_Emission);
			o.Emission = c.rgb * _Emission;
            
			fixed4 n = tex2D(_BumpMap, IN.uv_MainTex);	
			o.Normal = UnpackScaleNormal(n, _BumpScale);            

		}
		ENDCG
	}
	FallBack "Diffuse"
}

```

以上です！
テキストファイルを読み込む（python3）

何番煎じかよくわからないけれど、自分用メモです。
適宜更新。

#1行1要素のリストとして読み込む（改行コードあり）
```python
with open("hoge.txt",'r') as f:
    lines = f.readlines()
```
readlinesは各行を要素としたリストを作る。各要素はstr型。
各行末尾にある改行コードを気にしないのであればこれでオッケー。~~（どんなとき…？いつも消えててほしいんだけど。）~~

#1行1要素のリストとして読み込んで、各要素を区切り文字で更に分割する （190604追記）
```python
with open("hoge.txt") as f:
    lines = f.readlines()
for s in lines:
    list = s.split("任意の区切り文字")
```
とかすると、ある行を区切り文字で分けたものが要素として含まれるようなリストが得られる。
（もっとスマートな方法がありそうな気もするが…）

ここまでは文末の改行コードが含まれてしまっていたが、改行コードを消したい場合は下の通り。

#1行1要素のリストとして読み込む（改行コードなし）
```python
list = []
for i in open("hoge.txt", 'r').readlines():
    istrp = i.rstrip('\n') 
    list.append(istrp)
```
readlinesで作ったリストの各要素に対して改行コードの削除処理。
3行目でrstripを用いて、各行末尾に含まれる改行コードを削除。
この改行コード、OSやバージョンごとに違うらしいので注意。
ファイルはopenしたらcloseが原則必要だが、for文の中でopenしているときはwith open同様に自動的にクローズされる。

(190604 追記)

```python
with open("hoge.txt") as f:
    lines = f.read().splitlines()
print(lines)
```
コメントに頂いたこちらの方法だと、改行コードを気にせず、改行コードを消した状態の行を要素に持つリストが生成できる。
コメントくださった@shiracamus様ありがとうございます。

#UnicodeDecodeError: 'ascii' codec can't decode byte 0x83 in position 122: ordinal not in range(128)を回避する (20190615追記)
日本語を含むようなtxtファイルhoge.txtを読み込もうとしたところ、タイトルのようなエラーが出た。
回避するには、codecsモジュールのopenでエンコーディングとエラーに対する処理を指定してファイルを開く必要があった。

```python
with codecs.open("hoge.txt", 'r', 'ascii', 'ignore') as f:
   lines = f.readlines()
```
Windows Server 2016 (IIS 10以上)にIIS Media Services 4.1をインストールする (非サポート)

# この記事の目的

* 2021/2/16追記  
MicrosoftのダウンロードサイトからIIS Media Services 4.1が削除されました。  
サポート終了の公式アナウンスはないようですが、そもそもWindows Server 2016以降ではサポートされていないのでIIS Media Services自体が終了した技術と考えた方がよいです。

需要があるかは定かではないですが、Windows Server 2016 (IIS 10以上)にIIS Media Services 4.1をインストールする方法を記載します。
そのままインストールしようとすると以下のエラーになります。

```
IIS Version 7.0 or greater is required to install IIS Media Services 4.1.
```

IIS 10なのになぜ？
原因はIIS Media Services 4.1のインストーラーがIISのバージョンを決め打ちでチェックしているからです。
IIS 9までは対応しているのですが、IIS 10以上のバージョンだと「古いバージョン」と判断してしまいます。
※ Windows Server 2016以降はIIS Media Servicesのサポート対象ではないため、以下の回避策はサポートされない方法です。

# 前提
* Windows Server 2016
* IIS 10
* IIS Media Services 4.1

この作業はレジストリを変更します。
自己責任の上、レジストリの変更は十分に注意して行ってください。

# 準備
## IIS Media Services 4.1
~~以下からダウンロードできます。~~
~~https://www.microsoft.com/ja-jp/download/details.aspx?id=27955~~
~~※ IIS Media Service自体レガシーとなりつつあり、上記リンクはその内消滅する可能性があります。~~
上記URLは404になっていました。
公式にIIS Media Servicesをダウンロードする手段はなくなりました。

# 実施
実施する作業は以下の3点です。  

1. レジストリを変更し、IISのバージョンを古いものに偽装する。
1. IIS Media Services 4.1をインストールする。
1. レジストリを戻す。

### 1. レジストリ変更(バージョン偽装)

* 「ファイル名を指定して実行」(Windowsキー + R)、またはスタートメニューの検索で"regedit"と入力し実行して、レジストリエディターを起動します。
* ツリーから以下のキーを開きます。  
HKEY_LOCAL_MACHINE > SOFTWARE > Microsoft > InetStp
* 右画面で「MajorVersion」を選択し、右クリックして"修正"を選択します。
* 「表記」の「10進数」を選び、「値のデータ」に"9"を入力しOKを押します。
![regedit.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327819/8dc02f92-f026-4a94-a3f8-270a646e316f.png)

### 2. IIS Media Services 4.1 インストール
* ダウンロードしたIIS Media Services 4.1のインストーラー(IISMedia_amd64_ja-JP.msi)を実行し、案内に従ってインストールします。

### 3. レジストリ変更(戻し)
* レジストリエディターで、先ほど変更した「MajorVersion」の「値のデータ」を"10"に戻します。

# おまけ
IIS Media Services 4.1をPowershellでサイレントインストールする場合は以下のコマンドです。

```powershell:
$msiArgs = '/qn', '/i', "xxx\IISMedia_amd64_ja-JP.msi"
$ps = Start-Process -PassThru -Wait msiexec -ArgumentList $msiArgs
```

xxxはインストーラーを置いているパスを設定します。

# 参考
https://blogs.msdn.microsoft.com/pkirchner/2017/05/09/workaround-error-installing-iis-media-services-on-windows-server-2016/
~~Microsoftのブログなので、この手順は公式(のはず)です。~~
このブログ内でもWindows Server 2016以降はIIS Media Servicesがサポートされない旨が追記されていました。
bootstrapのレスポンシブデザインがスマホで反映されない

# 問題
bootstrapを使って作ったwebアプリがスマホ画面上でレスポンシブしてくれない:cry:
<img width="864" alt="スクリーンショット 2019-05-08 13.11.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259510/95ff2486-546f-d193-5177-a760895b04b3.png">

#　解決法

```html
<meta name="viewport" content="width=device-width, initial-scale=1.0">
```
上記の呪文を唱えるとワンパンでした。
Railsチュートリアル後に作る初めてのアプリでハマりがちだと思うので誰かの参考になれば嬉しいです。
iPhoneで撮影したHEICファイルをまとめてJPEGに変換する

# まとめて処理
すぐ忘れてしまうのですが、、、bashでフォルダ内のファイルにまとめて処理をする時は
こんな感じで書きました。

``` bash
for i in * ;do
  {処理}
done;
```

# 画像ファイルを変換
変換には`sips`を使っています。HEICからJPEGへの変換はこんな感じです

``` bash
sips --setProperty jpeg {input_file} --out {output_file}
```

# 処理をあわせて

上記の合わせて処理を組み合わせて〜。こんな感じでちょいちょいとやると、
フォルダ内のHEICファイルをまとめてJPEGに変換してくれます

``` bash
for input_file in *.HEIC; do
  output_file = `echo ${input_file} | sed -e s/HEIC/JPG/g`
  sips --setProperty jpeg ${input_file} --out ${output_file}
done;
```

# 最後に
撮影した__「HEIC」ファイルを他の端末に転送する際に「JPEG」に変換する__設定があったので、その設定をしておけば、わざわざ後から変換する手間は省けます〜。

以下の設定をしておきましょう

　1. iPhoneの設定を開く
　2. 設定の中の「写真」をタップする。
　3. 写真の中の「MacもしくはPCに転送」の項目で「自動」にチェックを入れる。
flutter webでexampleを動かすまで(flutterインストール済みを想定)

## flutterのバージョンを（1.5.4以上に）あげる
>Flutter 1.5 and above enable support for targeting the web with Flutter, including Dart compilation to JavaScript. To use the Flutter SDK with the flutter_web preview make sure you have upgraded Flutter to at least v1.5.4 by running flutter upgrade from your machine. 

とあるので下記コマンドでバージョンを上げる

```console
flutter upgrade
```

## flutter_webをcloneしてくる

>Clone this repository locally.

とのことなので下記でcloneしてくる

```console
git clone git@github.com:flutter/flutter_web.git
```

## hello_worldディレクトリへ移動(hello_worldのexampleを実行してみる場合)

```console
cd examples/hello_world/
```
別のexampleでも同じようにディレクトリ内に移動しておく

## webdevをインストール

>To install the webdev package, which provides the build tools for Flutter for web

とのことなので下記でwebdevをインストール

bash_profileの部分は適宜変更した形で下記の一連のコマンドを実行

```console
flutter packages pub global activate webdev
```

```console
echo 'export PATH="$PATH":"$HOME/.pub-cache/bin"' >> ~/.bash_profile
```

```console
exec $SHELL -l
# or
source ~/.bash_profile
```

上記方法でインストールしてwebdevが実行できない場合はwebdev実行時に[command]の部分を適宜変更して下記の形で実行

```console
flutter packages pub global run webdev [command]
```

#### (当初公式に代替コマンドが乗っていなかったため)自分が試した方法
自分の環境だと公式の方法で動かすことができなかったため下記コマンドでインストールした。（前提として[dart](https://v1-dartlang-org.firebaseapp.com/install/mac)が必要。pubが使えれば何でも良い）

```console
pub global activate webdev
```

## パッケージを更新

```console
flutter packages upgrade
```

## ローカル実行

```console
webdev serve
```

表示されたportにアクセスすればhello worldが表示される。

flutter_webをはじめて触った際に書いたものは[こちら](https://qiita.com/hiko1129/items/f842e34c323f6c1f0226)。
ただ触ったって話だけですw

~~後でfirebase hostingとかにあげるところまでやってみようかと思います。~~
[flutter webのアプリをfirebase hostingで公開してみました](https://qiita.com/hiko1129/items/b55835968820d6e37d27)



## 参考
[flutter_web](https://github.com/flutter/flutter_web#user-content-getting-started)
[Flutter Webを動かしたときにつまづいたこと](https://qiita.com/Nkzn/items/402a29fe9bb517ce78aa)

## 関連
[flutter webのアプリをfirebase hostingで公開する](https://qiita.com/hiko1129/items/b55835968820d6e37d27)を書きました。
[Flutter Web で Firestore を使う](https://qiita.com/hiko1129/items/73ea988df0c537657b10)も書きました。

## 追記
公式ドキュメントに下記の部分が追記されました。

>Note: if you have problems configuring webdev to run directly, try:
flutter packages pub global run webdev [command].
devise デフォルトルーティングのカスタマイズ

deviseでcontrollerをカスタマイズしていくときにルーティングもカスタマイズしていく事が多いと思います。
個人的に管理画面を作成していてルーティングを変更する事が多かったので備忘録として残していきます。

##sign_inとsign_outのルーティングを変更する

###変更前
```
　　new_user_session 　　　 GET    /users/sign_in(.:format)            devise/sessions#new                                           
             user_session POST   /users/sign_in(.:format)            devise/sessions#create　　　　　                                                
     destroy_user_session DELETE /users/sign_out(.:format)           devise/sessions#destroy                                                   
```
###変更後

```ruby:routes.rb
  devise_scope :user do
    get 'login', to: 'devise/sessions#new'
    post 'login', to: 'devise/sessions#create'
    delete 'signout', to: 'devise/sessions#destroy'
  end
```
こうすることで下記のルーティングになります。

```
login   GET    /login(.:format)               devise/sessions#new
        POST   /login(.:format)               devise/sessions#create
signout DELETE /signout(.:format)             devise/sessions#destroy
```

###prefixを変更前の様にnew_user_sessionの様にしたい場合はasを使い指定する必要があります。

```
  devise_scope :user do
    get 'login', to: 'devise/sessions#new', as: :new_user_session
    post 'login', to: 'devise/sessions#create', as: :user_session
    delete 'signout', to: 'devise/sessions#destroy', as: :destroy_user_session
  end
```

##Controllerをカスタマイズしている場合

```ruby:routes.rb
  devise_for :users,
    path: '',
    path_names: {
      sign_up: '',
      sign_in: 'login',
      sign_out: 'logout',
      registration: "signup",
    },
    controllers: {
      registrations: "users/registrations",
      sessions: "users/sessions"
    }

```

[![Image from Gyazo](https://i.gyazo.com/a01d83acc9b085a200f69cb8b172d9a8.png)](https://gyazo.com/a01d83acc9b085a200f69cb8b172d9a8)

##admin画面などでのルーティングを組みたい場合

```ruby:routes.rb
  devise_for :users,
    path: :admin,
    :controllers => {
      :registrations => 'organizers/registrations',
      :sessions => 'organizers/sessions',
      :passwords => 'organizers/passwords'
    }
```
pathを指定してあげるとusersを'admin'に置き換える事が出来ます。

[![Image from Gyazo](https://i.gyazo.com/ee4865f4e9156f2cec9dcc48c1fbc84e.png)](https://gyazo.com/ee4865f4e9156f2cec9dcc48c1fbc84e)


>参考になった記事
>>[sign_inとsign_outのデフォルトルーティングを変更する](https://techracho.bpsinc.jp/hachi8833/2017_05_09/39184)

ご覧いただきありがとうございました。
バネの落下

#バネの落下
https://twitter.com/irobutsu/status/1125581991645081600
↑このリンクにあるバネの落下の画像が面白かったので考えてみた。面白い点は「手を放したあとしばらくの間、バネの下端が止まって見える」ことである。ぼくはこれは「バネで繋がれた２つの質点をぶら下げて手を離した時の下側の質点の運動」で近似できると思った。バネの下端が止まって見えるのは

- バネの重心の自由落下

と

- バネの下端が弾性力で重心に引き付けられる運動

が打ち消しあって起きることだと思ったからだ。
![fig2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199087/58d5141d-7e0f-fd4b-a272-32d1261f3b87.jpeg)
図の様に２つの質量mの質点が自然長$l$でバネ定数$k$のバネにつながれ、上の質点が固定されて一様重力（下向きに重力加速度$-g$）で引かれて釣り合っているとする。このときバネの伸びは$mg=kx_0$で決まるので$x_0=\frac{mg}{k}$で与えられる。手を離した後、バネの下端は($x$座標を上の質点の初期位置原点とし、垂直上向きにとって）
$$
x = -l - \frac{1}{2} g t^2 - \frac{x_0}{2} \cos( \omega t)
$$
で落下する（単振動の振幅が半分になっているのは重心（＝２つの質点の中点）から下の質点までの距離は質点間の距離の半分なので）。$\omega = \sqrt{\frac{k}{\mu}}$ ($\mu = \frac{m}{2}$は換算質量）である。両辺を$x_0$で割り、$x_0=\frac{mg}{k}$を入れると
$$
\frac{x}{x_0} = -\frac{l}{x_0} - \frac{1}{2}\left(\frac{\mu}{m}\right) \omega^2 t^2 - \frac{1}{2}\cos (\omega t)　(1)
$$
を得る。 $ \cos \omega t \simeq 1 - \frac{1}{2} \omega^2 t^2 + \frac{1}{24} \omega^4 t^4$を入れると
$$
\frac{x}{x_0} -\simeq \frac{l+x_0}{x_0}  + \frac{1}{48} (\omega t)^4
$$
になって下端は($t^2$のオーダーでは）落下しないことが解る。
![fig1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199087/17250713-7d72-b1a9-dcf0-becf0a6ca161.jpeg)
図は縦軸を変位（$x_0=1$というスケール）で横軸を$\omega t$にした時の(1)式である（ただし、簡単のため$l=0$とした）。$wt=  \pi \simeq 3.28$（つまり半周期）の範囲ではほとんど下端は動かない。実際はバネが縮み切ったところで上端とぶつかってしまうのだろうけど、ビデオでバネが縮み切るまで下端が止まって見えるのはこのせいだと思う。


ということでこの面白いビデオは

「バネで繋がれた２つの質点をぶら下げて手を離した時の下側の質点の運動」で近似できる

んでいいんだと思う。ご意見をお待ちします！（計算間違いなどご指摘よろしく！）
旧Windows ServerをNitro 世代（m5,c5,t3 …）に変更してElastic Network Adapter (ENA) の恩恵を。

#問題
t3をはじめ、新型インスタンスは安くてうまい。リザーブドインスタンスを活用するとさらに安くなる。
しかし、Windows Server 2016以前はまずENA有効化しないとステータスチェックでアラートになり起動しない。
ENA有効化についてLinuxは情報が多かったが。WindowsのEC2はあまり使われてないのかな・・・いやーWindows Server 2012(R2)が使われてないのかも。

公式サイトを参考にしても失敗した。

Windows インスタンスにおける Elastic Network Adapter (ENA) を使用した拡張ネットワーキングの有効化
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/enhanced-networking-ena.html

ここからもらったps1を実行しても権限エラーになる。ドメイン管理上の権限不足らしきエラーが。原因を調べるうちに下記の方法で変更できたので権限エラー調査は見送りに。

#ドライバーを直入れてみた。成功！！
### 1.ENA関連ドライバー更新
https://s3.amazonaws.com/ec2-windows-drivers-downloads/ENA/Latest/AwsEnaNetworkDriver.zip
Windows Server 2012 R2は

```
...\AwsEnaNetworkDriver\bin.6.3\ena.inf
```
を右クリックでインストール

### 2.サーバを停止
停止しないとENA有効化できない
### 3.ENA設定確認

```
aws ec2 describe-instances --query "Reservations[].Instances[].EnaSupport" --instance-ids i-xxxxx
```
True：有効、Falseまたは空：無効

### 4.ENA有効にする

```
aws ec2 modify-instance-attribute --ena-support --instance-id i-xxxxx

ちなみに無効はこれ
--ena-support -> --no-ena-support
```

### 5.新しいインスタンスに変更
### 6.サーバ起動

#メモ
うちにいらっしたMSさんにWindows Serverにタブレットモードがあるなんってあり得ないと苦情を漏らしてシーンとなったことがある。
普段の古いWindows Server作業のイライラから八つ当たりをしてしまった。大変失礼いたしました。
とにかくWindwos Server 2012(R2)はもう使いたくない。
C++ Builder 10.2 Tokyo > JSON > DBXJSON.hppでなくSystem.JSON.hppをインクルードする (移行: XE4 -> 10.2Tokyo)

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
```

### 背景

XE4から10.2 Tokyoへコードを移行中。

### why are you using `#include <DBXJSON.hpp>`

- [C++ Builder 10.2 Tokyo > JSON > replace JSONvalue causes “access violation” with JsonValue->Free()](https://stackoverflow.com/questions/56017235/c-builder-10-2-tokyo-json-replace-jsonvalue-causes-access-violation-with)

のコメント (Remy Lebeau氏による上から3つ目のコメント)

> why are you using `#include <DBXJSON.hpp>` in Tokyo? You should be using `#include <System.JSON.hpp>` instead. DBXJSON hasn't been used since XE5.

- XE5より前
    - DBXJSON.hpp
- XE5以降
    - System.JSON.hpp

知りませんでした。

I appreciate it.
and
I appreciate it.
(Sky High from Tiger and Bunny).

### IDEのバージョン移行時

IDEのバージョン移行時。
古い知識に基づいた実装が残る。

それを気づけるかどうか。
それを教えてくれる人がいる環境に身を置くかどうか。

StackOverflowなどで聞くことで、そういう環境が生まれる。
プログラミング中に何してるか忘れたときってどうすれば良いの？

- Chromeのタブを見返す
- Slackのチャンネルを見返す
- コンソールのコマンド履歴を見返す

これでだいたい思い出せる。以上。

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1706








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ビルドとデプロイとリリースの違いについて

個人的にあいまいなところがあるので、
まとめてみました。

##Weblio辞書によると...

>**ビルド
【英】build
ビルドとは、コンピュータやソフトウェア関連の用語としては、ソースコードとしてコーディングされたソフトウェアを、コンパイル、リグレッションテスト、リリースノートや関連ドキュメントの生成、第三者に提出したり配布したりするための専用のファイルの生成、などを行う一連の工程のことである。**

>**デプロイ
【英】deploy
デプロイとは、主にネットワークを通じて提供されるWebアプリケーションなどのシステム開発工程において、システムを利用可能な状態にすることである。
デプロイ（deploy）という言葉は元々、配置する、展開するといった意味の英語である。デプロイはソフトウェアのリリースやインストールも含んだ意味の広い言葉であり、開発環境からステージング環境へシステムを反映させることも、ステージング環境から本番環境へ反映させることも、「デプロイする」と表現できる。**

>**リリース
【英】release
リリースとは、作品、製品、サービスなどを公開あるいは発売するといった意味で用いられる語である。**

##つまり...

**・ビルド**
ソースコードをコンパイル（機械語に翻訳）、
それらをリンク（一つにまとめる）し実行ファイルを生成する。
↓
**・デプロイ**
ビルドされた実行ファイルを実行環境に配置し利用可能な状態にする。
↓
**・リリース**
製品やサービスとして公開する。


という感じ。
時系列にすると理解しやすいです。

##参考
ビルド/デプロイ/リリース/ロールバックの 意味や違い
https://garafu.blogspot.com/2018/11/build-deploy-release-rollback.html
Bootstrap の class="container" だけ使ってレスポンシブでちょっと楽する

# まとめ

自分用メモ。
僕も昔は「とりあえず」な感じで入れてた Bootstrap だけど、Web アプリとかホームページに不用意に入れちゃうと思わぬ挙動をすることがあるので、そろそろ入れないことにする。
だけど、 `class="container"` だけはページ全体をラップする div に対してあてるとレスポンシブの幅を丁度良い感じにしてくれてたのでよく使ってた。
なのでこれだけ引っ張り出してきて適宜使おうと思った。

以下 styled-components によるそれ。必要になったら呼び出す。
React 使ってないとか styled-components 使ってないとかいう方は、これ SCSS の書き方になっているのでそこだけ良い感じにとっておくのがいいかも。

```js
import { css } from "styled-components";

export const container = css`
  width: 100%;
  padding-right: 15px;
  padding-left: 15px;
  margin-right: auto;
  margin-left: auto;

  @media (min-width: 576px) {
    max-width: 540px;
  }

  @media (min-width: 768px) {
    max-width: 720px;
  }

  @media (min-width: 992px) {
    max-width: 960px;
  }

  @media (min-width: 1200px) {
    max-width: 1140px;
  }
`;
```
toFixed() について(JavaScript)

#toFixed()とは
JavaScriptの関数。指定した少数点以下の桁数で数値を四捨五入してくれます。
[こちらの記事](https://qiita.com/koob/items/79c6d6fdf1f7cb1a5b18)で気象情報を扱うAPIを使用したのですが、その際に便利でした。

#使用するメリット
####シンプルにかける
例えば[OpenWeatherMap](https://openweathermap.org/forecast5)というAPIから気温を取得した際、「20.46」℃というように返ってきます。
でも普段見慣れている気温の表示って小数点第一位までじゃないですか。この場合は四捨五入して「20.5」℃としたい。

そこでまず初めに思いつくのはMath.round()関数。
例えば`var numTmp = 20.46`という値だった場合、

```javascript:
var numTmp = 20.46;
numTmp = Math.round(numTmp*10)/10;
```

とすることで「20.5」を取得しようと考える。
小数点を一桁残したいとはいえ、ちょっと無理やり感があります。
この時点でなんだかスマートじゃない。

さらに、APIからの戻り値ってJSONなので、つまり文字列なんですよね。
なので、実際は`var strTmp = "20.46"`という値を四捨五入しようと思ったら、

```javascript
var strTmp = "20.46";
strTmp = Math.round(parseFloat(strTmp)*10)/10;
```

となります。入れ子になっているのもあって、処理の順番が尚更ややこしく見えますよね。
私がこれを初めて見たとして、「小数点第一位までの」四捨五入をしているんだなとは、ぱっと見では思わないです。

toFixed() 関数を使用することで、以下のようにすっきり書くことができます。

```javascript
var strTmp = "20.46";
strTmp = parseFloat(strTmp).toFixed(1);
```

まず文字列を数値型にparseし、次に小数点一桁までの四捨五入を行う。
という処理の流れがシンプルに書けて、視覚的にもわかりやすくなりました。
()の中の数値は小数点以下の桁数です。「1」なら小数点一桁ですね。
仮に何も指定しなかった場合は「0」として扱われます。
つまり整数値に変換してくれるということですね。

####フォーマットが崩れない
計算した結果を文字列として渡したい、または出力したい、という場合があると思います。
Math.round()関数を使用すると、その後toString()した時にもし少数部分の最後が「0」だった場合、切り捨てられた状態で文字列型へ変換してしまいます。
例えば小数点第一位までの数字を並べて表示させているところに
19.5
20.1
20.6
20
と、一つだけ桁数がずれて表示されるのはちょっと不自然な感じがします。

対してtoFixed()関数を使用すれば、上記のような場合でも、指定した桁数まで表示されたままとなります。

```javascript:
  // toFixed()の後、toString()で文字列に戻す
  var strTmp = "20.02";
  strTmp = parseFloat(strTmp).toFixed(1);
    // strTmp = "20.0"
  
  // Math.round()のあと、toString()で文字列に戻す
  var strTmp2 = "20.02";
  strTmp2 = Math.round(parseFloat(strTmp)*10)/10;
  strTmp2 = strTmp2.toString();
    // strTmp2 = "20"
```
というのも、toFixed()関数を使用した際の戻り値が**文字列**だからなんですね。
試しに上記`strTmp`に+1すると、「20.01」となると思います。

ちなみに、数値型で返したいという場合は、toFixedしたい数値の先頭に`+`を付けるだけでいいです。

```javascript
  var strTmp = "20.02";
  strTmp = parseFloat(strTmp).toFixed(1);
  strTmp = strTmp + 1;
    // この時、文字列結合なのでstrTmp = 20.01となる

  var strTmp = "20.02";
  strTmp = +parseFloat(strTmp).toFixed(1);
  strTmp = strTmp + 1;
    // この時、数値の足し算なのでstrTmp = 21.0となる
```

　
以上、toFixed()関数についてでした。
文字列を１文字ずつのリストにする

# PerlとPythonの比較

Perlなら`split()`で一発。（Rubyも同じらしい）

```perl:Perl
use Data::Dumper;
print Dumper split(//, '日月火水木金土');
# =>
#   $VAR1 = '日';
#   $VAR2 = '月';
#   $VAR3 = '火';
#   $VAR4 = '水';
#   $VAR5 = '木';
#   $VAR6 = '金';
#   $VAR7 = '土';
```

Pythonだと、`split()`に空文字を渡してもうまくいかない。

```python:Python
print('日月火水木金土'.split())
# => ['日月火水木金土']

print('日月火水木金土'.split(None))
# => ['日月火水木金土']

print('日月火水木金土'.split(''))
# => ValueError: empty separator
```

正解はこちら。`list()`で一発。

```python:Python
print(list('日月火水木金土'))
# => ['日', '月', '火', '水', '木', '金', '土']
```

# こういうのがやりたかった

```perl:Perl
print join ',', map { qq|"$_"| } split(//, '日月火水木金土');
# => "日","月","火","水","木","金","土"
```

```python:Python
print(','.join(map(lambda x: '"{}"'.format(x), list('日月火水木金土'))))
# => "日","月","火","水","木","金","土"

print(','.join(map(lambda x: '"{}"'.format(x), '日月火水木金土')))
# => "日","月","火","水","木","金","土"

print(*map(lambda x: '"{}"'.format(x), '日月火水木金土'), sep=',')
# => "日","月","火","水","木","金","土"
```

文字列や配列の考え方が根本的に違う？
文字列を`split()`で配列にするというより、文字列自体が文字配列に近い形で扱われているという印象。
Craft CMS の出力値の翻訳に変数の値を渡す

普通の翻訳は下記の記事を参照のこと。

 - [【CraftCMS】出力値を翻訳する \- Qiita](https://qiita.com/SHIN_DEVELOP/items/7aa94ef2515cda231acb)

この翻訳に変数の値を渡したい場合は下記のようにする。

## site.php

`site.php` には下記のように定義する。

```php
return [
    'Articles in "{category}" category' => '「{category}」カテゴリの記事一覧',
];
```

## Twig

Twig テンプレートには下記のようにして変数を渡す。

```twig

{{ 'Articles in "{category}" category'|t({ 'category': category.title }) }}
```

## 参考

 - [templating \- How can I incorporate a variable into a string? \- Craft CMS Stack Exchange](https://craftcms.stackexchange.com/questions/200/how-can-i-incorporate-a-variable-into-a-string)
Python で値の重複を含むリストを値の一意なリストへ［スニペット的備忘録的に］

既存のリスト（一部の値が重複）：

```
['a','a','b','d','d','c','e','c','a']
```
これを値の一意なリストにしたい：

```
['a','b','d','c','e']
```

```python
>>> list1 = ['a','a','b','d','d','c','e','c','a']
>>> list2 = ['dummy'] # 最初にループさせるためのダミー要素．最後に削除
>>> for i in list1:
...     count = 0
...     for j in list2:
...         if j == i: # 作成中の一意リストは重複なく作られているのでここの条件 合致は 0回か 1回
...             count += 1
...     if count == 0: # count がとり得る値は 0 か 1
...         list2.append(i)
... 
>>> list2 = list2[1:] # ダミー要素の削除
>>> print(list2)
['a', 'b', 'd', 'c', 'e']

```
エアロジェルを使ったモバイルピザ窯 DE-Aero

DE-Aeroとは

- 500℃出せるピザ窯です
- 全備重量3kg
- Raspberry Pi で制御します
- 予熱5分、徐冷10分で機動性UP!


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2e369e7e-5317-66bb-a19e-0c8399479e1f.png)


この記事は以下の続きです

「IoTピザ窯、または巨大災害レジリエンスで娘に怒られたこと」
https://qiita.com/nanbuwks/items/0bb92acf7f7ee075a6b5


今までのモバイルピザ窯「DE-Live」では、工業用の断熱耐熱ブロックを組立てて作っていました。

![image](https://qiita-image-store.s3.amazonaws.com/0/139524/da861ce7-1ce3-d8c4-fb7f-31a3cca81a3e.png)

![IMG_20150412_142331.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/3a006aab-6561-417b-fc05-b82709a32ed7.jpeg)


# DE-Liveの問題点
 
- 重い
 - 既存の石窯に比べて1/10程度ではあるが、それでも20kg〜30kg程度。
 - キャリアカートで運べるが気軽という感じではない
- 耐久性
 - 断熱耐熱ブロックはもろい
 - 移動時に割れることが多い
- 粉が出る
 - 断熱耐熱ブロックはもろい
 - もろもろになってくる
 - オペレーション時にブロックの粉が床を汚す

# 分析

- 性能を決めるのは高断熱である
- 火力として投入エネルギー 1100W であっても、500℃を出せればおいしく焼ける
- 熱容量は現行 8kJ/k。これを減らしても制御プログラムの工夫でカバーできる

性能を維持しながら、質量を減らすには？

# 断熱性能

断熱のためには、

- 放射
- 伝導
- 対流

を遮断する必要があります。伝導を抑制するには密度を下げるのが効果的です。
以下を見ると、密度が低くなるごとに熱伝導率は低くなる傾向があります。


|名称|密度(kg/m3)|熱伝導率(W/mk)|耐熱温度|
|---|---|---|---|
|B1耐火断熱れんが |700 ≧|0.22@600|900|
|RA13耐火断熱れんが |≦ 550|0.19@350|1300|
|発泡スチロール（スタイロフォーム1B）|20以上|  0.040以下|80|
|グラスウール断熱材 16-45 ※1 |16| 0.045|300|
|空気|1.3|0.026|1300|
|エアロジェル| 10 - 150|0.017|500-600|
|パイロジェルXT| 180|0.064@500|650|


※1 住宅金融支援機構による断熱材の熱伝導率区分

B1耐火断熱れんがは0.22なので、仮に密度半分、熱伝導率も半分だと同じ性能のものが質量1/4で実現できることになります。

しかしながら、よく使われる発泡スチロールなどは耐熱性が無いため除外しないといけません。耐熱性が高いものとしてエアロジェルがあります。


# エアロジェル


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/fa85f63e-d021-85ec-3e06-b1e069a8ae60.png)



が、真空の次に
よく使われる1気圧空気よりそれよりもエアロジェルが熱伝導率が低くなります。

しかしながらエアロジェルは形を作るのが難しいため、耐久性を持たせるためにグラスウールに浸含させたものがよく使われます。今回は、そういったファイバーウールに浸含させたパイロジェルXTを使いました。

# 施工


パイロジェルXTは、そのままでは粉が盛大に出るし、またチクチクするのでステンレスフォイルや銅板でサンドイッチ構造にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/14d01842-5ad6-d6e0-60dd-f96cb696317e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/18de44ff-85b4-25c3-a0b8-ef11df4734ed.png)

# 完成したDE-Aeroです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f5572841-01be-e4f4-d9a5-56bf33bb5a4b.png)

# プログラム制御

DEシリーズは熱電対で温度を計測しています。500℃ぐらいでオペレーションしていますが、扉を開けると100℃ぐらい一気に下がります。

なので前代のDE-Liveでの当初では繊細な制御はあまり意味がないという仮説を立ててオペレーションしていました。

ところが一部黒焦げ一部生焼けとなってしまう問題があり、これについて

- 蓄熱体として溶岩プレートを導入
 - 熱慣性を大きくして内部に火を通す
 - ヒートスプレッダとして焼きムラを軽減
- DE-Liveを大きく組み直し、ヒーターと調理対象を離して火力を弱くする

などの対策をたてていました。

しかしながらプログラムで擬似PWMを行うことで、上記と同じ効果が得られることがわかりました。

以前の記事のプログラムコードにその昨日は含まれていますが、以下の項目

```

UpperLimitTemp1 = 540
UpperLimitTemp2 = 440
LowerLimitTemp1 = 540
LowerLimitTemp2 = 440
```

での、

```

UpperLimitTemp1 = 540
UpperLimitTemp2 = 440
```

が上ヒーターの設定温度、

```

LowerLimitTemp1 = 540
LowerLimitTemp2 = 440
```

が下ヒーターの設定温度となります。

2つの設定温度より上になったらヒーターOFF,下だったらヒーターON,
2つの設定温度の間なら擬似PWMで中間火力とすることで、熱慣性増大やヒートスプレッダ、ヒーターを離すことと同様な効果が得られます。

# 食べよう！
![IMG_20171123_152118.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c32e3ea3-f489-c979-6712-f64f7a96ff50.jpeg)
【bundle】Cleaning all the gems on your system is dangerous! If you're sure you want to remove every system gem not in this bundle, run `bundle clean --force`.

何回bundle updateしようがbundle clean --forceしようが下のエラーが鳴り止まない

Cleaning all the gems on your system is dangerous! If you're sure you want to remove every system gem not in this bundle, run bundle clean --force.

Google翻訳

```
システム上のすべての宝石を掃除するのは危険です。
このバンドルに含まれていないすべてのシステムgemを削除してもよければ、
bundle clean --forceを実行してください。
```

###解決したコマンド

```
bundle install --path vendor/bundle
```

bundleに時間がかかったが、解決できた
AngularのValidationではまったお話

AngularのFormControlで、minlengthを使用した際にハマッた箇所があったので書いてみました。

Angular公式ドキュメントだと、以下のような例で書かれていますが、実行してみると上手く動作しません。

```html
<div *ngIf="name.errors.minlength">
  4文字以上で入力してください
</div>
```

どうやら、インプットの中の値を上手く認識していない様子です。
ではエラーを見てみましょう。

```
TypeError: Cannot read property 'minlength' of null
```

調べてみると、『`errors?`』で上手く認識するようです。

```html
<div *ngIf="name.errors?.minlength">
  4文字以上で入力してください
</div>
```

errors.maxlengthでも同じ動きをするようなので、
errors?.maxlengthを使用します。