OmniAICreator/Qiita-1.07M huggingface dataset:
画面右上にナビゲーションを実装する


# 目的
次の2つの要件を満たす、Webサイトのナビゲーションを実装します。

- スクロールしても画面に表示され続ける
- 右上に配置される

今回は`a`タグを利用した各ページへのリンクの実装などは行わず、テキストの配置方法に関わるCSSのみに限定して、記事を書きます。

# ナビゲーションとは

> サイトナビゲーションとは、Webサイト上で目的のページを探す手がかりとなる、リンク付きの表示のことです。
[意外と知らない？Webサイトの「ナビゲーション」の種類と役割をご説明します](https://mtame.jp/design/web_navigation/#:~:text=%E3%82%B5%E3%82%A4%E3%83%88%E3%83%8A%E3%83%93%E3%82%B2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%AF%E3%80%81Web,%E3%81%AE%E8%A1%A8%E7%A4%BA%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82)

Webサイト上部などに設置されている、各ページや、同ページ内の見出しへ飛ぶことのできるリンクのようなものでしょうか。
[トヨタ自動車WEBサイト](https://toyota.jp/index.html)より次のスクリーンショットを撮影しました。
ここでいうところのラインアップ、購入サポート、etc... といったものが、ナビゲーションです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549712/e9867221-54eb-6a92-7b1a-15a38defd543.png)


# 実行環境（再現環境）
- [CodePen](https://codepen.io/)
- GoogleChrome バージョン: 88.0.4324.150



# テキストを画面に固定する

`position`は、ボックス要素を固定するプロパティです。
その中で`fixed`という値を指定することで、指定したテキストを画面内に固定します。
この記述により、スクロールを行っても画面内に指定されたテキストが表示され続けます。

```index.html
    <header>私たちについて　お品書き　参加方法</header>
```

```main.css
header{
  position: fixed;
}
```

# テキスト（テキストを要素に持つボックス）を画面右に配置する

ここまでの作業で、スクロールを行っても画面内にテキストが表示され続けるようになりました。
しかし、現状ではテキストは次の画像のように、画面左上に表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549712/08c9888a-8372-ddd6-c9bb-483cd89f44b7.png)


本記事においては、**画面右上にテキストボックスが表示されること**も、目的に含まれています。
この状態から、テキストを画面右上に表示されるようにソースコードを書き換えます。

ここでブラウザ上で`F12`キーを使って、デベロッパーツールを開いてみます。
次の画像から、`私たちについて　お品書き　参加方法`というテキストが、ひとつのボックスとして定義されていることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549712/5606c9ef-2b24-881b-0960-283e46935fdc.png)





## 失敗例

例えばここで、`text-align: center`をこのボックスに付与したとしても、テキスト位置がボックス内で右揃えになるだけなので、目的は達成されません。
画面の右側にテキストが配置されるわけではありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549712/b741db2e-7a22-7a2f-9283-7ea60f5819cf.png)



## 成功例　画面右にテキスト（ボックス）を配置する

cssに`right : 30px;`を追加し、次のようなCSSファイルに書き換えます。
`right`は、ボックスの配置位置を設定するプロパティです。

この書き換えられた記述は、画面右から`30px`の位置にボックスを配置することを示します。
画面右端ではなく、少し余白を作りたい場合は`30px`など指定すればよいです。
余白なしでよいなら、`right: 0;`で構いません。

このソースコードにより、次に示す画像のように、右上配置にすることができました。

```index.html
    <header>私たちについて　お品書き　参加方法</header>
```


```css
header{
  position: fixed;
  right: 30px;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549712/ab18e41b-bb48-0057-5184-c24fb30eeaf1.png)

### 補足
`right`以外にも、`top`, `left`, `bottom`で位置を指定することが可能です。
ただし、`left`と`right`、`top`と`bottom`は競合します。

もう少し具体的に説明すると、`left`と`right`プロパティ、`top`と`bottom`プロパティが混在している場合、それぞれ`left`, `top`の値が優先され、`right`, `bottom`の値は適用されないようです。


# 参考
- [CodePen](https://codepen.io/)
- [意外と知らない？Webサイトの「ナビゲーション」の種類と役割をご説明します](https://mtame.jp/design/web_navigation/#:~:text=%E3%82%B5%E3%82%A4%E3%83%88%E3%83%8A%E3%83%93%E3%82%B2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%AF%E3%80%81Web,%E3%81%AE%E8%A1%A8%E7%A4%BA%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82)
- [トヨタ自動車WEBサイト](https://toyota.jp/index.html)
JavaScriptの連想配列の配列で特定のvalueが配列の何番目（index）で出現するかを知る

例えば、'school'が何番目のオブジェクトの中にあるのか知りたい場合。

```javascript
const genres = [
    {route: 'jobs', name: '仕事'},
    {route: 'life', name: '日常'},
    {route: 'relationship', name: '人間関係'},
    {route: 'dozi', name: 'どじ'},
    {route: 'shame', name: '恥かいた'},
    {route: 'school', name: '学校'},
    {route: 'love', name: '恋愛'},
    {route: 'marriage', name: '結婚生活'},
    {route: 'game', name: 'ゲーム'},
    {route: 'disease', name: '病気'},
    {route: 'heart', name: '心'},
];

//まずrouteのvalueだけで配列を作成する。
const genreRoutes = genres.map((obj) => {
  return obj.route;
});
// 結果 genreRoutes = ['jobs', 'life', 'relationship', ....]

let index = genreRoutes.indexOf('school');
// 結果 5
```
なんか日本語が難しいですね。
タイトルがわけわかめ。。
ほぼ自分用なのですみません。

ちなみになぜ'route'なのかというと、Vue Routerでルートパラメータとして使用するからです。
もしこれ以外に方法があれば教えてくださいm(__)m
Railsでの検索で、大文字小文字の区別をしないようにする方法

すでに有名な方法だけどひっかかる点があったので備忘録的に。

たとえばデータベースで`Apple`という文字列があったとして、検索フォームに`apple`といれてもヒットしないのはいかにも不便だろう。方法はいろいろあるが、一番手っ取り早いのは`arel_table`を使う方法になるし、これは結構たくさん見つかる。

通常は

```ruby
if request.post? then

	f = '%' + params[:find] + '%'
	@user = User.where"name like ?",f

end
```

という感じで、whereのあとにSQL文を書いて検索とする方法が一般的。

しかしこれだと上記のように大文字小文字の区別がつかなくて面倒臭いので

```ruby
if request.post? then

	f = '%' + params[:find] + '%'
	user_table = User.arel_table
	@user = User.where(user_table[:name].matches(f))

end
```

これでいいんだけど、問題は複数のカラムから検索したいときはどうしようか？ってことがある。これが検索しても案外見つからなかったのでかいておくと

```ruby
if request.post? then

	f = '%' + params[:find] + '%'
	user_table = User.arel_table
	@user = User.where((user_table[:name].matches(f)).or(user_table[:address].matches(f)))

end
```

という風に、`.or()`で繋いでやると、複数のカラムからの検索が可能になる。そんだけー。
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

自分のメモとして記します

```
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```

以上のエラーが起きた場合

初めに

```
heroku addons:destroy アプリ名
```

その次に

```
heroku addons:add cleardb
heroku config
heroku config | grep CLEARDB_DATABASE_URL
```

の順にコマンドをうち、mysqlの情報を取得し以下のコマンドをうつ

```
heroku config:set DATABASE_URL=mysql2://[あなたのURL]
```
poetry add psycopg2がEnvCommandErrorでコケた時にすること

Flask + postgresqlで趣味グラムしていた時にこれで３時間ハマったので、その解決法です。

## 環境
M1 Mac
Mac OS 11.2.1 Big Sur
Python: 3.9.1
poetry: 1.1.4


## 事象
やったこと

```
poetry add psycopg2
```

エラー

```
Using version ^2.8.6 for psycopg2

Updating dependencies
Resolving dependencies... (0.1s)

Package operations: 1 install, 0 updates, 0 removals

  • Installing psycopg2 (2.8.6): Failed

  EnvCommandError

# 以下略

```


**なるほどわからん**
エラー内容をよく読んでみると

```
      ld: library not found for -lssl
      clang: error: linker command failed with exit code 1 (use -v to see invocation)
      error: command '/usr/bin/clang' failed with exit code 1
```

とある。
どうやらsslが見えなくてビルドに失敗しているようだ。


## 対処
1. コマンドラインツールを入れる。
2. homebrewでopensslをインストールする。
3. openssl配下のlibとincludeを環境変数に指定してpoetry addを実行する。

### コマンドラインツールを入れる。
※すでに入れている場合はスキップ可

```
$ xcode-select --install
```

### homebrewでopensslをインストールする。

```
# インストール
$ brew install openssl

# 確認
$ brew info openssl

# この２つの変数が大事！次で使うよ
For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/opt/homebrew/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/opt/homebrew/opt/openssl@1.1/include"

