OmniAICreator/Qiita-1.07M huggingface dataset:
go-playground/validatorのomitemptyが効かなくて困った(解決)

### go-playground/validator とは
structタグに条件を書いて validate.Struct(struct)するだけで
簡単にバリデーションをしてくれる便利なバリデーターです。

https://github.com/go-playground/validator

### 使用用途
net/httpのサーバーに送られてきたリクエストstructを処理前にバリデーションしたい。
ただし、送られてきたリクエストstructの内容は全て埋まっているとは限らない。
(変更したいフィールドの情報だけが埋められた状態でリクエストされる)

### やってみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254984/545fb46b-7314-2036-6006-f812cc0c44e9.png)

GatewayUrl/NodeUrlそれぞれにURLバリデーションを付けて validate.Structさせてみた。
文字列が空であってもバリデーションは走ってしまうらしい。
こういうときはomitempty を付けるといいようだ。

https://asahima.hatenablog.jp/entry/2018/07/31/220000

### omitemptyを付けてみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254984/3d2aabf5-b661-f808-7f09-f4c4e776e880.png)

確かに付いているのに、エラー内容が変わらない... 既にこのパッケージを使っている友人に助けを求めたところ `omitemptyが優先させて処理されるとかいう仕様じゃない`ので 先頭にかかないとダメらしい。参考に見せてくれたテストコードでも確かにomitemptyは先頭に書かれていた。

https://github.com/go-playground/validator/blob/b926bf0df97108effd04f9325365cd7969935e16/validator_test.go#L73

### omitemptyを先頭に移動させてみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254984/b564a210-2ebf-bc5c-cc67-bf5275c0a75b.png)

確かにバリデーションエラーが消えて期待通りに動作してくれるようになった。

### 結論
structタグに制御条件を書くときは、書く順番にも注意しよう。
DryDryDryな一日（if 文[条件分岐]〜update)


コードレビュー中です。

```git
    if @item.valid?
      @item.update(item_params)
修正ありがとうございます！
updateメソッドにはvalid?の機能も含まれているので、省略しましょう。
if文は「update出来たかどうか」で分岐するようにしましょう。
```
とコードレビューいただきました。
内容的には「Dry」のようです。
繰り返しはさけますが、
if内って実際に行われるれるんでしたっけ？

```rb:app/controllers/users_controller.rb
  def update
    if current_user.update(user_params)
      redirect_to root_path
    else
      render :edit
    end
  end
```

確かにif文だけに書かれていて次の処理文には出てきてませんね。

（修正前）

```rb:itemscontoroller.rb
 def update
    if @item.update(item_params)
       @item.update(item_params)
      render 'show'
    else
      render 'edit'
    end
  end
```

####if分は中身が実際に実行されるので
####単にtrue/falseが出されるだけではない。

（修正後）

```rb:itemscontoroller.rb
#修正後
 def update
    if @item.update(item_params)
      render 'show'
    else
      render 'edit'
    end
  end
```
Cloud Firestore でリアルタイム アップデート

firestoreのデータが追加、更新、削除される時にリアルタイムでアプリに情報を反映させたい時に、```onSnapshot()``` メソッドを使用すると簡単に実装できます。

##ドキュメントIDを指定する時
```vue.js
db.collection("cities").doc("SF")
    .onSnapshot((doc) => {
        console.log("Current data: ", doc.data());
    });
```

##ドキュメントIDを指定せず、コレクション内の複数のドキュメントを変更させたい場合

```vue.js
db.collection("cities").where("state", "==", "CA")
    .onSnapshot((querySnapshot) => {
        var cities = [];
        querySnapshot.forEach((doc) => {
            cities.push(doc.data().name);
        });
        console.log("Current cities in CA: ", cities.join(", "));
    });
```

デベロッパーツールを見ながら、firestoreで直接データを変更すると、リアルタイムでその場で値が変わっていく様子が観察できました。
【Linux】Linuxコマンドが実行される仕組み

## linuxコマンドが実行される仕組み

```
$ echo こんにちは
こんにちは
```
このように、echoというコマンドをターミナル上で実行すると、``こんにちは``と文字列が表示される。
ここでどのような流れでこのコマンドが実行されているのかを簡単にまとめておく。

### コマンドが実行される流れ
①キーボードから入力された、echoという文字列をLinuxが受け取る。
②echoというコマンドが存在するのかを探す。
③見つかったコマンドを実行する。
④実行した結果として得られた「こんにちは」という文字列をターミナルに表示する。

このような流れでLinuxはコマンドを実行し、文字列を表示している。

## コマンドの実行はLinuxカーネルが行っている
上の説明の③で実行するところは、Linuxの核となる部分であるLinuxカーネルが行なっている。

### そもそもLinuxカーネルとは
カーネルとは、OSの核となる部分であり、CPU・メモリなどのハードウェアを管理するとともに、コマンドの実行を処理するなどのプロセス管理も行なっているところ。正直なところあんまりよくわからないが、Linuxの中にはカーネルというものが存在するらしい。しかし、LinuxだけではLinuxは成り立たないから、このカーネルが必要。LinuxカーネルだけでもLinuxは成り立たないらしい。
【Terraform】for-eachのiteratorに関して

#Terraformのfor-eachで使用する"iterator"について#

こんにちは、Deliaです。
現在Terraformを学んでおります。
for-eachの例文で iterator がなんなのかよくわからなかったので書きました。

結果からいうと、iteratorは元からある変数の様な物と理解しました。
また、ブロック内で、__"iterator = 変数名"__　とすることで一時変数として、好きな変数名を使うことができます。

```shell
$ terraform -v
Terraform v0.15.0
```

```terraform:main.tf　itaratorを用いないVer
variable "variable_name" {
    type    = list(string)
    default = ["ec2_1", "ec2_2"]
}
dynamic "sample" {
    for_each = var.[variable_name]
    content {
        ec2_name = sample.value
    }
}

```

```terraform:main.tf　itaratorを用いるVer
variable "variable_name" {
    type    = list(string)
    default = ["ec2_1", "ec2_2"]
}
dynamic "sample" {
    for_each = var.[variable_name]
    iterator = name                   # iterator = [変数名]とすることで一時的に使える
    content {
        ec2_name = name.value
    }
}
```

https://www.terraform.io/docs/language/expressions/dynamic-blocks.html

指摘や補足がありましたら、お手数ですがご教示くださいますと幸いです。

以上。
Expressからslackに通知を送る機能をJestでテストするときNetwork Errorがでる

Expressで作ったAPIサーバー内で、webhookを用いてslackに通知を送る機能を実装をした。

しかしJestでテストしてみると以下のエラーが出て通知は送られなかった。

```
A request error occurred: Network Error

      at Object.requestErrorWithOriginal (node_modules/@slack/webhook/src/errors.ts:46:5)
      at IncomingWebhook.send (node_modules/@slack/webhook/src/IncomingWebhook.ts:70:15)
```

### 解決策

package.jsonにjestの設定を追加するだけ。

```json:package.json
"jest": {
    "testEnvironment": "node"
  },
```

テスト環境をデフォルトのブラウザ的な環境からnode的な環境に変更してあげればいいらしい。