```

### openssl配下のlibとincludeを環境変数に指定してpoetry addを実行する。

```
$ env LDFLAGS="-I/opt/homebrew/opt/openssl@1.1/include -L/opt/homebrew/opt/openssl@1.1/lib" poetry add psycopg2
Using version ^2.8.6 for psycopg2

Updating dependencies
Resolving dependencies... (0.1s)

Package operations: 1 install, 0 updates, 0 removals

  • Installing psycopg2 (2.8.6)

```
入りました！

## 参考
[error installing psycopg2, library not found for -lssl](https://stackoverflow.com/questions/26288042/error-installing-psycopg2-library-not-found-for-lssl/39244687#39244687)

[ld: library not found for -lssl](https://codelovingyogi.medium.com/ld-library-not-found-for-lssl-530911bdbb43)
【PHP】Laravel6で遊ぶ（セットアップ）

#この記事について
久しぶりにエンジニアとしてお仕事をし始めたので、ちょくちょく記事を投稿していきたいと思っています。
ここ1ヶ月ほどLaravelで遊んでいるので、備忘録として記事に残します。
今回はLaravelのセットアップまで。


#環境
OS：Windows10 Home

#Laravelのセットアップ
##PHP環境のセットアップ
ローカル環境でさくっとPHP環境をセットアップするには「XAMPP」が楽ですよね。
[ここ](https://www.apachefriends.org/jp/index.html)からダウンロードします。
Windows版も8.0.2が最新版ですが、本記事では7.4.15をインストールすることにします。
インストール自体は特に悩むことはないので、割愛します。

インストールを完了しても、このままだとコマンドプロンプトでPHPが使えないので、
環境変数にXAMPPでインストールしたフォルダ群に含まれるPHPフォルダのPathを追加します。

僕の場合、CドライブのWorks→Dev→XAMPPというフォルダにインストールしたので、
「C:\Works\Dev\XAMPP\php」を追加することになります。

追加後、コマンドプロンプトで```PHP -v```を打って、バージョンが表示されればOKです。

##Composerのセットアップ
LaravelはComposerからインストールをします。
LaravelはPHPのライブラリやパッケージを管理するためのツールで依存管理ツールと呼ばれています。

WindowsなのでComposerのインストールは[ここ](https://getcomposer.org/doc/00-intro.md#installation-windows)の「Composer-Setup.exe」をクリックしてインストーラーをダウンロードします。

Composerのインストールも特に悩むことはないです。
複数のPHPのバージョンをインストールしている場合はPHPのパスだけ間違えないように。

コマンドプロンプトで```composer -v```を打って、アスキーアートみたいな「Composer」の文字とバージョンが表示されればOKです。

##Larravelのセットアップ
LaravelをComposerを使ってインストールします。

```
composer create-project laravel/laravel （プロジェクト名）
```

上記コマンドだとインストールしているPHPに依存するLaravelの最新版がインストールされます。
現在バージョンは8まで出てはいますが、LTSはバージョン6なので、個人的にはバージョン6がおすすめです。
バージョンを指定してLaravelをインストールしましょう。
※プロジェクト名はdemoにします。

```
composer create-project "laravel/laravel=6.*" demo
```

ちなみにLaravelのファイル群はコマンドプロンプトのカレントディレクトリにインストールされるので、必要に応じでカレントディレクトリを変更しておきましょう。

XAMPPのインストールでapacheもインストールされていて、httdocsがドキュメントルートになるので、httdocsフォルダ内にLaravelをインストールするのがいいのではないでしょうか。

##Laravel起動
Laravelの関係ファイルはインストールできたので、早速起動してみましょう。

まず、XAMPP Control Panelからapacheを起動させます。

（起動前）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250196/5de79323-f34f-10e8-7164-3c28e73d5a47.png)

（起動後）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250196/eb70265b-216d-9823-312b-f6149de3f61a.png)

その後、コマンドプロンプトでカレントディレクトリをLaravelフォルダ（僕の場合、demoフォルダ）に変更し、以下のコマンドを打ちます。

```
php artisan serve
```

これでLaravelのサーバーが立ち上がったので、以下にアクセスしてみましょう。
http://127.0.0.1:8000/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250196/799a1907-3ddc-c5bf-d6a1-f281e4a7a8c1.png)

この画面が表示されればOKです！

#最後に
今回はLaravelのセットアップまでを記事にしました。
久しぶりに記事を書きましたが、やっぱり文章化することって難しいですね^^;

もし内容に誤りがありましたら、ご指摘をお願いします。
次の記事もよろしくお願いします。
【SwiftUI】公式 Tutorials「 Animating Views and Transitions」の解説Part.2

#この記事は何？
Section1「Add Hiking Data to the App」で作成するビューのコードを読んでみました。

###環境
macOS 11.2.1
Xcode 12.4
Swift 5.3


#HikeDetailビュー

````Swift:
struct HikeDetail: View {
    let hike: Hike
    @State var dataToShow = \Hike.Observation.elevation

    var buttons = [
        ("Elevation", \Hike.Observation.elevation),
        ("Heart Rate", \Hike.Observation.heartRate),
        ("Pace", \Hike.Observation.pace)
    ]

    var body: some View {
        return VStack {
            HikeGraph(hike: hike, path: dataToShow)
                .frame(height: 200)

            HStack(spacing: 25) {
                ForEach(buttons, id: \.0) { value in
                    Button(action: {
                        self.dataToShow = value.1
                    }) {
                        Text(value.0)
                            .font(.system(size: 15))
                            .foregroundColor(value.1 == self.dataToShow ? Color.gray
                                                                        : Color.accentColor)
                            .animation(nil)
                    }
                }
            }
        }
    }
}
````

HikeDetailビューの外観
![スクリーンショット 2021-02-16 1.33.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/b7bcc7ea-c6ca-4c87-85be-b96892a28b41.png)

HikeDetailを構成するビュー階層
![スクリーンショット 2021-02-16 1.39.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/78460379-c61a-24a9-5cba-e931e8bb14e2.png)

###状態変数detailToShowの挙動

````Swift:
ForEach(buttons, id: \.0) { value in
    Button(action: {
        self.dataToShow = value.1
    }) {
    Text(value.0)
        .foregroundColor(value.1 == self.dataToShow ? Color.gray : Color.accentColor)
    }                
}
````
expressでライブラリを使わずBasic認証を簡単に導入する

# Basic認証の実装

```typescript
import { RequestHandler } from "express";
import { Secret } from "../Configs/Secret";

export const authBasic: RequestHandler = (req, res, next) => {
  const authValue = req.header("authorization") || "";

  const requestBasicAuthDialog = () => {
    res.setHeader("WWW-Authenticate", "Basic");
    res.sendStatus(401);
  };

  if (authValue.length == 0) return requestBasicAuthDialog();

  const basicValue = authValue.split("Basic ")[1];
  const basicString = Buffer.from(basicValue, "base64").toString();
  const splitedString = basicString.split(":");
  const userId = splitedString[0];
  const password = splitedString[1];

  if (
    userId == Secret.BASIC_AUTH.USER_ID &&
    password == Secret.BASIC_AUTH.PASSWORD
  )
    return next();
  else return requestBasicAuthDialog();
};
```

Response headerに `WWW-Authenticate` を含めるとブラウザから自動でBasic認証のダイアログが表示されます。
ダイアログが表示され、ログインするまでの流れは以下のようになっています。

1. 該当パスにアクセスし、authorizationヘッダの値が空なので上記のヘッダを返し、ダイアログを表示します
2. ダイアログにID, Passwordを入力して送信すると、同一のパスにリクエストが再び来て、今度はauthorizationヘッダに値が入っているので、それをみて正しければnext()でRouterに設定されたハンドラーを実行、正しくなければ再度ダイアログを表示します

# 使い方
```typescript
import express from "express";
import { authBasic } from "../Middlewares/authBasic"

export const rootRouter = express.Router();

rootRouter.use("/", authBasic);

rootRouter.get("/", (req, res) => {
  res.send("Hi, owner!");
});
```
GithubとCapistranoへのキー設定

Capistranoでデプロイするためのキー設定を行います。ここではgithubのリポジトリへDeployKeyを設定しない方法を紹介しています。デプロイ先のサーバー台数が増えてきた場合はサーバー個別にキー設定をするのは面倒なので、この方法が良いと思います。

この記事で使用しているCapistranoのバージョンは3.15.0です。

## 1. 自分のマシンのssh鍵を作成する
下記のコマンドを実行します。

```bash
$ ssh-keygen -t rsa
```
パスフレーズはセットしません。
これにより、~/.sshにid_rsaとid_rsa.pubが作られます。
id_rsaが秘密鍵、id_rsa.pubが公開鍵です。

## 2. 自分のマシンの「公開鍵」をgithubに登録する
作成したid_rsa.pubをgithubに登録し、ローカルからgithubへsshでアクセスできるようにします。設定方法は下記のgithubのドキュメントを参考にしてください。

https://docs.github.com/ja/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account

## 3. githubにセットした公開鍵に対する秘密鍵を指定する

下記のコマンドを実行して、ssh-agentを起動し、秘密鍵のパスを指定します。

```bash
$ eval "$(ssh-agent -s)"
$ ssh-add ~/.ssh/id_rsa
```

毎回入力するのは面倒なので、.zshrcや.bash_profileに登録しておくと便利です。

## 4. ローカルからデプロイ先へのアクセス設定をする

Capistranoにローカルからデプロイ先のアクセスするための設定を行います。

AWS EC2を利用する場合はAWSが発行したpemを使ってアクセスしますが、そのケースは下記のように設定します。もしすでにデプロイ先に自分のマシンの公開鍵をセットするなどして、アクセスできる場合はこの設定は不要です。

```ruby:config/deploy/production.rb
set :ssh_options, {
  auth_methods: [ 'publickey' ],
  keys:         [ '~/.ssh/aws.pem' ],
}
```

上記はpemを~/.sshに配置したことを想定しています。それ以外の場所に設置した場合はそれにあわせて書き換えてください。

## 5. 確認

下記のようになれば成功です。

```bash
$ bundle exec cap production deploy:check
00:00 git:wrapper
      01 mkdir -p /tmp
    ✔ 01 ec2-user@xx.xxx.xx.xx 0.087s
      Uploading /tmp/git-ssh-a01f19cecd7277afb347.sh 100.0%
      02 chmod 700 /tmp/git-ssh-a01f19cecd7277afb347.sh
    ✔ 02 ec2-user@xx.xxx.xx.xx 0.082s
00:00 git:check
      01 git ls-remote git@github.com:username/sampleapp.git HEAD
      01 3c12f893e9804130cba2621d2920555fc7d2a4c3	HEAD
    ✔ 01 ec2-user@xx.xxx.xx.xx 2.070s
00:02 deploy:check:directories
      01 mkdir -p /var/rails/sampleapp/shared /var/rails/sampleapp/releases
    ✔ 01 ec2-user@xx.xxx.xx.xx 0.038s
00:02 deploy:check:linked_dirs
      01 mkdir -p /var/rails/sampleapp/shared/log /var/rails/sampleapp/shared/tmp/pids /var/rails/sampleapp/shared/tmp/cache /var/rails/sampleapp/shared/tmp/sockets /var/rails/sampleapp/shared/public/system /var/rails/sampleapp/shared/…
    ✔ 01 ec2-user@xx.xxx.xx.xx 0.115s
00:02 deploy:check:make_linked_dirs
      01 mkdir -p /var/rails/sampleapp/shared/config
    ✔ 01 ec2-user@xx.xxx.xx.xx 0.079s