> テストに使用されるテスト環境です。Jestのデフォルト環境は、jsdomによるブラウザライクな環境です。ノードサービスを構築している場合は、代わりにnodeオプションを使ってノードライクな環境を使うことができます。
>
> [公式ドキュメント](https://jestjs.io/docs/configuration#testenvironment-string) より。
pyhon標準入力一覧表

#　はじめに
なんども標準入力の方法を検索して中々覚えることができないので、自分へのメモ書きとしてpythonの標準入力を書き留めました。
※随時加筆していく予定

# 1行に数字が一つ
```
入力例
5

n = int(input())

```

# 1行に数字が2つ以上で、別々に受け取る場合
```
入力例
4 5

A,B = map(int, input().split())

```

# 1行に空白区切りで、数字が2つ以上あり、リストとして受け取る場合
```
入力例
4 5

A = list(map(int,input().split()))
```


## 複数行の入力があり、終了文字に指定があるとき
```python
:例　終了文字が0
2
5
17
4
8
14
0

x = []
while True:
    n = int(input())
    if n == 0:
        break
    x.append(n)
```
PHP 変数を破棄する

# 目的

- 関数を用いた変数を破棄する方法をメモ的にまとめる

# 情報

- 下記のサービスを用いて動作を確認した。
    -  [https://paiza.io/ja](https://paiza.io/ja)

# 紹介

- `unset()`関数を用いることで変数を破棄する事ができる。
- 説明用に下記にソースを記載する。下記には`unset()`関数は記載されておらず、実行すると「$strは存在しています。」と出力される。

    ```php
    <?php
    
    function forget() {
        $str = 'これは削除される文字列です。';
    
        if(isset($str)) {
            echo '$strは存在しています。';
        }else{
            echo '$strは存在していません。';        
        }
    }
    
    forget();
    ```

- `unset()`関数を追記してみる。

    ```php
    <?php
    
    function forget() {
        $str = 'これは削除される文字列です。';
        unset($str);
    
        if(isset($str)) {
            echo '$strは存在しています。';
        }else{
            echo '$strは存在していません。';        
        }
    }
    
    forget();
    ```

- `unset()`関数により$strが破棄されているため、isset()関数にてfalseとなる。
- なので「$strは存在していません。」が出力される。

# あとがき

- ちなみに`unset()`は厳密に言うと関数ではなくPHPの言語構造である。
- [unset](https://www.php.net/manual/ja/function.unset.php)に下記の様に記載されている。

    ```text
    注意: これは、関数ではなく 言語構造のため、可変関数 を用いて コールすることはできません。
    ```

# 参考文献

- [https://www.php.net/manual/ja/function.unset.php](https://www.php.net/manual/ja/function.unset.php)
【論文メモ】DeepLearningを用いた動画像超解像の調査論文のまとめ

#本記事の概要
動画像における超解像の調査論文である、
Video Super Resolution Based on Deep Learning: A comprehensive survey(2020 July)
を軽ーく読んだのでそのまとめをします。
(自分があとで見返せるようなメモです...)

まとめ方は、この記事を参考にしています。
https://iis-lab.org/misc/paperreading/

#1.研究の出発点
・単一画像超解像におけ調査論文はあるが、動画像超解像に対する論文は存在しない。
・動画像における深層学習を用いた超解像手法の技術が年々増えてきている。
・同じ深層学習でも複数のアプローチがあり混同しやすい。
・各モデルのパフォーマンスが一眼でわからない。

#2.研究手法
・今までに提案された深層学習の超解像手法の概要の解説と実装。
→調査方法は、過去に提案された論文を読み、提供されているコードや実装からパフォーマンスを測定し比較。

#3.結果と知見
・各モデルにおいて動き補償のプロセスや超解像プロセスに大きな違いがあるということ。
・動画像超解像の現在位置（研究の意義や今後の課題）が明らかになった.

#4.貢献
著者は、深層学習を用いた動画像超解像分野の研究がまばらに行われており、分野としてまとまっていないという課題から、調査を行い、1つの論文としてまとめた。

#5.キーワード
・Video super resolution
・Motion Competition 
・Optical Flow
・Low Images

#6.課題
###・動画像超解像は大規模なので、現実世界への課題に対してアプローチがしにくい。
→大量のパラメータ、計算量、保存領域、学習時間など、規模が大きい。
→携帯のような日常的に用いるデバイスへの応用がきかない。
→小規模で高いパフォーマンスを出すことが必要である。

###・モデルの説明力不足
→深層学習はブラックボックス化されており、モデルの学習経路やパフォーマンスの良し悪しが不明瞭。
→畳み込み演算によって高解像度化がされるが、理論的な説明が不可能
→理論の確立や調査が必要

###・高倍率拡大
→現状では、8倍や16倍のような高倍率の拡大は難しい。
→倍率が上がるほど、予測や情報の保存が難しくなる。
→今後普及するであろう4K, 8K, 16Kなどに向けて、高倍率の超解像は重要な課題である。

###・低解像度生成プロセスの不確実さ
→現状、Bicubic法やガウシアンフィルタなどによるぼかしが低解像度生成方法である。
→現実世界に起こる現象や、実際の映像は非常に複雑な構造(シーン)で構成されており、単純な縮小やぼかしでは再現できない。
→現実世界や映像の現象を明らかにし、低解像度生成プロセスとのギャップを減らす必要がある。

###・教師あり学習によるデータの問題
→提案されている超解像手法は全て教師あり学習であり、LR/HRのセットデータが大量に必要である。
→動画像のデータセットは種類が少ない上に高価である。
→更に、現実世界の多数のシーンの全てに対応できるわけではなく、データを増やしても正確な結果を出せるとは言えない。

###・動画像のシーンによって結果が左右される。
→動画像のシーン(例；スポーツ、ドラマ)によって結果が左右される。
→実世界には多数のシーンが存在する。
→シーンごとに映像やデータセットを分割することは現実的ではない。
→どんなシーンにも対応したモデルを生成することが必要である。

###・評価手法の問題
→現状、PSNRやSSIMが使用されているが、人間に知覚とのズレがある。
(これらの評価値が高いからといって人間が綺麗と感じるかは別問題であるということ。)
→人間の知覚に沿った指標が必要。

###・フレーム間情報の活用
→計算量が莫大なので、動き補償などのフレーム間情報の推定が不正確である可能性がある。
→より高価的なフレーム間予測の手法が必要。

#7.関連研究
・動画像超解像手法の各論文など
【AWS】ユーザの種類とIAMユーザの設計について

#プログラミング勉強日記
2021年4月21日
IAMについては[こちらの記事](https://qiita.com/mzmz__02/items/0813ccd943def63a91eb)で詳しくまとめてる。

#ユーザの種類
　主に3種類ある。
　まずIAMユーザの説明を簡単にすると、IAMポリシー(ユーザへのアクセス権限を付与するための設定ドキュメント)内でAWSサービスを利用できるユーザ。基本操作はIAMユーザで行う。

##1. ルートアカウント
　ルートアカウントは、AWSアカウント作成時に作られるアカウントで、すべてのAWSサービスとリソースを使用できる権限を持つ。基本的な操作ではルートアカウントは使用しないことが強く推奨される。

##2. 管理者権限(IAMユーザ)
　管理者権限が付与されたIAMユーザのことで、フルアクセスの権限を有する。ただし、ルートアカウントでしかできない権限は持たない。

##3. パワーユーザ(IAMユーザ)
　パワーユーザはIAM以外のすべてのAWSサービスにフルアクセス権限を有するIAMユーザ。ただし、IAMの操作権限は持たない。

#IAMグループとは
　グループとして権限をまとめて設定された単位のこと。複数のIAMユーザをIAMグループとしてまとめて、グループでまとめて権限の設定を行うことができる。

#IAMユーザの設計
　AWSを利用するユーザの役割やアクセス権限を組織構造と合わせて設計することが重油尾である。

##1. IAMユーザとIAMグループのどちらを使うか
　少数利用はIAMユーザを使い、組織など複数人数での利用はIAMグループを使う。ただし、少数での利用がずっと続く場合を除いては、少数利用であっても最初からIAMグループで設定する方がいい。

##2. グループ設計
　組織別または個人単位にAWSユーザとその役割別の利用範囲を整理して、グループ設計を行う。そのため、まずAWSユーザとその役割を整理する。次に、同じ役割や利用範囲を1つのグループとしてまとめて、グループ別の名称と最小限利用範囲を確定する。
中国語・日本語・朝鮮語に対応したプログラミング用フォントSarasa Gothic（更紗ゴシック）をMacにインストールする

## Sarasa Gothicとは？

[be5invis/Sarasa-Gothic: Sarasa Gothic / 更纱黑体 / 更紗黑體 / 更紗ゴシック / 사라사 고딕](https://github.com/be5invis/Sarasa-Gothic)

プログラミング用のフォントです．会社の人がおすすめしていたので試しに入れてみました．軽く調べてみた感じ以下の特徴があるようです．

- プログラミング用フォント
- CJK（Chinese-Japanese-Korean）対応
    - 作者は中国人っぽい
- losevkaと源ノ角ゴシックがベース
    - 関連サイト：[Iosevkaというフォントが良い](https://zenn.dev/luna_chevalier/articles/4ebfb6c8a2dda62fc682)

## インストール

ソースをクローンしてNodeでビルドできますが，面倒くさいのでReleasesから最新のバージョンをダウンロードしましょう．

- sarasa-gothic-ttc-*****.7z
- sarasa-gothic-ttc-unhinted-*****.7z
- sarasa-gothic-ttf-*****.7z
- sarasa-gothic-ttf-unhinted-*****.7z

ファイルの形式がいくつかあります．フォント周りは詳しくなく違いについてわかりませんがどれでも問題はなさそう？　私はttfをダウンロードしました．

7zを解凍してttfファイルをクリックすればインストールできますが，数が多くひとつひとつクリックするのも大変なのでMacのフォントを管理する標準ソフトウェアFont Bookを使います．

![fontbook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/87b5e56b-fd3a-850d-1d79-82fb95764e7d.png)

Font Bookを起動したら，新規コレクションから「Sarasa」コレクションを作成します．コレクションで管理することで標準のフォントとカスタムでインストールしたフォントの区別がつけられます．

作成したら「フォントを追加」からSarasaのttfファイルを全て選択しましょう．少し時間はかかりますが，これでインストール完了となります．

![スクリーンショット 2021-04-21 21.08.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/b1f02b21-96f6-659c-6a62-fbf05cdfe16c.png)

フォントとしては全部で48種類もありました．どれを使うか悩みますね．比較しながら好みのものを探してみようと思います。
たまに吐き出すやつ

# .zshrc

`~/.zshrc`の中身を不定期に吐き出す。

今回はMac用。

```
# Lines configured by zsh-newuser-install
HISTFILE=~/.histfile
HISTSIZE=5000
SAVEHIST=3000
bindkey -e

zstyle :compinstall filename '/home/ユーザ名/.zshrc'

autoload -Uz compinit
compinit
# End of lines added by compinstall
setopt  ignore_eof
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'

autoload -U colors  ; colors
PROMPT="%{$fg[green]%}%m@%n[%h]%#%{$reset_color%} "
RPROMPT="%{$fg[green]%}[%(5~,%-2~/.../%2~,%~)]${WINDOW:+"[$WINDOW]"}%{$reset_color%}"

preexec () {
    if [[ "$TERM" == "screen" ]]; then
        local CMD=${1[(wr)^(*=*|sudo|-*)]}
        echo -ne "\ek$CMD\e\\"
    fi
}

alias grep="grep --color=auto" 
alias egrep="egrep --color=auto"
export LSCOLORS=Gxfxcxdxbxegedabagacad
alias ls="ls -F -G"

# 追加
setopt interactivecomments

# 以下debug用
export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"

export CFLAGS="-Wno-error=implicit-function-declaration"
```

参考：
<https://blog.y-yuki.net/entry/2020/06/21/003000>

# .vimrc

```text
set number
set cursorline
set cursorcolumn
highlight CursorColumn ctermbg=blue
set expandtab
set tabstop=4
```
VIPERモデルについて

#はじめに
この記事では、VIPERモデルについて簡単にまとめました。
⚠️当方初学のため認識違いがある可能性大です
誤りを見つけた際はコメントにて指摘していただけると幸いです🙇‍♀️🙇‍♂️


#参考
この記事は、以下の情報を参考にして執筆しました。

- [cheesecake Labs](https://cheesecakelabs.com/blog/ios-project-architecture-using-viper/)
- [VIPERアーキテクチャ まとめ](https://qiita.com/hicka04/items/09534b5daffec33b2bec
)
- [VIPERで作ろう! 実践iOSアプリ開発 〜録画したライブコーディングを添えて〜](https://www.youtube.com/watch?v=ieqNIySokxI)


#VIPERモデルとは
![UlKit independent mediator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790168/3c464f35-dc05-11be-fa52-ac19abcae273.png)
（https://qiita.com/hicka04/items/09534b5daffec33b2bec から引用）

Router : 画面遷移を担当。
Presenter : 旗振り役。
Interactor : ビジネスロジックを担当。
Entity : データそのもの。
View : 見た目とユーザ操作を担当。
UIView and/or UIViewController : 見た目とその処理等を行う。
UIKit independent mediator: 仲介役。
Manipulates data and use cases : データとその処理を担当。
Owns and sends user actions : ユーザアクションの通知。
Owns and asks for updates : 処理、更新の依頼。
Knows about : 一方的に知っている。
Notifies : 通知。
Updates : 更新。

クリーンアーキテクチャをiOSアプリ開発用に再整理したもの
View , Interactor , Presenter , Entity , Router に役割を分けていてその頭文字を取ってVIPERと呼ぶ。


#VIPERアーキテクチャの理念
###依存性の分離
- 要素同士関心のない状態
- 互いにプロトコルで繋がる（プロトコルにのみ依存している状態）
- 実態は外部から差し込む(依存性注入)

###単一責任の原則
- クラスの中身を変更する理由は複数存在しない（１言で説明）

→1ビジネスロジック = 1クラス


#View
画面の更新とPresenterへのイベント通知を担当。
1ViewControllerに対して1protocolを切る。


#Interactor
CRUD担当。
Presenter から依頼されたビジネスロジックを実施し、結果を返す。
import UIKit禁止（UIがどうなっているか気にしない）。
※循環参照にならないよう注意。


#Pressenter
Viewから受け取ったイベントを元に別のクラスに依頼する。
Viewに対して画面の更新を依頼する。
Interactorに対してデータの取得を依頼する。
Routerに対して画面遷移を依頼する。
import UIKit禁止（UIがどうなっているか気にしない）。
Presenterには状態を持たせない（ハブに徹底）。
※状態を持たせてしまうとテストコードが書きにくくなる。


#Entity
structでデータ構造を定義する。
import UIKit禁止（UIがどうなっているか気にしない）。
基本的にプロパティとイニシャライザのみ定義し、ロジックを持たないようにする。


#Router
画面遷移とDI（依存性注入）を担当。
VIPERアーキテクチャの肝であり、他の有名アーキテクチャにないところ。
（他アーキテクチャでは画面遷移の処理はViewが請け負っており、コードの見通しが悪くなりがち。）
※画面生成は Router で行い、クラス内部で init() 等をしない。
GoogleのCWV(Core Web Vitals)に対応するアレコレ

5月からCore Web Vitalsが検索順位の決定に使われる様になりますが、lighthouseやchromeのアップデートによってテスト結果が変わったりと、色々追われています。
基本的にはフィールドデータが利用されるらしいのでラボデータはそこまで気にしなくても良いのですが、フィールドデータ無かったりするんで、やれることはやっとかなきゃって感じです。

で、色々やったのでいくつかまとめます。

## ファーストビュー内の要素に``content-visibility:auto;``は設定しちゃダメ

HTMlやCSSにもよると思うんですが、これでCLSのスコアが悪化してました。

## 画像の``width``,``height``属性はアスペクト比を計算するために使う

今どき、別に```width```と```height```属性なんか入れなくてもCSSでちゃんと設定してやればちゃんと画像表示されるって言うか、画像のサイズはCSSで制御してるのがほとんどだと思うんですが、サボって入れてないと**Cumulative Layout Shift**が起きる。

画像がロードされるまえに、そのimgの領域をどれくらい確保しておくかは、CSSの```width```か```height```が```auto```に設定されていると、imgタグののwidth属性とheight属性を使ってアスペクト比を計算して使うらしい。

ref: https://web.dev/cls/

## 画像の```loading="lazy"```はつかい所によっては微妙

その要素が``Largest Content``と判断されるとlazyにすることによって少しスコアが悪くなることがある。

## slick sliderがウザい

使い方やCSSにもよるんだろうけど、めっちゃCLSのスコアが悪くなった。止めたい。
とりあえずスライダーやサムネイルの``width``属性と``height``属性をちゃんと指定して、CSSやslideのjsの発火タイミングなんかをいじくってどうにかした。

## Javascriptのライブラリを読み込むときは``defer``属性だけじゃなくて``import()``も試す

普通に``<script src="https://example.com/sample.js"></script>``と書くと、インタラクティブになるのが遅くなったりする。defer付けてもスコアが良くならないケースがあったので、``import``使ったらスコア良くなった。

あと、jQueryロードしたらすぐやって欲しい処理、他のjQuery依存のライブラリロードしないとできない処理を分けれたので良かった。

## 画像はwebpに変換した物を準備しておいて、webp対応ブラウザからのアクセスだったらwebp返す

とにかく普通のpngやjpgだと重いと怒られる。せっかくなので、サムネイルも自動生成するバッチ作って回した。
jpgやpngじゃなくてwebp返す処理は.htaccessとかWebサーバにやらせる。PHPとかアプリケーション側でやらん方が良い。

## ChromeのDeveloper ToolsのPerformanceタブのオプションを設定する

``Enable advanced paint instrumentation (slow)``や``Web Vitals``のチェックボックスOnにしとかないと見れない現象とかある。
![スクリーンショット 2021-04-21 20.58.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5743/7f7d6a62-f61e-5437-019e-e01dc047640a.png)
Big Sur 環境の rbenv install で謎いエラーが出た時にやったこと

Big Sur にアップグレード後、rbenvでrubyのバージョンをあげようとしたらハマった話です。
根本原因は特定できていませんが、これで出来たという結果だけ書いておこうと思います。同じような症状で何日も悩む人が一人でも減りますよう・・・🙏

## やったことと現象
`rbenv install -v 2.7.3` (3.0系でも同じでしたが) したら次のようなエラーがログに出力されていました。システムによって強制終了されている？っぽい。

```
-e:4:in `write': Interrupted system call @ rb_sysopen - failure.failed (Errno::EINTR)
```

## 解決した方法と原因かもしれないこと

**方法その1**
検索してみると、アンチウィルスソフトを無効化すると解消した、といったコメントがチラホラありました。私の環境では無効化が出来ないため試してはいませんが、まずはそれで解消するか確認してみると良いかもしれません。

**方法その2**
https://github.com/rbenv/ruby-build/issues/1706#issuecomment-758235089
↑このissueを社内の賢者から教えていただき、私はこれで解決しました。(圧倒的感謝)

ビルドオプションにopensslのディレクトリなどを指定していますが、おそらくそれだけでは解決しなくて(何度か試した時に解決しなかったので)、肝は `MAKE_OPTS=-j1` の部分かなと思われます。思われますが確証はありません。

```
$ MAKE_OPTS=-j1 RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl) --with-readline-dir=$(brew --prefix readline) --with-libyaml-dir=$(brew --prefix libyaml)" ruby-build --verbose 2.7.3 ~/.rbenv/versions/2.7.3/
$ rbenv rehash
```

`MAKE_OPTS=-j1` でmakeの並列数を1に限定するようです。これが必要だったように思われます。思われるだけで確証は（以下略

Big Surでアンチウィルスソフトが入っている環境では、makeのプロセス数と何か関係があるのかも？といった推測があがっていましたが、原因はまったく分かりません。分かりませんが、とにかくこれで解決しました。(それしか言えない)

ちなみに `sudo rbenv install ...` をしたらインストール自体は成功したのですが、rootによるインストールは様々な弊害をもたらし、railsの起動時にもっと困ったことになった・・・ということだけ書き残しておきます。(私と同じ轍は踏みませぬよう🙏）
一度だけ初期化してほしいときは関数スコープの static 変数を使ったり

# これは何？

一度だけ実行したい初期化処理があるときにどうするのがよいか。
C++11 以降で。

# まずい例

```text:擬似コード
if ( 初期化処理やるべき？ ){ // [A]
  初期化処理やるべき？ = false; // [B]
  初期化();
  初期化済み？ = true
}
while( ! 初期化済み？ ){ちょっと寝る();}
```

みたいに書きたくなるけど、これは複数スレッドから呼ばれると不幸になることがある。
一番乗りが [A] に到達したあと、 [B] が実行される前に他のスレッドが [A] を通り抜けてしまうかもしれない。

で。どうするか。

# 案1. atomic_exchange

[A] と [B] をまとめてアトミックに実施できればよいので

```text:擬似コード
if ( std::atomic_exchange(&初期化処理やるべき？, false) ){ // [A] + [B]
  初期化();
  初期化済み？ = true
}
while( ! 初期化済み？ ){ちょっと寝る();}
```

とすればうまくいくと思う。
変数 `初期化済み？` を `volatile` かつ atomic にすることをお忘れなく。

# 案2. call_once

とはいえ「一度だけ呼ぶ」という趣旨の関数がすでにあるのでそれを使ったほうが簡単。

```text:擬似コード
static std::once_flag once;
std::call_once(once, 初期化);
```
この記事を書くまで知らなかったんだけど、複数スレッドから立て続けに `std::call_once` 呼ぶと、一番乗りの `std::call_once` が終わるまで、二番手以降の `std::call_once` はブロックされるらしい。便利。

# 案3. static 変数

static 変数は、C++11 以降であれば複数スレッドからでもちゃんと一回だけ初期化されるので、こんな風にしてもいい。

というか、こう書けるように型を定義するのが無理ない感じなら、これが一番平易だと思う。

```text:擬似コード
struct some_type { some_type(){ 初期化処理(); } };
static some_type some_obj;
```

# まとめ

というわけで

* 一度だけ初期化したい
* 複数のスレッドが初期化コードのあたりに到達するかもしれない
* もちろん未初期化で初期化コードより先に行かれると困る

ということなら、 static 変数か、 `std::call_once` がおすすめだよ。
S3のKey命名について

S3のバケットに色々なデータを置いていくと、ちょいちょい命名に悩むことがあります。
本記事は命名規則、というほど大袈裟なものではありませんが、「こうしたら楽だった」という経験則についてのお話です。

# REST的な命名は意外と困る
RESTに慣れていると、S3もそれに合わせて以下のような命名にしたくなります。

```
dogs/{dogId}/age.json
dogs/{dogId}/name.json
dogs/{dogId}/weight.json
```

idと、その属性を保存したいようなケースですね。
この場合、特定のidに対する属性は簡単に取得することができます。
ListObjectsV2のprefixで、`dogs/{dogId}/`を指定すればすぐですね。

https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html#API_ListObjectsV2_RequestSyntax

ただ、開発を続けていると「全てのdogsのageを知りたい」ってケースも当然のように出てきて、そうなると対象のdogIdを全て知っている必要があり、ちょっと面倒なことになります。

# ではどうしようか
シンプルな話ですけども、`属性をできる限り前に記載し、一意とする識別子は後ろにする`を基本にすると便利です。

```
dogs/ages/{dogId}.json
dogs/names/{dogId}.json
dogs/weights/{dogId}.json
```

って感じですね。
この書き方であれば、「全てのdogsのageを知りたい」というケースは`dogs/ages/`のprefix指定で取得可能です。

とはいえ、当然の如く

「おいおい、それじゃ、特定のidに対する全ての属性を取得する」ってケースに対応できなくなるがな」

って話になりますが、属性は基本的にそんな大量にない＆あらかじめ知っているはず、という前提にて、「全ての属性について知る」と「全てのidについて知る」のどちらが楽か、というと、やはり前者になるかと思うわけです。

例外的なケースは当然あろうとは思いますが、何か新しいファイルを置く必要が出てきた際、毎回「こうかなぁ、、、？」って悩まずとも、この基本ルールを適用すると話がサクサク進んで良いかなと思っております。

# 一意とする識別子が複数ある時はどうすんの？
例えばこんなケースもありますよね。

```
breeders/{breederId}/dogs/{dogId}/age.json
```

これも悩ましい話ではあるのですが、`属性をできる限り前に記載し、一意とする識別子は後ろにする`に従うとこうなります。

```
dogs/ages/breeder.{breederId}/dog.{dogId}.json
```

わからなくはないです。でも、なんか、ちょっと気持ち悪い、、
でも、いつか「特定のbreederIdに所属する全てのdogのageを知りたい」って要件が出てきた時、これは結構助かります。

# じゃあさらに一意となる値が複数出てきたらどうするの？
仰ることはわかります。こういうことですよね。

```
organizations/{organizationId}/breeders/{breederId}/dogs/{dogId}/age.jsonn
```

OK、わかったわかった、こうだろう？

```
dogs/ages/organization.{organizationId}/breeder.{breederId}/dog.{dogId}.json
```

問題は解決しました。これなら「特定のorganizationに所属するdogの全てのage」も、「特定のorganizationに所属する特定のbreederが育てたdogの全てのage」も取得できます。

しかしここでまた新しい要件が。
「breederは複数のorganizationに所属していることがある。特定のbreederが育てたdogの属性を全部知りたいんだ」

え？organizationIdは全部わかるんですよね。え？取得するのにめちゃくちゃ負荷がかかるから使いたくない？ **無茶言うな**

# 無茶なのは、、、？
全く、どんどん要件変えやがって。困ったもんだ。無茶ばっかりだ、、

という気もしますが、まぁ、ぶっちゃけるとそんな複雑な検索要件が出てくるものをS3で扱おうって前提が間違っていた、という可能性も大いにあります。**DynamoDBを使え**

そうです、本記事は、安いからついS3をDynamoDBの代替にしたくなる貧乏性が産んだ経験則だったのです、、、！

という締まらない結論にて締めたいと思います。
ここまで読んでいただいて、ありがとうございました。



でも、要件が固まってるタイプのデータなら、S3をDBがわりにするのって結構楽ちんなんですよね（小声）
HTMLとCSSで画像の上に要素を配置する

#HTMLとCSSで画像の上に要素を配置する
ウェブアプリケーションの作成にあたって、背景画像に写真を使いたかったため以下の手順で実装しました。

1. 画像と文字を配置する
1. 相対位置と絶対位置について理解する
1. 画像の上に文字を配置する(絶対位置と相対位置の設定をする)
1. 画像の上に要素を配置する(絶対位置と相対位置の設定をする)


##画像と文字を配置する
まずは、画像を文字のあるhtmlのページを作成します

```html:まずは画像と文字を配置する
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <img src="sample01.jpg" >
  <p>サンプル文字</p>
</body>
</html>
```

##相対位置と絶対位置について理解する
相対位置と絶対位置についての説明をする前に、下記のような記述ができれば、相対位置や絶対位置について学習せずとも背景に画像が適用ができます。

```html:できそうでできない、、、
<img src="sample01.jpg" >
  <p>サンプル文字</p>
</img>
```

しかし、imgタグは開始タグと終了タグを分けて記述することができません。
そのため、配置する位置関係を工夫することで背景に画像を適用します。
まずは、相対位置(relative)と絶対位置(absolute)についての理解が必要です。

####相対位置(relative)・・・
　自分と同じ階層にある要素に対し、一つ前にある要素の左下を始点とし、どう配置するのかを決める方法

####絶対位置(absolute)・・・
　配置されている要素に関係なく、そのページの一番左上を始点とし、どう配置するのかを決める方法

**デフォルトでは、相対位置**での記述になっています。
そのため、上記のhtmlの構成では<img>の次に<p>があるため、位置関係として写真の左下を始点とした文字がその下に表示されているという関係になります。そこで、絶対位置を用います。<p>を絶対位置で画像の上に当たる場所に配置することで実装します。

##画像の上に文字を配置する(絶対位置と相対位置の設定をする)

<img>に対して「backgroundImage」クラスを指定
<p>に対して「onImage」クラスを指定

```html:html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>
<body>
  <img src="sample01.jpg" class="backgroundImage" >
  <p class="onImage">サンプル文字</p>
</body>
</html>
```

指定したクラスを実装する
「backgroundImage」については、上下左右を画面一杯に表示する設定
「onImage」については、絶対位置を適用し、画面左上からどこの位置に文字を表示するかの設定

```css:style.css
.backgroundImage {
  width: 100%;
  height: 100%;
}
.onImage {
  position: absolute;
  top: 0%;
  left: 0%;
}
```

##画像の上に要素を配置する(絶対位置と相対位置の設定をする)
これで、画像の上に文字を表示できるようになりました

しかし、このままでは下記のように画像の上に表示したい要素が増えた場合に、onImageを下のクラスにも適用すると、サンプル文字と追加文字に対して「top:0,left:0」が適用されてしまい、同じ場所に文字が表示されてしまうため、綺麗に表示できません。

```html:綺麗に表示できない、、、
<img src="sample01.jpg" class="backgroundImage" >
<p class="onImage">サンプル文字</p>
<p class="onImage">追加文字</p>
```

そこで、親要素と子要素の関係を利用します。
親要素には絶対位置としての情報を付与し、子要素では相対位置を利用するといったものです。
実際のコードとしては以下のようにします。

```html:親要素と子要素の関係性を利用
<img src="sample01.jpg" class="backgroundImage" >
<div class="onImage">
  <p>サンプル文字</p>
  <p>追加文字</p>
</div>
```

<p>の親要素である<div>では絶対位置が指定されているためそのタグで囲まれている<p>はともに画像の上に表示ができ、<p>同士は相対位置で表示されるため綺麗に表示ができるというわけです。
あとは要素を中央に寄せたり、余白をつけたりと通常通りのcssの記述方法に則り記載します。
controller内のdry（Don't repeat yourself)「メソッドによるコード省略」


今日はDRYです。
さて、今回学習したのはcontroller内のprivateメソッドとbefore_actionです.


メソッドによるコード省略
-

同じコードをメソッドにまとめよう
続いて、tweets_controller.rbを見てみましょう。
tweets_controller.rbの中身を見ると、@tweet = Tweet.find(params[:id])が繰り返し記述されています。

```ruby:app/controllers/tweets_controller.rb
class TweetsController < ApplicationController

  def index
    @tweets = Tweet.all
  end

  def new
    @tweet = Tweet.new
  end

  def create
    Tweet.create(tweet_params)
  end

  def destroy
    tweet = Tweet.find(params[:id])
    tweet.destroy
  end

  def edit
    @tweet = Tweet.find(params[:id])
  end

  def update
    tweet = Tweet.find(params[:id])
    tweet.update(tweet_params)
  end

  def show
    @tweet = Tweet.find(params[:id])
  end

  private

  def tweet_params
    params.require(:tweet).permit(:name, :image, :text)
  end
end
```

before_actionを利用して、メソッドとしてまとめる
-

before_actionを使用すると、コントローラで定義されたアクションが実行される前に、共通の処理を行うことができます。

|メソッド名|オプション|
|--|--|
|before_action :処理させたいメソッド名|only/except|

*resourcesと同様にonlyやexceptなどのオプションを使用することによって、どのアクションの実行前に、処理を実行させるかなど制限が可能です。

 tweets_controller.rb を編集しましょう


```app/controllers/tweets_controller.rb
 class TweetsController < ApplicationController
  before_action :set_tweet, only: [:edit, :show]

  def index
    @tweets = Tweet.all
  end

  def new
    @tweet = Tweet.new
  end

  def create
    Tweet.create(tweet_params)
  end

  def destroy
    tweet = Tweet.find(params[:id])
    tweet.destroy
  end

  def edit
  end

  def update
    tweet = Tweet.find(params[:id])
    tweet.update(tweet_params)
  end

  def show
  end

  private

  def tweet_params
    params.require(:tweet).permit(:name, :image, :text)
  end

  def set_tweet
    @tweet = Tweet.find(params[:id])
  end
end
```

今回のように、before_action :set_tweet, only: [:edit, :show]と記述することで、editアクションとshowアクションが実行される前に、set_tweetに定義されている処理が実行されるようになります。つまり、editアクションとshowアクションが実行される前に、@tweet = Tweet.find(params[:id])が実行されるということです。

before_actionを用いることで、重複した記述を1つのメソッドにまとめることができます。
[Blender]MMDモデルをアニメーション付きFBXファイルとしてエクスポートする

#BlenerでMMDを読みこんでアニメーションを付けてFBX出力をしたい！

個人的な趣味のためにアニメーション付きのMMDモデルをFBXファイルとして出力する必要があり、
せっかくなので記事にしてみました。

##今回使用したもの
- [blender2.91.0](https://www.blender.org/download/)
- [mmd_tools](https://github.com/sugiany/blender_mmd_tools)
- [Autodesk FBX Review](https://apps.autodesk.com/MAYA/ja/Detail/Index?id=6979630331069053932&appLang=en&os=Win64)
- [YYB Kagamine Rin_10th_ver1.0](https://bowlroll.net/file/155087)
- [メランコリックモーション](https://bowlroll.net/file/156160)

モデル、モーションをお借りしました。ありがとうございます。

##blenderにMMDを読み込んでアニメーションを付ける
blenderにmmd-toolsを導入は各自でお願いします。
早速BlenderにMMDモデルを読み込ませていきます。
文字で説明すると長くなってしまうのでスクショ主に進めていきます。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/7fcf08ea-ab71-d2c1-2494-3c677740a4c2.jpeg)
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/426760ed-4ecc-600e-fbae-70bcef58dea2.jpeg)
以上の設定でMMDモデルの読み込みを行います。
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/1e0dd064-86b1-6118-3728-bd740ea40735.jpeg)
これでMMDモデルの読み込みはできたと思います。
ただ、このまま踊ってもらっても髪なんかが動かないです。
それを回避するためにモデルを選択した状態で、BlenderのMMDタブの上の画像に映っているphysicsのBuildをクリックします。
この状態で再生ボタンを押して髪やスカートなんかに物理演算がされていたらOKです。
次にモーションの読み込みこませてみます。
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/a9cda6e9-4af3-3911-9cba-7e4fe4b2631e.jpeg)
モデルを読み込んだ際と同じように今度はMikuMikuDance Motionをインポートします。
インポートが終わったら再生してみましょう。
これで踊り始めてくれたらOKです。
その他タブのMMD ShadingのGLSLを押してマテリアルを適用してFBXエクスポート前にチェックしましょう。
![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/5fb30383-1dd8-28f4-8843-3bd7d882e307.jpeg)
大丈夫そうであればブレンダーのファイル->エクスポート->FBXからエクスポート設定を行いましょう。
設定は以下のように行いました。
![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/068efb21-6bf3-0f3b-1571-0e036a58ceb1.jpeg)
![7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/f486e103-f921-c8fa-db72-017ec6bc44f9.jpeg)
作成したFBXファイルをAutodesk FBX Reviewを使ってみてみましょう。
![8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272154/0b2e2c04-0928-e618-bcff-6f5c61706d40.jpeg)
正しくアニメーションされたfbxファイルが出力されました。
水色や黄緑のオブジェクトも一緒に出力されてますがこれは物理演算が行われているオブジェクトですが、
この色が使用する際にはマテリアルとして出力されると思うのでそのマテリアルを透明にすれば解決するかと思います。

##注意
今回紹介した方法は表情がエクスポートできません。
色々試してみましたが今の自分の知識ではわかりませんでした。
ご存知の方がいらっしゃればご教授お願い致します。

##終わり
ありがとうございました。
バッチファイルでグローバルIPアドレスを変数に格納

Y子です。
今日は、グローバルIPアドレスを取得し、変数に格納してみます。
やり方はいろいろあると思いますが、わたしが思う一番簡単な方法で作ってみました。

# 概要・用途
自分のグローバルIPアドレスを取得して、変数に格納します。
IPアドレスとドメイン名を関連付けたい場合など、グローバルIPアドレスを知りたい場面で使えると思います。
_【[確認環境：Windows 10 Home (Bld. 19042.928)](https://qiita.com/koiwaiwaiko/items/ef2d457ae1e1a7c8b698 "Windows10のバージョンを確認・表記する")】_

# コード
__[以前の記事](https://qiita.com/koiwaiwaiko/items/68da3132fbb8d0c18156 "バッチファイルでファイルをダウンロードする（プロキシ・失敗考慮）")__ に、`curl`を使ってネット上のファイルをダウンロードする方法を書きました。
今回は、その応用です。
アクセスした端末のグローバルIPアドレスを、シンプルにテキスト表示してくれるサイトがありますので、その結果を変数に格納します。
※プロキシ認証の対応方法は、 __[以前の記事](https://qiita.com/koiwaiwaiko/items/68da3132fbb8d0c18156 "バッチファイルでファイルをダウンロードする（プロキシ・失敗考慮）")__ を参照してください。

```bat:get_globalip1.bat
@echo off

rem コマンドの実行結果を変数に格納
for /f "usebackq" %%a in (`curl https://api.ipify.org`) do set ipaddr=%%a

echo %ipaddr%
```

```:実行結果
> get_globalip1.bat
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    11  100    11    0     0     11      0  0:00:01  0:00:01 --:--:--     8
xx.xx.xx.xx
```

結果のIPアドレスは、`xx.xx.xx.xx`と伏せています。
3行にわたって、ダウンロードの進捗状況等が表示されます。
これが不要な場合は、`curl`コマンドに`-s`オプションを与えることで、次のように消すこともできます。

```bat:get_globalip2.bat
@echo off

rem コマンドの実行結果を変数に格納
for /f "usebackq" %%a in (`curl -s https://api.ipify.org`) do set ipaddr=%%a

echo %ipaddr%
```

```:実行結果
> get_globalip2.bat
xx.xx.xx.xx
```
IPアドレスだけが表示されました。
ネットワークが遅い場合などは、結果が表示されるまで数秒の時間がかかると思いますが、それが逆に不自然に感じる場合は、`-s`オプションをなくして進捗が見えた方が安心かもしれません。
これは使い方や環境によって、選べばよいと思います。

# おわりに
グローバルIPアドレスを変数に格納！
これもしかして、ネットワーク管理に便利だったりしませんか！
どう便利か、なかなか具体例が思いつきませんが…。

まあきっと、何かあるでしょう。方法を知ってることが大事なのです。（強気）

では！
sudoersを壊した時にdockerコマンドで復旧する方法


sudoersの設定をミスるとこんな感じで死ねる。

```shell
$ sudo ls
>>> /etc/sudoers.d/aaa: syntax error near line 1 <<<
sudo: parse error in /etc/sudoers.d/aaa near line 1
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin
```

single user modeであげなおして修正すれば済むのだけど、一般ユーザでdocker --privilegedが使える特殊な方は以下でも可能。

```shell
$ docker run --privileged --rm -i -t -v /etc:/data --name aaa busybox /bin/sh
/ # mv /data/sudoers.d/aaa /data/aaa.bak
/ # exit
```
無事完了。
動作確認。

```
$ sudo ls
[sudo] password for ubuntu:
```

dockerの設定がざるな方はご参考まで。
セキュリティ的に駄目な例でもあるので、これが出来る環境を複数人で利用している場合は権限等の見直しは御一考を。
なお、一般ユーザでdockerを叩くには以下をやっておけばOK。

```shell
sudo usermod -aG docker username
Best Civic Gloc Pads

![racebrake500-366.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489447/b92867d0-8087-934e-ab1e-7ce48eb9a261.png)
Are you in need of Civic Gloc Pads? If yes, then Race Brake Shop is here to help you. We at Race Brake Shop, offer you all high quality components from brake pads to brake cooler kits at affordable prices under one roof. Civic Gloc Pads are our high-performance street compound as it produces very little dust and noise. For more information, visit us at https://racebrakeshop.com/honda/
AtCorder の rep マクロを関数にしたい

## ことの発端

最近、 paiza で求人をしているのですが、C++ の回答で ```rep``` というマクロを多用するコードを見かける。

```cpp
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
```

で、よくよく調べてみると AtCorder のサイトで公開されているコードということが分かった。
AtCorder は競プロの世界なので、コーディングの速度だったり、実行速度だったりが目的なので、これはこれでアリかと思う。

ただ、個人的には次の理由でマクロは採用できないかなぁ。

* 型チェックが行われない
* デバッガでステップ実行時に、行ズレが発生するケースがある
* 過去の経験ですっげ～痛い目にあっている（苦笑）

そうは言っても、効率化という大義のためにマクロが登場することがある（５～１０年に１回くらい）けど、局所的に、且つ背徳感に苛まれながらマクロを書いてます。

まぁ、正解・不正解がある話じゃないし、マクロの善悪の話じゃなくて、今回はこいつを型安全な関数にできんのかと書いてみたという話です。（処理速度は落ちるであろうことは予測できますが、私は型安全にしたんだ！）

んで、書いてみようと思ったきっかけは、```STL``` の ```algorithm``` における反復処理は ```iterator``` が登場することが多いので、今回の ```rep``` マクロ的なの無かったんじゃないかというのが動機です。 [^1]

[^1]: 探せば ```stl``` とか ```boost``` であるかもだけど、こいういうパーツ作るのを楽しむタイプなので、暫くは探さないことにしよう。メモリ確保しない ```range``` 的なのがありそう。

## 書いてみた

```cpp
#include <iostream>
#include <functional>

void rep(int n, std::function<void(int)> fn){
  for(int i = 0; i < n; i++) fn(i);
}

int main(void){
  rep(5, [](int i){
    std::cout << i << std::endl;
  });
}
```

そのまま書くとこんな感じかな。。。

あ！！でも

* ```break``` ができない
* 型をちゃんと渡したい

とか考えて。。。

```cpp
#include <iostream>
#include <functional>

template <typename T> bool rep(
  T start,  /* 初期値 */
  std::size_t count,  /* 回数 */
  std::function<bool(T)> fn,  /* false を返却したら break */
  std::function<T(T)> stepper = [](T value) {return value + 1;} /* デフォルトは +1 */
){
  T& value = start; /* rename */
  for(std::size_t i = 0; i < count; i++){
    if(!fn(value)) return false;
    value = stepper(value);
  }
  return true;
}

int main(void){
  rep<int>(1, 10, [](auto value){
    std::cout << value << std::endl;
    return true;
  });
  
  rep<std::string>("abc", 10, [](auto value){
    std::cout << value << std::endl;
    return true;
  }, [](auto value){return value + "z";});
}
```

型推論が効かないのが残念ポイントですが、数値だけじゃなくて文字列も渡せるようになった～
。。。けど、そんなことやるのか？　やらないな。
それに、「もう、もはや ```for``` 文で良くね？」という感じになったけど、 この関数は ```break``` した情報を伝搬する仕様にしたことで、多重ループ時の脱出が楽になった気がする。

```cpp
int main(void){
  rep<int>(1, 10, [](auto value){
    return rep<int>(value, 10, [](auto value){
      std::cout << value << std::endl;
      if(value == 14) return false; /* 14 が登場したらループ終了 */
      return true;
    });
  });
}
```

多重ループって、抜けるのが結構面倒だったりするんだけど、これならすんなり抜けられるな。
これはこれで収穫じゃ～
それに、 ```for``` 文で範囲指定じゃなくて回数指定というのも地味面倒だったりするので、作ってみたら案外アリかも。
もうちょい煮詰めれば使い物になるかも知れない。
Power Automate Desktopがなんとなく使える講座 #2 Excelデータの抽出 その１

　今回は、条件に一致するデータを別シートに貼り付けていきます。
　前回作成したフローの7ステップ目に行った、「Excelワークシートに書き込み」を消して、続けて以下のようなフローを作成していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/49642073-1d8c-74bd-ffe9-be048320c3d3.png)

# 項目名の書き込み
　まず、5ステップ目の「Excelワークシートからの読み取り」を開き、詳細設定で「範囲の最初の行に列名が含まれます」のチェックを入れます。1行目を列名として取り込むと、項目名を使ってデータ処理が行えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/f8eb89a4-21a3-9def-f02a-9b5cc784e909.png)
　次に、ワークシートの1列1行目をアクティブにしたいので、「Excelワークシート内のセルを選択」でセルを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c163d9d0-11cb-5f19-6ecc-71c5f78b1033.png)

　**For each**で項目名を入力してきます。
　左のアクションでループから「For each」を選び、パラメータを入力します。終了の値は、ExcelDataの左にある「>」記号をクリックすると、要素が表示されますので、「.Columns」を選びます。 Columnsには、列名がリスト形式で入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/07aa08ea-f763-f876-17b2-8d9c67bc05e8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/f985759a-77dc-0470-d8a4-5ecb9690f283.png)

　項目名は、**CurrentItem**に入っているので、現在のアクティブなセルに書き込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/70ef38ab-7c82-7830-ff2b-951de958a541.png)

　次に1つ右のセルをアクティブにしたいので、「Excelワークシート内のセルをアクティブ化」を選んで、相対位置で一つ右をアクティブになるように指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/646100ad-e3b3-a29b-e3cf-6ed4a07f1d81.png)

![motion2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/40b7f57a-beca-e677-1951-b209f3ab2d8e.gif)
Azure Spatial Anchors クイックスタート をやった

Azure Sptial Anchors クイックスタートをやりました。
※ 描画がうまくいきませんでした。
   対処法ご存知の方いらっしゃればご共有いただけると助かります。
# 開発環境
+ HoloLens2
+ Windows 10 pc
+ Unity 2019.4.1f1

# クイックスタート
[Azureポータル](https://portal.azure.com/)にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/9b84e41b-ffac-ad6f-a23f-5aecadb70bbe.png)
リソースの作成をクリック
Spatial Anchors で検索 > クリック 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/a9dcf1bb-089b-6bd9-c218-ea3ebb088c51.png)
作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/a53ef98d-be2f-e1d5-f507-c8a004646026.png)
各項目を埋めて作成をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/73293940-041b-3ad8-4609-e80e1ffee909.png)
作成が完了すると下の画面になるのでリソースに移動をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/77d6d6ff-c2c1-c782-dfe9-7cc6a445037c.png)
アカウントドメインとアカウントIDをコピーしてメモ
![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_1264045_74076e26-2b03-9eb0-fed9-ef2f2a16d006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/92297bb8-bf4d-896b-fb30-d9006ddfb97f.png)
アクセスキーに移動し主キーをコピーしてメモ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/ff9ac630-cfe9-1218-cfd4-f8ad451c2af0.png)
[azure-spatial-anchors-sample](https://github.com/Azure/azure-spatial-anchors-samples/releases)を開いてver2.8.1をダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/9badfd45-25b1-bb1f-bc54-6d5ee322e07f.png)

ダウンロードが完了したら解凍して Unity Hubを起動
リストに追加をクリック azure-spatial-anchors-samples-2.8.1 > Unity を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/f768e9b4-cbe8-e737-61da-6f153c08101f.png)

azure-spatial-anchors-samples-2.8.1 を起動
File > BuildSettings を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/af25083d-5647-4455-4efd-22bf4a41db5e.png)
Universal Windows Platform を選択
TargetDevice を HoloLens に変更
SwitchPlatform をクリック
完了したら BuildSettings を閉じる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/c3d336b3-c935-328c-55e3-e579b0f578a0.png)
Project > Assets > Resources > spatialAnchorConfig 
Inspector から先ほどメモした AzureSpatialAnchors アカウント情報を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/9a79b4d0-0daa-794b-749e-58be846e42fa.png)
# 動作確認

File > BuildSettings を開いて
Buildをクリック > 適切なフォルダーを選択してビルド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/0a61a032-39de-c148-4774-874ddd0d0307.png)

Configure Azure Spatial Anchors Session
Start Azure Spatial Anchors Session
Tap a surface to add the Local Anchor.
Save Local Anchor to cloud
Saving local Anchor to cloud...
Stop Azure Spatial Anchors Session
Create Azure Spatial Anchors Session for query
Start Azure Spatial Anchors Session for query
Look for Anchor
Looking for Anchor...
Delete Anchor
Stop Azure Spatial Anchors Session for query
Restart demo

上の順番にデモが進んでいきます。
herokuでデプロイした時のエラー備忘録