```

## 6. 備考
#### forward_agentオプションについて
これに関するの記事を見ると、forward_agent: trueを設定しているものを見かけますが、今回試してみたところ、この設定はあってもなくても関係なくデプロイができました。Capistranoのバージョンにもよるのかもしれませんが、今回使用している3.15.0では不要であったため、記載していません。

#### 公式ドキュメント

Github（SSH関連）
https://docs.github.com/ja/github/authenticating-to-github/connecting-to-github-with-ssh

Capistrano（認証関連）
https://capistranorb.com/documentation/getting-started/authentication-and-authorisation/
create-react-app + electrion-forge @Windows

# はじめに

[Electron Apps Made Easy with Create React App and Electron Forge](https://dev.to/mandiwise/electron-apps-made-easy-with-create-react-app-and-electron-forge-560e)を参考に初めてみた。

が、`electron-forge make`が失敗する。
どうやら、Windowsのパス制限の模様。ざっくりというと、以下のような感じにする！

1. プロジェクトは浅いディレクトリで開発する。
2. package.jsonにasar:trueを指定する。

## よくわからない言葉で怒られる.....

```
An unhandled error has occurred inside Forge:[39m
[31mAn error occured while making for target: squirrel[39m
[31mFailed with exit code: 1[39m
[31mOutput:[39m
[31m'electron_react.nuspec' ?????????????????[39m
[31m??????????????????????????????????? 260 ????????????????? 248 ????????????[39m

[31mError: Failed with exit code: 1[39m
[31mOutput:[39m
[31m'electron_react.nuspec' ?????????????????[39m
[31m??????????????????????????????????? 260 ????????????????? 248 ????????????[39m
```

node_modules\electron-winstaller\src\spawn-promise.tsあたりで怒られているが、実際は、node_modules\electron-winstaller\lib\spawn-promise.jsで怒られている。
＃ソースマップでそうなるのはわかるが......

とりあえず、iconv-liteをかましてstdoutをShift_JISを変換かけてやる。

```js:spawn-promise.js
        var bufHandler = function (b) {
            // var chunk = b.toString();
            // stdout += chunk;
            stdout += iconv.decode(Buffer.from(b), 'Shift_JIS')
        };
```

どうやらパスが長いらしい。
Windows 10になっても、あいかわらず、こんなことで怒られるとは......
ということで、プロジェクトのディレクトリを上の方に移動すると、とりあえずは解決する。

## 再度、怒られる.....

今度は、こんな感じ。

```
An unhandled error has occurred inside Forge:
An error occured while making for target: squirrel
Failed with exit code: 4294967295
Output:
System.AggregateException: 1 つ以上のエラーが発生しました。 ---> System.IO.PathTooLongException: 指定されたパス、ファイル名、またはその両方が長すぎます。完 
全限定型名は 260 文字未満で指定し、ディレクトリ名は 248 未満で指定してください。
   場所 System.IO.Path.LegacyNormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
   場所 System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
   場所 System.IO.Path.InternalGetDirectoryName(String path)
   場所 Squirrel.ReleasePackage.<>c__DisplayClass14_0.<extractZipWithEscaping>b__0()
   場所 System.Threading.Tasks.Task.InnerInvoke()
   場所 System.Threading.Tasks.Task.Execute()
```

どうしようかと調べてみると、以下のように、asarを使ってあげればいいらしい。

```json:package.json
 "config": {
    "forge": {
      "packagerConfig": {
        "asar": true
      },
```

# おしまい

ぜんぜん、本題に入れないが、とりあえず、makeまでできるようになった。
これから、なんか作っていこう！
XcodeでVimキーバインドを利用する方法

## 概要
SwiftUIでiOSネイティブ開発をすることになった．
慣れたVimキーバインドで開発をしたいが，IDE（Xcode）なしでネイティブ開発するのは辛すぎる...
そこで，XcodeでVimキーバインドを利用するように設定する．
具体的には，[XVim2](https://github.com/XVimProject/XVim2)というXcodeの 3rd party extension を導入する．
XCode 8 以降は 3rd party extension の導入を前提とした設計になっていないので，KeychainAccessなどの設定を自分ですることになる．

## 本記事での環境
* macOS Big Sur (version 11.1)
* Xcode Version 12.4 (12D4e)

## 手順
### code sign certificate の準備
~/Application/KeychainAccess.app を開く．
下図の通り，Certificate Assistant -> Create a Certificate を開く．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251973/c75fcb58-9179-63d2-244d-1c4ac0e87559.png)

「Create Your Certificate」のウィンドウが新しく開くので，適当なNameを設定し，Certificate Type を Code Signingにする．
Done を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251973/7da36d26-e28c-7fc3-e6e7-0dc872e405f1.png)

### Xcodeの再署名
```
sudo codesign -f -s XcodeSigner /Applications/Xcode.app
```
結構，実行には時間がかかる．

### XVim2のクローンとmake
```
git clone https://github.com/XVimProject/XVim2.git
```

makeする

```
cd XVim2
make
```

### Xcodeの起動
Xcode.appを開く．
起動時に，bundleを読み込むかどうか聞かれるので，読み込むを選択する．
上記の手順が正しくできてインストールされていれば，vimキーバインドを使うことができる．
どのようなキーバインドが使えるかは，[feature list](https://github.com/XVimProject/XVim2/blob/master/Documents/FeatureList.md)に記載されている．

以上
Deviseのパスワードリセットでメールアドレスが登録済みかどうかに関係なく動くようにする方法

備忘録として書いたものです。

## やりたいこと

- deviseのパスワードリセット機能で、登録されていないメールアドレスを入力するとエラーが表示される(不正なアクセスにより使用されているメールアドレスが特定される可能性がある)

これを

- メールアドレスが登録されているか(できるだけ)分からないようにする

## 方法

Deviseのparanoidモードを使います。
設定ファイル内でコメントアウトされているので有効にします。

```rb:config/initializers/devise.rb
config.paranoid = true
```

詳しくは参考リンクをご確認ください。

## 参考リンク

Github

- https://github.com/heartcombo/devise/wiki/How-To:-Using-paranoid-mode,-avoid-user-enumeration-on-registerable
【SwiftUI】公式 Tutorials「 Animating Views and Transitions」の解説Part.1

#この記事は何？
Section1「Add Hiking Data to the App」で作成するビューのコードを読んでみました。

###環境
macOS 11.2.1
Xcode 12.4
Swift 5.3

#HikeView

````Swift:HikeViewの定義
struct HikeView: View {
    var hike: Hike
    @State private var showDetail = false

    var body: some View {
        VStack {
            HStack {
                HikeGraph(hike: hike, path: \.elevation)
                    .frame(width: 50, height: 30)
                    .animation(nil)

                VStack(alignment: .leading) {
                    Text(hike.name)
                        .font(.headline)
                    Text(hike.distanceText)
                }

                Spacer()

                Button(action: {
                    self.showDetail.toggle()
                }) {
                    Image(systemName: "chevron.right.circle")
                        .imageScale(.large)
                        .rotationEffect(.degrees(showDetail ? 90 : 0))
                        .padding()
                }
            }

            if showDetail {
                HikeDetail(hike: hike)
            }
        }
    }
}
````



HikeViewの外観
![SwiftUI1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/06c292ce-a846-db46-c74a-3a3ad2a24663.jpeg)


HikeViewを構成するビュー階層
![HikeView.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/c0f0f1fc-18ea-3a96-5898-0fce5a8e4822.png)




###状態変数showDetailの挙動
````Swift:
Button(action: {
    self.showDetail.toggle()                
}) {
    ...
}
````

````Swift:
if showDetail {
    HikeDetail(hike: hike)            
}
````

![SwiftUI2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/aa2c4cb0-0abb-3ddd-04b7-3aca3d5638db.jpeg)
【devise】Mysql2::Error: Specified key was too long; max key length is 767 bytesを解決した一例

# 対処方法(一例)
1. config/database.ymlファイルの「encoding:」の設定を「utf8」に変更
2. `rails db:migrate:reset`
3. `rails db:migrate`

# エラー発生までの経緯
```
・rails _6.0.0_ new アプリ名 -d mysql
・rails db:create
・rails db:migrate
・gem 'devise'を記述
・bundle install
・rails s
・rails g devise user
```
上記を実行後、マイグレーションファイルに必要なカラムを追加し、`rails db:migrate`を実行したところでエラーが発生。

```
Mysql2::Error: Specified key was too long; max key length is 767 bytes
```


# 対処するまで
上記エラー文をそのまま検索し、こちらの記事を見て「encoding:」の設定を変更し忘れていたことに気づいた💦
参考[【Mysql2】Mysql2::Error: Specified key was too long; max key length is 767 bytes→文字制限をかけるファイルを新規作成することで解決する
](https://qiita.com/cherry_2020/items/07dafcf709e04a0ffb34)

```config/database.yml
# 〜省略〜
default: &default
  adapter: mysql2
  encoding: utf8      # ← utf8mb4 から utf8 に変更
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock
# 〜省略〜
```
これで一旦上記エラーは解決。しかし、再び`rails db:migrate`を実行すると別のエラーが発生。

```
Mysql2::Error: Table 'users' already exists
```

こちらは既にテーブルが作成済みとのことだったので、以下のコマンドを入力。

```rails db:migrate:reset```

ようやくエラーが解決し、最後に`rails db:migrate`を実行。
無事にdeviseの導入をすることができた。
Reactメモ

#項目
- 環境構築
- `Hello World`
- JSX
- コンポーネントとProps
- etc

#環境構築
[これでnode.jsを入れておく](https://qiita.com/pokurin123/items/3e77ce236772168344d1)

```bash
$ npm -v
#ここでバージョンが出てくればOK
$ npm install -g create-react-app
#作業ディレクトリに移ってから
$ create-react-app my-app
$ cd my-app
$ npm start

#これでそれっぽいページが出れば完了
```

#Hello World
`src/App.js`は全部コメントアウトしていい

```javascript:src/index.js
import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
  <h1>Hello World</h1>,
  document.getElementById("app")
);
```

```html:public/index.html
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--↑このrootをappに変更-->
<div id="app"></div>
```
- `import React from 'react';`、`import ReactDOM from 'react-dom';`はライブラリを入れている
- `ReactDOM.render`は描画する色んな物の土台みたいなやつ
- `document.getElementById("app")`、テンプレートで書いたidをここで使っている
- このidに割り当てられた`<h1>Hello World</h1>,`を描写している

#JSX
- 上の`<h1>Hello World</h1>,`のこと
- HTMLのタグっぽいけどそうではない
- でも同じようなもの
- 変数に入れて使用も出来る

```javascript
//例
const hello = <h1>Hello World</h1>;

ReactDOM.render(
  hello,
  document.getElementById("app")
);
```
###JSX中にJavaScriptを使う
- JSX中で`{~~~}`で囲む

```javascript
//例
let x = 1
let y = 2
const sum = <h1>{x} + {y} = {x + y}</h1>;

ReactDOM.render(
  sum,
  document.getElementById('app')
);

//1 + 2 = 3
```
- 関数を使うことも可能

```javascript
//例
function hello(){
  return "Hello World";
};

const he_wo = <h1>{hello()}</h1>;
ReactDOM.render(
  he_wo,
  document.getElementById('app')
);

//Hello World
```
###JSXに属性の定義
- `name`やら`id`やら
- 普通に定義すればOK
- 数値型を入れたい場合は`{~~~}`で囲む

```javascript
//例
const hello = <h1 name="hello_w">Hello World</h1>
ReactDOM.render(
  hello,
  document.getElementById('app')
);

//数値型の場合は <h1 name={1}> こんな感じにする
```
- **関数の返し**を属性として扱えたりもする
- この場合は`<h1 name={関数名(引数)}>`でOK
- **ラベル**も付けられる
- `<h1 name={{name: "Hello_w"}}>`　こんな感じで二重に囲む、一度ラベルの処理をしてからその結果をjavascriptとして認識してる?

#コンポーネントとProps
- `コンポーネント`：機能ごとに分けて書く時のやつ、Flaskで一個のバックエンドディレクトリで書いた時のdefというか何というか
- 明日かく
[Ruby on Rails] Mysql2::Error: MySQL  client  is not connected

今日は初めてのエラーに遭遇しました。
その備忘録を書いていきたいと思います。



　　
テストコードを書き終わって、確認の際の
bundle execコマンドを実行した時に出くわしたエラーでした。


![スクリーンショット 2021-02-15 11.43.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/d00f99db-c383-9342-8a3b-cf44c587d495.png)

このエラーが出ると、テストコードも読み込んでくれなくなり大変でした。



###結論から言うと

**原因はサーバー高負荷によるものでした。**
　　　　
　　
まず、考えられる原因が２つありました。


**・**テストコードのFactory.Botの記述でインスタンス変数を3つも使用していたこと。
その中でbuildではなく、**3つともcreate**を使っていたのが原因の一つだと考えられます。

createの記述にするとデータベースにデータを**保存しようとするので処理が重たくなった**のでは、と考えられます。

　

**・**もう一つは上記の中、テストコードを読み込んでくれるコマンドを**何回も実行していたから**だと考えられます。

　
　
##解決方法

まずcreateの記述自体がミスで、結果２つでよかった。

あとは読み込みが重くなっているであろう
インスタンス変数を定義してある文の下に
こちらのコマンドを記述する。


##sleep（0.1）

簡単に説明すると、**処理の読み込みを、あえて遅くするメソッド**です。


自分の場合は 最初**sleep(1)**から実行して、どんどん下げながら様子を見ました。
結果、**sleep(0.1)**に落ち着きました。


それ以降は問題なく動いています。
Larevelプロジェクト作成からのコマンド一覧

自分用のメモとしてLaravelのコマンドを書いていきます。

皆さんの開発を準備する上で参考にして頂けたらなと思います。

特に細かい説明はございませんのでご了承ください。

#プロジェクトの作成#

```
composer create-project "laravel/laravel=8.*" 名前 --prefer-dist
```

``--prefer-dist``はzip形式でダウンロードすることを意味しています。

zip形式でダウンロードすることでより早くプロジェクトを作成することが可能です。

``laravel/laravel=8.*``ではこのようにしてバージョンを指定することができます。

最新版をダウンロードしたい場合は``laravel/laravel``としてください。

#モデルの作成#

```
php artisan make:model Model -m
```

モデルの作成コマンドです。

テーブルを作る際には``-m``としてモデルを作成することをおススメします。

なぜかと言うと、テーブルを参照する際に普通は以下のように書くと思います。

```
DB::tabel('models')::where()～
```

ですが、モデルを作成しておくと

```
Model::where()～
```

と書くことができ、``DB::table()``を省略することができます。

使わなくても``-m``コマンドを付けておけば後に使いたくなった時に便利でしょう。

#コントローラーの作成#

###api、モデルなし###

```
php artisan make:controller SharesController
```

###apiあり、モデルなし###

```
php artisan make:controller SharesController --api
```

###api、モデルあり###

```
php artisan make:controller SharesController --api --model=Model
```

``--api``を使うことでAPI作成を行うための準備を自動でやってくれます。

``--model``は先ほど説明した``Model::where()``を使うために指定します。

#CORS対策#

次にCORS対策を行います。

簡単に説明すると、バックエンドとフロントエンドをつなぐための設定を行います。

```config/cors.php
<?php
return [
 'paths' => ['*'],
 'allowed_methods' => ['*'],
 'allowed_origins' => ['*'],
 'allowed_origins_patterns' => [],
 'allowed_headers' => ['*'],
 'exposed_headers' => false,
 'max_age' => false,
 'supports_credentials' => false,
];
```

基本的にはこれで大丈夫でしょう！

phpコマンドは長いので結構忘れるのでメモしておきました。

皆さんもぜひご利用ください！！

以上、「Larevelプロジェクト作成からのコマンド一覧」でした！

良ければ、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

Thank you for reading
心理学の観点から考えるUI/UX

# はじめに
* 今回は、Webページやアプリに関するUI/UXを心理学の観点から考えてみるという内容です。
* オライリーより出版されている[「インタフェースデザインの心理学 ―ウェブやアプリに新たな視点をもたらす100の指針」](https://www.amazon.co.jp/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%81%AE%E5%BF%83%E7%90%86%E5%AD%A6-%E2%80%95%E3%82%A6%E3%82%A7%E3%83%96%E3%82%84%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AB%E6%96%B0%E3%81%9F%E3%81%AA%E8%A6%96%E7%82%B9%E3%82%92%E3%82%82%E3%81%9F%E3%82%89%E3%81%99100%E3%81%AE%E6%8C%87%E9%87%9D-Susan-Weinschenk/dp/4873115574)を基にしています。

## 視線追跡とWebページ
### ポイント
* Webページを見て、まず注目し意識するのは人の顔です。
* その顔が、同じページの別の場所や商品を見ている場合、閲覧者はその視線を追って、その先のもの意識的に見る傾向がある

### 心理学的に
* 人間の脳には、顔の認識だけを専門に行っている領域があるそうです。(紡錘状顔領域)
* この領域により、通常の認識経路を通らずに顔を物の認識よりも素早く識別できるようになっている。→ なので、webページを見た際に意識的に人の顔を識別し視線の先を見てしまうようです。

## 人はどのように画面を見るのか
### ポイント
* 左から右に読む言語だと、ユーザは画面を左から右に見る傾向があるようです。右から左に読む言語なら、その逆です。
* 画面の端を避けて中心の方から見る傾向もある。

### 心理学的に
* 人は普通画面を見た時に、自分の使う言語で標準的な読み方で移動していくものです。
* ただ、逸脱するパターンもあり、例えば、大きな写真や動きのあるバナーなどが該当します。

## アフォーダンスとデザイン
### アフォーダンスとは
* ある物(現実の世界であれ、画面上であれ)を見たときに、それを使って何ができるか見ただけで分かるようにすること。

### ポイント
* 右のドアノブを見たときに思うのは、「掴んで押し下げる」だと思います。=>　これが期待通りの機能をするならこの設計は適切
* Webページとかだと、下線付きの青いテキストは、ハイパーリンクになっており、クリックすると別ページへ飛ぶ。=> これは多くの人が期待通りと思う。
* マウスを動かしてあるオブジェクトの上にカーソルが重なった時に、ポインタの形と全体の色が変わるような作りは、多くの人が期待した動きと逸脱すると思う。=> アフォーダンスの配慮が足りていない。

## 文化によって色の意味が違う
### ポイント
* 色は、見た人が思い浮かべる意味に配慮して選ぶ。
* 自分のデザインの対象となる主な文化圏をいくつか選び、想定外の連想を招かないように(https://informationisbeautiful.net/)等に掲載されている文化のカラーチャートで確認する。

### 心理学的に
* 色には意味があり、何かを連想させる効果もある。
* 例えば、赤は「赤字」, 経営難, 時には危険や「止まれ」を意味する。
* 緑は、「金」(米国の場合)や、「進め」を意味する。
* 白は、米国では純潔を意味し、結婚式で使うが、白が死を意味し、葬儀で使う文化圏もあります。

## 情報は少ないほどきちんと脳で処理される
### ポイント
* 段階的開示を利用すると、ユーザが必要としている時に、必要な情報を表示することで、分かりやすくなります。
* 段階的開示とは、人がそのとき、その時点で必要としている情報を提供することです。

### 心理学的に
* 人が1秒あたりに処理できる情報は400億と推測されているが、この中で脳によって意識的に処理される段階にたどり着くには40くらい。
* なので、一度に大量の情報を与えるのは良くない。
* Webページに段階的開示を取り入れると、利用者が何度もクリックを必要とするかもしれない。=> しかし、クリックのたびに適度な情報を得ながら先へ進めるのであれば、クリックしていることを意識しない。
(https://mailchimp.com/)

## 心的リソースの量

### ポイント
* ユーザにかかる心的リソースの消費で一番大きなものは認知負荷

### 心理学的に
* オンラインバンキングのシステム利用する場面を考えたときに、どのような作業を行うか考える。
* 何の代金をいつまでに送金しなければならないのか考える。 => 認知負荷
* 残高を確認する => 視覚負荷
* ボタンをクリックして振り込み処理を行う。 => 運動負荷
* 心的リソースの消費が多い順に並び替えると、「認知」 =>「視覚」 => 「運動」

****

* Webアプリ、webサイトを設計する時、この心的リソースはトレードオフの関係になるのを注意する。
* 例えば、クリック数が多くなるが、そのおかげで認知負荷が減るのであれば、価値がある。

## まとめ
* UI/UXで迷った時に、心理学観点を持つと、ユーザビリティの高いものになるかもしれません。
* 次回は、代表的なマッチングアプリのUI/UXを比較し、考察する的なことをしてみたいと思います。w
Quicとは何か？

# QUICとは
* QUICとは、Googleが高速化を目指し、UDPソケット上に用意したプロトコルです。
* なぜ、Googleはこのquicを作り出したのかというと、それは多分HTTP/2がTCPソケットの上に実装されたものであるからだと考えられます。
* どうしても、TCPは接続初期に何度か往復した通信をする必要があり、エラーや順序の整列をきちんとするために受信通知を返す必要があります。つまり高機能ではあるが、パフォーマンスへの影響が少なからず起こるということです。

**では、UDPはどうか?**
UDPは、TCPで行われている再送処理や輻輳制御などを取り払い通信回数を減らすことでパフォーマンスへの影響を減らしたプロトコルです。

**では、QUICはどうなのか？**
QUICでは、TCPが行っているようなパケットロス時の再送処理や、輻輳時の制御などを自前で実装しています。
また、TLSの機能を保持しており、シーケンス番号などのデータも隠蔽しています。

**じゃあ、HTTPSでのTCPと変わらないのでは？**
HTTPSでは、TCPのハンドシェイク後にTLSのハンドシェイクを行う必要があり、何度も通信を往復しパケットを送信する必要がありました。
しかし、QUICでは、この2つの確認を融合しておりより少ない通信、(初回で1往復でネゴシエーション)できます。

![スクリーンショット 2021-02-15 22.59.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/459d63e0-01c4-480b-3cf0-5376d6d88b1b.png)

[引用: https://datatracker.ietf.org/meeting/98/materials/slides-98-edu-sessf-quic-tutorial/](https://datatracker.ietf.org/meeting/98/materials/slides-98-edu-sessf-quic-tutorial/)

**実はこの、QUICのIETF版として議論されているHTTP over QUICをHTTP/3という名前にすることが決定されています。**

## QUICトランスポートプロトコル
QUICトランスポートプロトコルは、QUICのIETF版として定義されたもので、TCPとTLSレイヤが置き換わるようなもので、
UDPを基にして再送処理、輻輳制御, 暗号化などを実装したものです。
![スクリーンショット 2021-02-15 23.36.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/8cbb2de8-1230-460f-643a-c6e25ec22cb7.png)
[引用: https://blog.honai.me/post/how-http-works-5-quic-http3](https://blog.honai.me/post/how-http-works-5-quic-http3)

**つまり、どう違うの？**

* TCPでは、1つのコネクション内のパケットが全て整列されて転送されることを保証する。
* QUICでは、セッションは張るがその中に複数の通信のストリームを張り、ストリームの内部では順序を保証するものの、ストリーム間での保証はしない。

# quic-go
goでquicを試してみたい場合は、[quic-go](https://github.com/lucas-clemente/quic-go)がおすすめです。
僕も試してみようと思ったのですが、体力が尽きたので、実際に試されている面白記事を載せて終わらせたいと思います。
[参考: https://tech.aptpod.co.jp/entry/2021/01/28/100000](https://tech.aptpod.co.jp/entry/2021/01/28/100000)
vscode＋SFTPで拡張機能のホストが予期せずに終了しました（解決済み）

#環境
macOS Big Sur
VSCode（version:1.53）
SFTP（拡張機能)
AWSEC2
#事象
複数のEC2に対してSFTP(拡張機能)でアップしているのですが、
その中の1つのサーバのみ「拡張機能のホストが予期せずに終了しました」表示が出てSFTPでアップできない。
開発ツール表示してもExtension host terminated unexpectedlyとかマイクロソフトのなんやらとかなんだか色々出てる。

#やったこと（直らなかったやつです）
**再起動**
**ソース丸ごと差し替え**
**拡張機能全停止**
**vscod入れ直し**
**キーチェーンのそれっぽいやつ消してみる**

1つのサーバのみなので、原因はソース側？と予想して、色々やってみたものの、
やればやるだけわからなって、ネットに出てくる情報片っ端から試しました。


#解決策
バージョン: 1.53から、バージョン: 1.52.1にダウングレード。
これで一発でなおった。

複数の中の1サーバのみで、ソース差し替えてもNGってことは、認証系の何かだと思うけど、未だ原因は不明・・

#最後に
vscodeの自動更新を止めておかないと、すぐ元に戻っちゃうので、
設定→更新で検索して自動更新をoffにしとくと良いです。
`sfdx force:auth:web:login` で `localhost:1717` が応答しない

メモです

## 起きた事

`sfdx-cli` で sandbox 環境の認証を通そうとしたら出来なかった。

> [sfdx\-cli \- npm](https://www.npmjs.com/package/sfdx-cli)

よく分からないけどバグっぽい。

> [Webserver not responding \- force:web:auth:login on Linux · Issue \#783 · forcedotcom/cli](https://github.com/forcedotcom/cli/issues/783)

コメントにあるようにダウングレードしてみたけど、自分の環境では変わらなかった。
以前使っていたバージョンでは認証出来ていたけど、何度かパッケージのアップデートをしてしまっていて、そのアップデート後のバージョンでは認証操作は試していなかったかも。
認証がパス出来ていたバージョンが分からない…。

WSL2 で起きていたので、 Windows 上に Node.js のバイナリを入れる所から試してみたけど変わらず。

## 回避策

`force:auth:web:login` ではなく `force:auth:device:login` を使う。

```sh
sfdx force:auth:device:login -r https://test.salesforce.com
```

なお `@salesforce/plugin-auth` の特定のバージョンを入れていると認証先に sandbox を指定できないので注意。その場合はアンインストールする。
今日色々試す過程で入れちゃったけど、本来は不要なプラグイン。
S3の暗号化について

## 暗号化

バケットに保存されたオブジェクトを自動的に暗号化する機能があります。

![S3 Management Console - Google Chrome 2021-02-15 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/65de67dc-58f9-6fa8-cece-d27e581072f1.png)

暗号化タイプは2種類あります

### SSE-S3

- s3がデータ暗号化キーとマスター暗号化キーを管理を管理します
- キーに対する個別アクセス制限は出来ず、当該AWSアカウントID以外の拒否のみとなります
- CloudTrailのログには残りません
- 追加料金は発生しません

### SSE-KMS

- 暗号化キーの作成および管理が自分で出来る
- AWSアカウントのリージョンごとに作成されるデフォルトサービスキーを使用することが出来る
- [KMS](https://qiita.com/miyuki_samitani/items/c3c871e2312b9a47b9e2) に対するAPIコールを行うため、CloudTrailを残すことが可能
-   KMSを利用するため、KMSの費用が発生

## 勉強後イメージ

監査に残さないといけない だったり、
自分で鍵を管理するためにはKMSで管理するべきなのかー
とりあえずで暗号化しないといけない だけだったらs3のデフォルト暗号化でよいのかな？

## 参考

- [SSE-S3とSSE-KMSの違いを知る](https://ktrysmt.github.io/blog/difference-between-sse-s3-and-sse-kms/)
- [S3が暗号化されている実感がわかないので、復号できない場合の挙動を確かめてみた](https://dev.classmethod.jp/articles/behavior-when-s3-cannot-be-decrypted/)
超個人的Gitコマンドメモ（備忘録）

#よく使うgitコマンド
###ブランチを確認する
git branch

###「AAA」というブランチを作成する
git branch AAA
※作成だけで切り替えはしないため注意

###ブランチを確認する（できたか）
git branch
⇒出来ていたらこんな感じになる。
　AAA
* master

###ブランチを切り替える
git checkout AAA

念のためgit branchするとこうなる。↓
* AAA
　master

##コミットした後
###masterブランチへ移動
git checkout master

###git pullでmasterを最新に
git pull origin master

###開発用ブランチへ移動
git checkout BBB

###mergeコマンドでmaserの内容を取り込む
git merge origin master
⇒「BBB」に最新にしたばっかの「master」ブランチ情報を取り込む
【RaspberryPi】Apache+WSGI+FlaskでBasic認証を実装する

# 概要
WSGIを使ってデプロイしているFlaskアプリケーションに.htaccessでBasic認証をかけようとしたができなかったので、別の方法を試してみた。

# はじめに
この記事では、すでにWGSIを用いてFlaskアプリケーションがデプロイされた状態での記事になっています。
>[【Raspberry Pi】Apache+WSGI+Python Flaskを使ってhttpsでWebアプリケーションを公開する - Qiita](https://qiita.com/t-kasa-moto/items/29288246284e1ddcd259)

# 使用環境
- Raspbian 10.7
- Apache 2.4.38
- Python 3.7.3
- Flask 1.0.2
- Flask-httpauth 4.2.0

# 環境構築
## Flaskアプリケーションの設定
### flask-httpauthのインストール
RaspberryPi上でFlaskでBasic認証を可能にするパッケージをインストールします。筆者の環境はPython3なので`pip3`コマンドを使用しますが、Python2を使用しているなら`pip`を使用します。

```console
$sudo pip3 install flask-httpauth
```

### app.pyの編集
以下のようなFlaskアプリケーションを用意します。

```python:app.py
from flask import Flask
from flask_httpauth import HTTPBasicAuth

app = Flask(__name__)
auth = HTTPBasicAuth()

users = {
    "user1": "password"
}

@auth.verify_password
def verify_password(username, password):
    if username in users and password == users.get(username):
        return username

@app.route('/')
@auth.login_required
def hello():
    return 'Hello {}!'.format(auth.current_user())

if __name__ == '__main__':
    app.run()
```

`@auth.get_password`はパスワードを取得するために使用され、認証には非推奨とのことなので、`@auth.verify_password`を使用しています。
`@auth.login_required`はBasic認証を突破出来たら、その先を実行する機能です。
この時点でBasic認証はできるようになっていますが、今のままでは何を入力しても認証はできません。

## Apacheの設定
### configファイルの編集
前の記事で作成したconfファイルのWSGIを記載した部分に以下の内容を追記します。

```conf:flask_wsgi.conf
WSGIPassAuthorization On
```
これによりWSGIアプリケーションへHTTP承認を受け渡すことができるので、Basic認証が正常に使えるようになります。
### Apache2の再起動
忘れずにApache2のロードも行っておきます。

```console
$sudo systemctl reload apache2
```

正常に再起動できたら、実際の画面を開いてBasic認証が作動するか確認します。
お疲れさまでした。

# まとめ
今回は、httpsで動作していたのでシンプルなベーシック認証を実装しましたが、セキュリティの関係上ダイジェスト認証の方がいいのかなーって思います。
あと、今のままだとユーザ名とパスワードがべた書きなのでハッシュ関数なども導入してもう少し実用的な機能にしたいと思います。いずれ...

# 参考
- [flask-httpauthを使って、FlaskでBasic認証を5分で実装する - Qiita](https://qiita.com/mitch0807/items/d5e354a4e6e5b4f04bd6)
- [https://qiita.com/hum_op/items/7d5c0393ef01642cf754 - Qiita](https://qiita.com/hum_op/items/7d5c0393ef01642cf754)
- [Welcome to Flask-HTTPAuth’s documentation! — Flask-HTTPAuth documentation](https://flask-httpauth.readthedocs.io/en/latest/)
- [WSGIPassAuthorization — mod_wsgi4.8.0ドキュメント](https://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIPassAuthorization.html)
【Swift】"Fixed width constraints may cause clipping"の警告を消す方法

#はじめに

最近アプリを作成しており忙しくて投稿していなかったのですが、
ある程度の機能は実装できたので久しぶりに投稿したいと思います。

今回は、実際に私も遭遇した警告についてです。

とりあえず警告を全て消したいなと思ったので対処していたのですが、
その中でも解決に時間がかかった警告について共有いたします。

どなたかの解決に繋がりましたら幸いです。

#警告内容

タイトルにもありますが、表示される警告文は下記のものになります。

`Fixed width constraints may cause clipping`
![スクリーンショット 2021-02-15 23.35.28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/5cacf076-211d-75a4-38dc-8190c0bd2184.jpeg)


この警告は、Storyboardにオブジェクトを追加し、AutoLayoutでwidth固定の制約をつけると出現します。
内容を和訳すると`固定幅の制約によりクリッピングが発生する可能性があります`とのことです。

あっているのかわかりませんが、widthの幅を固定にすると、
フォントの変化などにより文字列の横幅が変わるので固定幅にすると文字が切れる可能性がありますよ！
という感じの警告だと思っています・・・。

私が設定した固定幅は多少の変化など問題ないくらいの余裕があるはずですが、
なぜかこの警告が出てしまいます。
（定数ではなく変数だとテキストの内容が変わるのでそれが原因なのかな？）

原因はなんとなくわかったので、次に警告を消すための解決策についてです。

##解決策

結論から言いますと、固定幅を`equal`ではなく`Greater Than or Equal`に変更すればOKです！

つまり横幅を`イコール（=）`から`以上（≧）`にするということです。

制約した横幅で収まりそうな場合はその固定幅で、
収まらなさそうな場合はその都度サイズを変更してくれる。

といった感じになります。

実際の変更手順は下記のようになります。

##手順

###パターン１
①StoryBoard右上の警告マークをクリックする
②表示されている警告の中から該当するものを選択する
![スクリーンショット 2021-02-15 23.44.24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/65eae8e3-02a9-c8b2-2ecc-5ce71939a08b.jpeg)
③`Relation`をEqualから`Greater Than or Equal`に変更する
![スクリーンショット 2021-02-15 23.45.40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/4d702064-22e7-7155-0f57-9732527bf6cd.jpeg)

###パターン２
①StoryBoardから警告が出ているオブジェクトをクリックする
②右メニューの上のロゴ？を三角定規に合わせる
![スクリーンショット 2021-02-15 23.50.04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/7f298097-262e-5319-8d93-ff08cc1087dd.jpeg)
③少し下にスクロールしwidthの制約をダブルクリックする
![スクリーンショット 2021-02-15 23.50.17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/65df62b9-8a71-53ed-3427-1f20578f7ebd.jpeg)
④`Relation`をEqualから`Greater Than or Equal`に変更する
![スクリーンショット 2021-02-15 23.50.32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/24d5b1f2-ef72-cebb-4890-fa912a29eb5c.jpeg)

上記のどちらかのパターンで解決できるはずです！

#さいごに

今回は、制約のwidthを超えることはないのでこのように解決しましたが、
本来ならしっかりと考えて変更するべき内容でもあるのかなと思います。

UI・UXは大事！というのはよく聞きますが、
こういった箇所の設計などは独学では少しハードルが高い気がします。

早く仕事でSwiftに触れたいものです・・・。

以上、最後までご覧いただきありがとうございました！
文字起こしツールを作った（無料でとりあえず動かしたい人向け） 

#はじめに
色々書かれてると逆にわからなくなるので、本当に音声認識ができる最低限のソースです。
コピペで動きます。
８行。

#精度について
比較のために、pythonのspeechrecognitionライブラリも使ってみましたが、今回使っているwebspeechapiの方が精度よかったです。（日本語・日常会話でざっくり試しただけ）

pyaudioが自分のPCと相性悪くてテスト版にしないとインストールできないとか無駄に手こずるところもあるので、オフライン利用じゃなければwebspeechapiおすすめ。

#使用ツール
・VScode＋liveserver

VScodeに下のコードを貼って、ローカルサーバ立ち上げれば動きます。
#コード
```webspeechapi.html
<script>
    const s = new webkitSpeechRecognition()//ブラウザ内臓なのでキーいらない
    s.lang = 'ja'//言語指定
    s.start()//開始処理
    s.onresult = function(e) {//音声認識処理完了時に発火
        console.log(e.results[0][0].transcript)
    }
</script>
```

#録音し続けたいとき
onendで、文字起こし１ターン終わったのを判定できるので、
ここで再startかけてあげると、録音しつづけられます。

```webspeechapi.html
<script>
s.onend = () => { //onresultで完了すると、接続が切れるため、.onendの場合、再度スタートをする。
    s.start() 
}
</script>
```

#ついでに翻訳したい
GASで翻訳API（無料）で作れるので、下記をapiに投げる処理を入れ込んであげれば、
リアルタイム文字起こし＋翻訳もできるよ。
翻訳APIって従量課金とかで手が出しにくいから、GASは本当に有能だと思う。
（自分は仮想通貨ニュースみたいので、自分はこれ＋プルダウンで言語切り替えできるようにしてます）

```
e.results[0][0].transcript
```

#作ったもの
英語youtubeの文字起こし＋翻訳
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599035/0fca1ba2-7682-c07f-5cf1-9265241e2c43.png)
関連させて削除する方法

#Sequel Pro上の違うテーブルに保存されているカラムもまとめて削除する

例として二つのモデル、guide.rbとmessage.rbを用意する
guideは掲示板、messageは掲示板への書き込みとする
この二つのモデルの関係性は

```guide.rb
has_many   :messages
```

```message.rb
belongs_to :guide
```
ここで、掲示板を削除する処理をした際に、もし掲示板に書き込みがあったとしたら、正しく削除の処理が出来ない。
なぜなら、掲示板の情報は削除したいが書き込みはどう処理したら良いか指示がないからだ。
そこで、二つのモデル、guide.rbとmessage.rbのモデルの関係性を利用して、

```guide.rb
has_many   :messages, dependent: :destroy
```

このようにコードを記述してあげることで、掲示板が削除される時はその案内板に紐づいている書き込みも一緒に削除する指示ができる。

データベースに関するエラーが表示された際は、参考にしてください。
【Unity】フレームと fps について

# フレームとは

ゲームや映画は、静止画を連続再生して、パラパラ漫画と同じような仕組みで動きのある映像を作り出している。
1つの静止画を表示させてから、次の静止画を表示するまでを「**フレーム**」という。

# fps(frame per second／フレームレート) とは

1秒間に何回フレームが切り替わっているかの単位。
格闘ゲームでよく使われている。
最近のゲームは **60fps** で処理されているものが多いと思います。（鉄拳とかスマブラとか…）

**60fps** だと、1秒間に60回フレームが切り替わっているという意味になります。
言い換えると、 1秒間に60枚の静止画（コマ）が使われていることになります。

ちなみに映画は 24fps らしいです。

ゲームが常に 60fps で動作している場合は、60fps 以上のスピードで計算、画像を作成して、わざと遅らせて画面に表示しています。
もし、計算が遅れてた場合など、何らかの原因で画面に表示できず、画面が一瞬途切れることがあります。
これを <font color="Red">**フレーム落ち**</font> と言います。

ゲームをしていて、たまにカクカクしたりするのは、フレーム落ちが発生しているためです。


### 余談：リフレッシュレート(Hz) とは

1秒間に最大何回フレームの切り替わりを処理できるかの単位。
モニターとかスマホのスペック紹介でよく使われている。

144Hz だと、1秒間に最大144回フレームを切り替えることができるという意味になります。

ちなみに iPhone の画面のリフレッシュレートは 60Hz、iPad Proは 120Hz らしいです。

# Unity の Update 関数

Unity の Update は、毎フレームごとに呼ばれます。


# Unity におけるfps

Unity のデフォルト設定では、実行環境によってFPSが自動調整されるようになっています。
この時間は、 `Time.deltaTime` を使用することで取得できます。
**直前のフレームと今のフレーム間で経過した時間[秒]** を返してくれます。

# Unity の FixedUpdate 関数

Unity には Update 関数とは別に、 FixedUpdate 関数も存在します。
これは、fps とは関係なく一定間隔で実行されます。
（一定間隔 = デフォルトでは 0.01 秒）

物理演算の前に呼ばれているらしいです。

### 余談：Unity の LastUpdate 関数

Unity には LastUpdate 関数も存在します。
これは Update 関数が実行完了したあとに、実行される関数です。

# Unity で fps を固定する

1. Edit > Project Settings を押す
2. Quality > VSsync Count の項目を **Don't Sync** に変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233011/7bde220d-4775-6f28-29a7-b4ccf302948b.png)
3. スクリプトで `Application.targetFrameRate` を定義する

```c#
Application.targetFrameRate = 30; // 30fpsに設定
```

ゲーム開始時に実行される Awake 関数や Start 関数で呼び出すと良いと思います。

# 参考文献
[書籍『Unity入門』 - Unity におけるフレームと Update](https://unity-yb.github.io/articles/frame_and_update.html)
[ゲームのフレームとは【Unityゲーム制作基礎】](https://dkrevel.com/unity-explain/unitymove/)
[【Unity】フレームレートの固定と端末での計測](https://deve-cat.com/unity-frame-rate/)
リダイレクト URI の前方一致

# はじめに

OAuth 2.0 の認可レスポンスは、登録済みの『**リダイレクト URI**』宛に返却されます。詳細は『[OAuth 2.0 の認可レスポンスとリダイレクトに関する説明](https://qiita.com/TakahikoKawasaki/items/8567c80528da43c7e844)』を参照してください。

複数のリダイレクト URI が登録されている場合、どのリダイレクト URI に認可レスポンスを返して欲しいかを、認可リクエスト時に指定する必要があります。この目的のために、`redirect_uri` リクエストパラメーターが用いられます。

認可サーバーは、`redirect_uri` リクエストパラメーターで指定された URI が、事前登録されたリダイレクト URI のいずれかに一致するかどうかを確認します。この「一致」について、「**前方一致**のサポートは可能か？」との質問を受けることが稀にあるので、見解を述べさせていただこうと思います。

# OpenID Connect のケース

ID トークンを発行するなど、OpenID Connect の機能を使う場合、`redirect_uri` は登録済みのものと完全一致が要求されます。下記は [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html) / [3.1.2.1. Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) にある `redirect_uri` リクエストパラメーターの説明からの抜粋です。

> _This URI MUST exactly match one of the Redirection URI values for the Client pre-registered at the OpenID Provider, with the matching performed as described in [Section 6.2.1](https://tools.ietf.org/html/rfc3986#section-6.2.1) of [RFC3986] \(**Simple String Comparison**)._

「**Simple String Comparison**」が「単純な文字列比較による完全一致」を意味しています。

このように、OpenID Connect ではリダイレクト URI の前方一致の許容は仕様違反となるので、サポートできません。

# Financial-grade API のケース

Financial-grade API / Part 1 / 5.2.2. Authorization Server / 10 に次のようにあります。

> _10. shall require the value of redirect_uri to **exactly match** one of the pre-registered redirect URIs;_

簡潔な文ですが、「**exactly match**」という表現が「完全一致」を要求しています。このように、Financial-grade API ではリダイレクト URI の前方一致の許容は仕様違反となるので、サポートできません。

# OAuth 2.0 のケース

OpenID Connect でも Financial-grade API でもない、純粋な OAuth 2.0 ([RFC 6749](https://tools.ietf.org/html/rfc6749)) の場合、リダイレクト URI の比較には二つのケースがあります。

一つは、比較対象の登録済みリダイレクト URI が Full URI のケースで、このときは、OpenID Connect のときと同様、[RFC 3986](https://tools.ietf.org/html/rfc3986) / [6.2.1 Simple String Comparison](https://tools.ietf.org/html/rfc3986#section-6.2.1) による完全一致が要求されます。

もう一方は、比較対象の登録済みリダイレクト URI が Full URI ではないケースで、このときは、[RFC 3986](https://tools.ietf.org/html/rfc3986) / [6. Normalization and Comparison](https://tools.ietf.org/html/rfc3986#section-6) の規則に従って正規化 (Normalization) してから比較することなります。

いずれのケースにおいても、前方一致による比較はおこなわれません。

# 独自拡張

OAuth 2.0 (RFC 6749)、OpenID Connect、Financial-grade API のどの仕様を見ても、リダイレクト URI のチェックを前方一致でおこなうことを許容するようなことは書いてありません。そのような実装があるとすれば、それは独自拡張ということになります。

# セキュリティ専門家の意見

『[OAuth 2 in Action](https://www.manning.com/books/oauth-2-in-action)』の共著者の一人である Antonio Sanso は、2016 年 11 月 28 日に公開したブログ記事『[All your Paypal OAuth tokens belong to me - localhost for the win](http://blog.intothesymmetry.com/2016/11/all-your-paypal-tokens-belong-to-me.html)』で次のように述べています。

> _The ONLY safe validation method for redirect_uri the authorization server should adopt is exact matching_
>
>_Although other methods offer client developers desirable flexibility in managing their application’s deployment, they are exploitable._

つまり、**`redirect_uri` の確認方法で唯一安全な方法は「完全一致での比較」であり、サブドメインやサブディレクトリを許容するなどの他の方法（前方一致含む）は「便利かも知れないが悪用可能な脆弱性」**であると述べています。

# 結論

リダイレクト URI のチェックを前方一致でおこなう機能は、セキュリティ的に問題があるので、私が実装することは今後もありません。

もしあなたの認可サーバーの実装が前方一致を許容しているのであれば、PayPal 社が Antonio の指摘を受けてそうしたように、実装を修正することを強く推奨します。
PowerShellでJSONを整形

#使い所
- PowerAutomateで出力されたフラットなjsonを整形して確認したい。
- 職場でEdgeしか使えない。　→Firefoxなら勝手に整形してくれる。
- VSCodeは使えない環境。
- jsonはアカウント情報を含んでおりオンラインツールはやめておきたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/21e35afd-0afa-55ef-a109-70a73c3c2a06.png)

・デスクトップに置いたjson-min.txt内にjsonを貼り付けるか、フラットなjson直接貼り付ける。

```PowerShell:json整形
$_defaultJsonPath = "$home\Desktop\json-min.txt"

$file_or_json = Read-Host "フラットjsonかファイルパスを入力して下さい。"

if($file_or_json -eq ""){
    if((Test-Path $_defaultJsonPath) -eq $false){
        Write-Host "ファイルが見つかりません。"
        return
    }

    $file_or_json = $_defaultJsonPath    
}


if((Test-Path $file_or_json) -eq $true){
    (Get-Content -Path $file_or_json -Encoding UTF8) | ConvertFrom-Json | ConvertTo-Json -Depth 100 | Set-Content $file_or_json -Encoding UTF8
    Write-Host "整形が完了しました。：" (Split-Path $file_or_json -Leaf)

}else{
    $prettyJson = $file_or_json | ConvertFrom-Json | ConvertTo-Json -Depth 100
    Write-Host $prettyJson
}

```
【Javaについてまとめてみたオブジェクト編】クラスについて

#はじめに
今回はJavaのクラスについて書いていきたいと思います。
オブジェクト指向の始まりみたいなとこなのでぜひ理解していきたいです。

##クラスとは
例えば、下記のようなまとまったデータがあるとします。

| 商品ID | 商品名 | 値段 | 在庫 |
|:-:|:-:|:-:|:-:|
| １  | チョコ  | 10  | true  |
このデータをまとめてプログラミングで扱いたい。
でも配列だと、数値や文字列が混ざってて一括で扱うのは無理や。。
こんな時に使うのがオブジェクトです。
そしてそのオブジェクトの設計図となるのがクラスなんです！！

##クラスの定義の仕方
```java:クラスの定義
public Class Item{
    int itemId;
    String itemName;
    int price;
    LocalDate date;
}
```
こんな感じで設計します。
「int itemId；」とかはメンバ変数といい、何か処理をしたい時はメソッドを作成します。
###コンストラクタ
クラスを作るうえでコンストラクタというのも重要になってきます。
コンストラクタは、インスタンスを作成する際に自動で呼ばれるメソッドで
メンバ変数の初期化などオブジェクトを作成する断崖で実行したい処理を記述します。

```java:コンストラクタの作成
public Class Item{
    int itemId;
    String itemName;
    int price;
    boolean stock;
　　//ここからがコンストラクタ
　　public Item(String itemId ,String itemName,int price,boolean stock){
	　this.itemId = itemId;
	　this.itemName = itemName;
	　this.price = price;
	　this.stock = stock;
　}
}
```
コンストラクタはクラス名と同じ名前にする必要があります。
###デフォルトコンストラクタ
ちなみにコンストラクタを定義しなかった場合はデフォルトコンストラクタと呼ばれるものが呼び出されます。

```java:デフォルトコンストラクタ
public Item(){
 super();
}
```
>(アクセス修飾子) クラス名(){
  super();
>}

引数なしのコンストラクタになっております。
一つでもコンストラクタを定義したらデフォルトコンストラクタは作成されない為、引数なしのコンストラクタも別で欲しい場合は自分で定義する必要があります！
##インスタンス化
それでは作成したクラスをオブジェクトにしてみましょう。
クラスからオブジェクトを作成することをインスタンス化といいます。

```java:インスタンス化
//引数あり
Item item1 = new Item(1,"チョコ",10,true);
//引数なし（デフォルトコンストラクタ）
Item item1 = new Item();
//メンバ変数の呼び出し
item1.itemId;
item1.itemName;
```
これでオブジェクトが作成されまとまったデータを扱えるようになりました！

##さいごに
クラスどうだったでしょうか
今回は簡単な設計でかつメソッドとかもない状態でしたが、もっと細かくみればいろんな機能があります。
軽くイメージが掴めたら幸いです。
他にもこんな機能があるとか、間違ってたらコメントください。

ご覧いただきありがとうございました。