##git push heroku master時、以下のメッセージ文が出たら...

```
-----> Ruby app detected
remote: -----> Installing bundler 2.2.16
remote: -----> Removing BUNDLED WITH version in the Gemfile.lock
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.6.5
remote: -----> Installing dependencies using bundler 2.2.16
remote:        Running: BUNDLE_WITHOUT='development:test' BUNDLE_PATH=vendor/bundle BUNDLE_BIN=vendor/bundle/bin BUNDLE_DEPLOYMENT=1 bundle install -j4
remote:        Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform
remote:        is x86_64-linux. Add the current platform to the lockfile with `bundle lock
remote:        --add-platform x86_64-linux` and try again.
remote:        Bundler Output: Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform
remote:        is x86_64-linux. Add the current platform to the lockfile with `bundle lock
remote:        --add-platform x86_64-linux` and try again.
remote: 
remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote: 
remote:  !     Push failed
remote:  !
remote:  ! ## Warning - The same version of this code has already been built: f61987a525962d5489c36028ef399a68c6f1686f
remote:  !
remote:  ! We have detected that you have triggered a build from source code with version f61987a525962d5489c36028ef399a68c6f1686f
remote:  ! at least twice. One common cause of this behavior is attempting to deploy code from a different branch.
remote:  !
remote:  ! If you are developing on a branch and deploying via git you must run:
remote:  !
remote:  !     git push heroku <branchname>:main

```

```
重要なとことは、以下の文。
Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform
remote:is x86_64-linux. 
```

##解決したコマンド

```
以下の文を打てば、解決
% bundle lock　--add-platform x86_64-linux　　　＃このコマンドは何回か弾かれたから、コンソールをコピーして
% git add .
% git commit -m 'Add platform'
```
XMLHttpRequest：sendしたときにエラー発生

#はじめに
これは完全忘備録です。
予めご了承ください

# したかったことと発生したエラー

新規投稿ページでタグをつける際に、インクリメンタルサーチ機能を実装した。
他の編集ページでタグを更新する際も同様のJSファイルを読み込ませて、インクリメンタルリサーチ機能を実装しようとすると以下のようなエラーが発生

```terminal
ptag.js:16 GET http://localhost:3000/practices/3/ptaglist/?keyword=%E3%81%A0 404 (Not Found)
```

# 原因
こういうときは、まずは深呼吸。エラー文をしっかり読んで課題を最小単位までに分解してと、、、

404のエラーといことは、 リソースが見つからなかった場合ってことが多い、、、、
新規投稿ページのときとの差異はなんだろうか、、、
調べていくとsendされる先が違う！！！

そう！
答えは、**パスが間違っている！！！**

# 解決策

正確にいうと、今回の場合は相対パスで書いていたのでエラーが発生した。
よって絶対パスに変更してあげればOK！！

```変更前.js
 const XHR = new XMLHttpRequest();
      XHR.open("GET", `ptaglist/?keyword=${keyword}`, true);
      XHR.responseType = "json";
      XHR.send();
```

```変更後.js
 const XHR = new XMLHttpRequest();
      XHR.open("GET", `/twwets/ptaglist/?keyword=${keyword}`, true);
      XHR.responseType = "json";
      XHR.send();
```

# 終わりに
エラーは本当にありがたいものです。答えのヒントをくれますからね。
とにかくエラーがでたら、課題を最小単位に分離して考えていけば必ず答えは出ます！
頑張りましょう！！！
cakephp3 メモ

#cakephp3のメモ

MAMPのローカル環境ではDB接続に使用するファイルは**app_local.php**
記入例）

```php
    'Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => 'localhost',
            'username' => 'root',
            'password' => 'root',
            'database' => 'cake_blog',
            'encoding' => 'utf8',
            'timezone' => 'UTC',
        ],
```
[Docker環境] MySQL8:ConnectionError: Plugin caching_sha2_password could not be loaded:

#概要
* DockerでMySQL8の環境を整えていたときにエラー発生
* `rails db:create`をしようとしたら発生

```
ConnectionError: Plugin caching_sha2_password could not be loaded:
```

MySQL8での認証プラグインはデフォルトで`caching_sha2_password`が使用されているため、起こったエラーのようです。

#解決策
* 設定ファイルにて`mysql_native_password`に認証形式を変更
* コンテナとボリュームを削除して再起動

```my.cnf
[mysqld]
default_authentication_plugin= mysql_native_password
```


`caching_sha2_password `に適用させる方法もあるみたいですが、そちらについては調べきれなかったのでこちらを採用しました。
Power Automate で Adaptive Card を投稿する時に試したこと

#Adaptive Card で通知を投稿するようにしたので色々と試行錯誤しました。
今後の思い出すためのメモです。触りしか書いていない部分が多分にあります。
Teams への Bot からの投稿はAdaptive Card を使用することでかなり幅が広がると思います。
ただ、色々と初期設定が面倒ではあります。
##今後Adaptive Card メインになるようなので、早めに切り替えた方が良さそうです。
[Microsoft Teams 向けアダプティブ カードの概要](https://docs.microsoft.com/ja-jp/power-automate/overview-adaptive-cards)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/a37625a2-1d01-1268-0368-9ccd79fb12cb.png)
今回は↑↑こんな感じのCard を送るための設定です。
##Share Point に新しいファイルが保存された時（Created）にCardを送ることでUserに通知する
※Power Automate は英語設定にしておいた方がネット上の情報をそのまま使いやすいので（Action を探す時とか、検索する時の語句とか）**英語表記が個人的にはおすすめ**です。
###Trigger は以下のものを使う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/ab5928fa-0449-5821-8502-f9d516a7be55.png)
Site Address：ご自分のShare Point をpulldownから選択
Library Name：”Documents”
Folder：対象のフォルダ
###Card のPostには以下のActionを使う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/7d2b2bc6-aa09-8773-dd5a-acf11a867eae.png)
Team：投稿するチームをpulldownから選ぶ
Channel：投稿するチャネルをpulldownから選ぶ
###Adaptive Card は JSON で書く
####Aaaptive Card Designer を使うのが楽
[Designer | Adaptive Cards](https://adaptivecards.io/designer/)
↑↑このEditor を使用するとJSON のイロハが分かっていなくてもSample を見ながら↓↓こういう風に書けると思います。

```json:JSON
{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.0", 
    "body": [
 {
"type":"TextBlock",
"text": "<at>xxx@hoge.com</at> <at>yyy@hoge.com</at> <at>zzz@hoge.com</at>"
      },
        {
            "type": "TextBlock",
            "text": "New file was uploaded",
            "wrap": true
        },
       {
            "type": "TextBlock",
            "text": "File Name: **[Title](URL)**",
            "size":"large",
            "wrap": true
        }
    ]
}
```
こんな感じで書きます。

- "version" は "1.0" とするのが良いです、"1.3" だと error になってしまいます。
- Hyperlink は[Title] 部分に表示したいテキスト、(URL) 部分に飛ばしたいURLを記述します。（ここにダイナミックコンテンツでアップロードされたShare Point 内のファイルを通知しました）
- "size" や "wrap" など色々表示の仕方があります。


####Adaptive Card の Text 装飾
上の装飾は各ブロックの装飾ですが、下記の方法を使うとブロック内の個別のテキストを装飾できます。
[テキスト機能 - Microsoft Docs](https://docs.microsoft.com/ja-jp/adaptive-cards/authoring-cards/text-features)
####＠メンション
\<at>TeamsChat のアドレス\</at>
と表記することで、投稿したCard に個人をメンションすることが出来ます。（複数名の時はスペースを空けたほうが良いです）
####ダイナミックコンテンツ
Power Automate で取得したDynamic Contentsは TextBlock の随所でテキストとして使用することが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/b1a46b39-6553-9ebe-793b-38132e7b022e.png)
preタグを利用したときにインデントされたソースから先頭の空白を削除する

preタグを使うと整形済みのソースをそのまま表示できるので便利ですが先頭の空白だけ消して表示したいという場面は多々あると思います。

例えば、こういう↓ときに、``text = "あかさたな、"``という文字を表示させたい場合

```vuejs:index.vue
<pre class="text">
  {{ text }} <!-- {{ text }}の前にインデント分スペースがはいっているのでその部分まで反映されてしまう -->
</pre>
```

そのまま表示すると、コード内のインデント分の空白分も反映されてしまって、表示すると前にスペースが空いてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670446/275acd80-0976-d2d7-512e-03aba4c041d8.png)


この部分がそのまま反映されて、スペースが前にある状態で表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670446/117d7852-8d5a-62ce-4e77-f24b0ad72015.png)



そのスペースは``text``中にもともとはいっているスペースではなくて、コード上のインデント分のスペースなので、表示では省きたいです。

そういうときに使えるcssを紹介します。


## 結論

```scss
white-space: pre-line;
```

このcssをつけるだけ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670446/ad2f37d4-138d-3d37-01fb-98b130de64d1.png)

これで行の最初の空白だけつめられる感じになりました。
改行などはそのまま反映されるので、あくまで行の最初のスペースだけなくすようなcssです。


## 問題点
ただ、このままでは一点だけ問題点がありまして、それは実際にユーザーが最初にスペースを入力している場合でも行の最初のスペースは表示されないということです。
例えば、``text = " サンプル"``の場合、理想はユーザーが入力した行の最初のスペースだけは表示すべきなのかもしれません。
ただ、残念ながら今回の``white-space: pre-line;``では行の最初のスペースは無条件で削除するというものなので、それでは都合が悪い場面は別の対応が必要になります。
* そもそも厳密にそのへんもやるならpreタグ自体使うべきではないと個人的には思います。

ただ、今回は行の最初のスペースは表示しなくて良いという要件だったので``white-space: pre-line;``だけで対応しました。

## 感想
preタグを使うと色々制限もかかりますが、整形済みソースをそのまま表示できて楽ですね。
今後も必要に応じて使っていきたいと思います。


## 参考
https://developer.mozilla.org/ja/docs/Web/CSS/white-space
よく利用するコマンドライン関連メモー

環境Mac
---
### インストールしてるかどうか確認
    brew doctor
    ある時結果：
    Your system is ready to brew.

### HomeBrew インストール[リンク](https://brew.sh/index_ja)
**参考：[初心者向け：Zshの導入](https://qiita.com/iwaseasahi/items/a2b00b65ebd06785b443)**

    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

#### zshが使われているかを確認
     echo $SHELL
     使われてる時結果：
     /bin/zsh

#### zshインストール
    brew install zsh

#### ADBパス設定
    これで adb logcat アクセス可能
    echo 'export PATH="$HOME/Library/Android/sdk/platform-tools:$PATH"' >> ~/.zshrc

#### 設定を反映
    source ~/.zshrc

### SSHキー生成
    ファイルに移動
    cd ~/.ssh

    作成開始
    ssh-keygen -t rsa

    結果
    Generating public/private rsa key pair.

    ここでファイル名前変更が可能
    Enter file in which to save the key (/Users/(username)/.ssh/id_rsa):id_git_rsa
    パスワード入力あってもなくても問題なし
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:

    公開鍵表示
    cat ~/.ssh/id_rsa.pub

    鍵コピー
    pbcopy < ~/.ssh/id_rsa.pub (Mac)
    clip < ~/.ssh/id_rsa.pub (Windows)

#### GitHubとの接続
    ssh -T git@github.com
**接続成功すると.sshフォルダの中にconfigファイルがない場合自動作成されます。**

    中身
    Host github.com (デフォルトホスト変更可能)
        HostName github.com
        User ユーザー名
        Port 22
        PreferredAuthentications publickey
        IdentityFile /..../.ssh/作成された鍵のファイル名
        UseKeychain yes
        AddKeysToAgent yes

#### 複数sshキーを利用の場合
    Host test1 (ここを変更するだけ)
    接続変更
    ssh -T git@test1

**これで一応複数ssh接続可能になってます！！。**

### Mac JDKアンインストール

     バージョン確認
     $ /usr/libexec/java_home -V
     
     インストール JDK 確認
     $ cd /Library/Java/JavaVirtualMachines/
     $ ls -la

     JDK 削除
     $ sudo rm -fr /Library/Java/JavaVirtualMachines/jdk-17.0.5.jdk/
Railsでdeviseを使った利用者、管理者を別に管理する

deviseでユーザーと管理者、それぞれを管理することになったので、そちらの分け方の備忘録。

##1.gemの導入

```
gem 'devise'
```
Gemfileへ上記の記述ができれば

```
$ bundle install
```
を行う。

##2.deviseの初期設定

```
$ rails g devise:install
```
を行い、

``` /config/initializers/devise.rb
config.scoped_views = true #コメントアウトを外し、trueの部分がfalseになっていればtrueに変える
```

なかなか探しにくいと思うのでCommand+fで検索機能使ってconfig.scopedで探すと楽。

##3.deviseに関連するmodelの作成
userモデルやadminなど、deviseで管理したいモデルを全て作成します。
deviseなのでrails gのあとはmodelではなく、deviseでモデル名は複数形ではありません。

```
$ rails g devise User
$ rails g devise Admin
```
この後でもしテーブルに必要なカラムがあればdbのファイルに名前のカラムなどを追加。

##4.dbへマイグレーションする

```
$ rails db:migrate
```

##5.modelに対応するcontrollersを作成する

作成したモデルに対してそれぞれコントローラーを作成。
deviseなのでrails gのあとはdevise:controllersでコントローラー名は複数形。

```
$ rails g devise:controllers Users
$ rails g devise:controllers Admins
```

##6.modelに対応するviewを作成する

作成したモデルに対応するviewを作成。
コントローラー名と一致するように気をつける。

```
$ rails g devise:views Users
$ rails g devise:views Admins
```

##7.routingを修正

UsersとAdminsが非常に共通したルーティングとなっているため、ルーティングを修正。

修正前

``` /config/routes.rb
  devise_for :admins
  devise_for :users
```

上記の修正前をこのように修正

修正後

``` /config/routes.rb
  devise_for :admins, controllers: {
  sessions:      'admins/sessions',
  passwords:     'admins/passwords',
  registrations: 'admins/registrations'
}
devise_for :users, controllers: {
  sessions:      'users/sessions',
  passwords:     'users/passwords',
  registrations: 'users/registrations'
}
```

これでdeviseでの複数モデルを管理できる。
富士通 電子ペーパー QUADERNOを買ったら設定すること。「書き込みの編集制限」を「無効にする」

この記事の対象機種: 富士通QUADERNO FMV-DPP03/FMV-DPP04。QUADERNO（Gen.2）FMVDP51/FMVDP41。
SONYのDPT-RP1/DPT-CP1にもこの設定がある。SONYの人も要チェック。

# 「書き込みの編集制限」を「無効にする」を設定しましょう。

富士通 電子ペーパー QUADERNO FMVDP41を使ってみて、不便だったことがある。
ノートPCなど他のPDF編集アプリでPDFに書き込んだデジタル手書き(鉛筆脚注)が、本機で編集できない(消しゴム機能で消す/削除することができない)。
使えねえ、と思ったら、設定の問題だった。

- 設定→本体設定→書き込みの編集制限→無効にする

と設定すると良い。
他のPDF編集アプリでPDFに書き込んだデジタル手書きも編集できるようになる。
消しゴム機能で消せるようになる。
初期設定では編集できないようになっているので、本機を購入した人は、上記の設定をしておくように。
個人的には、初期設定として、これは意地悪だと思う。

この設定については、ネットを検索してもほとんど出てこないので、気がつくのにだいぶかかってしまった。
他のPDF編集アプリによる手書きPDFの資産がたくさんある人は、これで救われる。
該当する人は、心置きなくQUADERNOを購入して使うがよい。