OmniAICreator/Qiita-1.07M huggingface dataset:
【Vue.js】オブジェクト構文について

Vue.jsについて必要な知識をまとめました。
自身の備忘録として記載します。

#オブジェクト構文について
スタイルを指定する場合には「オブジェクト構文」と呼ばれる書き方をします。

```
v-bind:class="{ クラス名 : 変数 }"
```
クラス名の後に変数を指定することができます。

#v-bind:classにオブジェクトを設定する
クラスの数が増えてくると、v-bind:class内に全て記述するのが難しくなってきます。なのでv-bind:classにはオブジェクトを値として設定することができます。

#スタイルとオブジェクト構文
classにv-bindで値を設定する際にオブジェクト構文を使用して多数のクラスを用意することができました。このオブジェクト構文は他の所でも使用できます。その一つが「style」属性です。

```
v-bind:style=" オブジェクト構文 "
```
このようにv-bind:styleにオブジェクト構文を使用して値を設定することができます。style属性はスタイル名と値を必要なだけ記述していきます。

#v-bind:styleにオブジェクトを指定する
このvi-bind:styleの場合も、v-bind:classと同様にオブジェクトを値に設定することが可能。設定したオブジェクトの中に、スタイル情報をプロパティとして組み込んでおくことができれば値の設定はもっと容易になります。

#参考URL
Vue.js & Nuxt.js超入門
https://www.amazon.co.jp/dp/4798056596?tag=maftracking247988-22&linkCode=ure&creative=6339https://www.amazon.co.jp/dp/4798056596?tag=maftracking247988-22&linkCode=ure&creative=6339
Qt Creator for Windowsでコード全体の折り畳みをショートカットキーに割り当てる

# 自己紹介
画像解析系の研究をしている大学院生です。QtでGUIを作ったり、Visual Studioを使って解析コードを書いて過ごしています。
「誰でもわかる」を目指しつつ、自分の備忘録としてちょっとしたことを記載しています。

# 記事を書いたモチベーション
GUIを作成するときにはQt Creator for Windowsを使わせていただいているわけですが、CUIと違ってGUIではWidgetの記述分コード量が多くなってしまいます。コードが長いと書き換えるのが大変なので、一般的なコードエディタに実装されているソースコード中の関数やif, for文などを折りたたむ機能をよく使っています。
この機能をうまく使うことでソースコードの記述効率が上がりますが、Qt Creator for Windowsのデフォルト設定では**現在のカーソルの部分のみ**を折りたたむ/展開するショートカットキーしか割り当てられていません（カーソル位置を折りたたむ:Ctrl+<, 展開する:Ctrl+>）。
つまり、**コード全体を折りたたむ/展開する機能にはショートカットキーが割り当てられていない**ので、いつかまた環境設定をするときのために方法を記載しておきたいと思います。

# 手順
#####1. メニューバーからツール→オプションを選択すると以下のようなwindowが出現する。環境タブを選択する。
![Imgur](https://i.imgur.com/cG5TFMn.png)

#####2. Keyboard Shortcutsグループにフィルタと記載されたテキストボックスがあるので"fold"と入力する。

#####3. TextEditor - UnFoldAllが出現するため選択する。
![Imgur](https://i.imgur.com/p4oCHrD.png)

#####4. ウィンドウ下部のShortCutの欄のKey sequenceに割り当てるショートカットキーを入力する(僕はCtrl+@にしました)。
![Imgur](https://i.imgur.com/GrwbcNx.png)

#####5. ウィンドウ右下部の適用をクリックしてからOKを押すことで入力したショートカットキーが適用される。

# できているかの確認
![Imgur](https://i.imgur.com/RIVOaR7.png)
↓ ショートカットを押す！(僕はCtrl+@)
![Imgur](https://i.imgur.com/fzWB0jZ.png)
もう一度押すと展開できます。
うれしい♪
R: 整数ベクトル生成問題

えぇえぇまた嵌りました。

#起こったこと
Rで整数ベクトルを作ったのさ。
いわゆる省略形ってやつだ。

~~~
m <- 5
l <- 10
~~~

ってしとくよ。

~~~
print(m:l)
~~~

これは何を出すか。

~~~
[1]  5  6  7  8  9 10
~~~
だよね。


じゃあこれは？

~~~
m:2*l
~~~
なんと

~~~
[1] 50 40 30 20
~~~
アイエエエ？
50ナンデ？50ナンデ？ってなる。

たぶん、m:2の全体に10であるところのlがかかっている。
その順番で行くのか。。。とちょっと驚き。

ちゃんと括弧をすれば順番を指定できる。

~~~
m:(2*l)
~~~
こうすれば出力は


~~~
 [1]  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
~~~

ってなる。

### 解決策
良い子のみんなはコロンの前後はちゃんとかっこしておこうね。
おじさんとの約束だよ！
modern CSS resetでaltテキストを指定しないと画像がぼやける

:::note alert
2023年7月6日追記：
この記事の内容は完全に過去の内容です。modern CSS resetからimg要素にalt属性が指定されていないときに画像にblurがかかる仕様は既に削除されています。[参考プルリクエスト](https://github.com/Andy-set-studio/modern-css-reset/pull/33)
:::

特に設定していないはずなのに画像がぼやける現象に悩んでいた。



## 解決しなかった方法
まずGoogleで適当に検索したところ、以下のようなサイトがヒットした。
[Chromeで画像を縮小表示すると文字がなんだかぼやける現象を回避するTips](https://creativememomemo.com/chrome_image_blur/)

これに従って`-webkit-backface-visibility: hidden;`を適用させてみたが変化なし。

## 結論
[modern CSS reset](https://github.com/hankchizljaw/modern-css-reset/blob/master/dist/reset.css)に以下のようなコードがあった。

```CSS
/* Blur images when they have no alt attribute */
img:not([alt]) {
  filter: blur(10px);
}
```

**解決法**：該当部分を削除する(非推奨)か、**imgタグにalt属性を設定する**。

##まとめ
HTML5では必須でなくなったものの、Altテキストはスクリーンリーダでの利用者やBot、画像が読み込めなかった場合の代替テキストとして重要なので、必ず設定するようにする。
YouTube に Listen On Repeat へのリンクを追加する Tampermonkey スクリプト

#YouTube に Listen On Repeat へのリンクを追加する Tampermonkey スクリプト
いちいち動画IDをコピペしていたのだけれど、そういえばインストールするだけして忘れていた Tampermonkey で楽できるのではと思い立ったので試しに作ってみた。

### 8/4追記
YouTube 自体にループ再生機能追加されてた。終了。

## できたもの
```javascript:script
// ==UserScript==
// いろいろ省略
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
// ==/UserScript==

window.addEventListener('load', function(){
    'use strict';
    const videoKey = (new URLSearchParams(location.search)).get('v');
    const url = 'https://listenonrepeat.com/?v=' + videoKey
    const icon = '<svg viewBox="0 0 24 24" style="display: inline-block; color: rgb(37, 37, 37); fill: rgb(204, 204, 204); height: 22px; width: 22px; user-select: none; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;"><g id="ic_repeat"><path d="M12.8110867,2.51789455 L13.3313633,1.14289591 C13.3313633,0.570087802 12.9436767,0.335891856 12.4695722,0.622203342 L8.48364464,3.03099659 C8.00962857,3.31740063 8.00962857,3.78607023 8.48364464,4.07247428 L12.4695722,6.48126753 C12.9436767,6.76767159 13.3313633,6.53338308 13.3313633,5.96057496 L12.8110867,4.65527969 C16.8643265,5.06294726 20.0442764,8.64670064 20.0442764,12.993581 C20.0442764,17.6128878 16.4532885,21.3709459 12.0393401,21.3709459 C7.62539163,21.3709459 4.03440371,17.6128878 4.03440371,12.993581 C4.03440371,10.4516756 5.1190947,8.07602158 7.01020563,6.47562091 C7.44707172,6.10590604 7.51482621,5.43571685 7.16163603,4.97852564 C6.8083574,4.52133442 6.16787405,4.45042767 5.73109641,4.82004997 C3.3598662,6.82654456 2,9.80573916 2,12.993581 C2,18.7868296 6.50363911,23.5 12.0393401,23.5 C17.5750411,23.5 22.0786802,18.7868296 22.0786802,12.993581 C22.0786802,7.47211077 17.9875827,2.93167159 12.8110867,2.51789455"></path><rect id="Rectangle" fill="none" x="0" y="0" width="24" height="24"></rect></g></svg>'

    const uiContainerSelector = '#info-contents > ytd-video-primary-info-renderer > #container > h1'

    function addUI() {
        const target = $(uiContainerSelector);
        if (target) {
            target.append('<a href="' + url + '">' + icon + '</a>');
        } else {
            setTimeout(addUI(), 100)
        }
    }

    addUI();
});
```

## ページ読み込みを待って実行するために
Window の load イベントでトリガーすることでページ読み込みが終わったタイミングで実行できます。
はずなのですが、そのタイミングだと DOM を掴めないことがあります。起きたり起きなかったり、ログをはかせるデバッグコードを追加すると再現しなかったり、非同期あるあるな感じです。load イベントの仕様なのか YouTube の仕組みなのか。
動的に追加されているなら MutationObserver を使うのだけれども、どうもそうではなさそう……
いくつか YouTube にボタンを追加するスクリプトを見た感じでは setTimeout で適当に遅延実行したり setInterval で初期化を繰り返したりといった感じなので、それで動けばいいということなんでしょうがちょっと気持ち悪いですね。
[CentOS 8]チューニングプロファイルの設定（メモ）

#概要
CentOS（たぶんRHELも）はtunedデーモンがチューニングプロファイルを管理していて、プロファイルを選択することでシステムのパフォーマンスを最適化することができる。
tuned-admコマンドで設定、管理する。

#tuned-admコマンド

##設定されているプロファイルの確認

```
$ tuned-adm active
Current active profile: virtual-guest
```

##プロファイルの一覧表示

```
$ tuned-adm list
Available profiles:
- accelerator-performance     - Throughput performance based tuning with disabled higher latency STOP states
- balanced                    - General non-specialized tuned profile
- desktop                     - Optimize for the desktop use-case
- hpc-compute                 - Optimize for HPC compute workloads
- intel-sst                   - Configure for Intel Speed Select Base Frequency
- latency-performance         - Optimize for deterministic performance at the cost of increased power consumption
- network-latency             - Optimize for deterministic performance at the cost of increased power consumption, focused on low latency network performance
- network-throughput          - Optimize for streaming network throughput, generally only necessary on older CPUs or 40G+ networks
- powersave                   - Optimize for low power consumption
- throughput-performance      - Broadly applicable tuning that provides excellent performance across a variety of common server workloads
- virtual-guest               - Optimize for running inside a virtual guest
- virtual-host                - Optimize for running KVM guests
Current active profile: virtual-guest
```

##推奨プロファイルの表示

```
$ tuned-adm recommend
virtual-guest
```

## 自動設定
```
$ sudo tuned-adm auto_profile
$ tuned-adm active
Current active profile: virtual-guest
```


## プロファイルモードの確認
```
$ tuned-adm profile_mode
Profile selection mode: auto
```

##プロファイルの手動変更

```
$ sudo tuned-adm profile balanced
```

##無効化
```
$ sudo tuned-adm off
$ tuned-adm active
No current active profile.
```
ある日composer installが爆遅くなった

## ある日突然composer installがすごく遅くなった
```
$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)

// ここでフリーズ

```

- dockerコンテナ内でも外でもフリーズしている
- `composer install -vvv` → ゆっくり動いている(ほっとくと1時間くらいで完了することも)
- `composer require XX` → 入る（遅い気がする）

## 試したこと

- `composer diagnose` → 問題無し
- mac側のcomposerアンインストールしいて入れ直す→だめだった
    - docker内でも起こっていたので関係ない

## 調べて得られた情報

- メインサーバーでネットワークの問題があるかもしれない
- ↑が原因で必要なJSONをダウンロード出来なくなっている
- `composer clear-cache`でキャッシュを削除すればいい
    - これを実行しても私の場合はダメでした


## 効いた対応
composerが参照するリポジトリを以下のミラーサイトに変更。

https://packagist.jp/

以下を実行した

```
composer config -g repos.packagist composer https://packagist.jp
```
【Rails】docker-composeの速度を上げる方法

# 開発環境
・Docker: 19.03.8
・Docker-Compose: 1.25.5
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

# 前提

下記実装済み。

・[Dockerで環境構築する方法](https://qiita.com/drafts/d2bd360d769fe298f368)

# 原因

docker-compose実行時に、`temp`、`log`、`vendor`、`.git`等の余計なファイルをマウントしてしまっている。

# 解決方法

マウントする必要のないディレクトリのマウントを、別のvolumeで上書きします。

## `docker-compose.yml`を編集

```yml:docker-compose.yml
# 変更前
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

# 変更後
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_HOST_AUTH_METHOD=trust
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app:cached
      - /app/vendor
      - /app/tmp
      - /app/log
      - /app/.git
    ports:
      - '3000:3000'
    depends_on:
      - db
```
leafletを鍛える。その29

#概要

leafletを鍛えてみた。
geojsonを表示してみた。
turf使ってみた。
squaregrid使ってみた。

#参考にしたページ

https://qiita.com/ryo-a/items/4f651dbcf82537ac36f1

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/4892e0b5-df10-750c-0dd4-4f2de487a233.png)


#成果物

https://embed.plnkr.co/plunk/oGcukHyRKrowV4ol

以上。
[CentOS 8]プロセスの優先度設定（メモ）

#nice値
CentOS（RHELも同じだと思う）のプロセスの優先度はnice値で設定する。各プロセスのnice値は親プロセスの値を継承し、通常は「0」
nice値は-20から19までの40段階で設定され、値が小さいほど優先度が高くなる。

#設定と動作

負荷をかける。

```
$ sha1sum /dev/zero &
[1] 2155
$ ps u |grep sha1
user01      2155 94.8  0.0  16852  1772 pts/0    R    10:16   1:33 sha1sum /dev/zero
user01      2183  0.0  0.0  10280  1056 pts/0    S+   10:18   0:00 grep --color=auto sha1
```
100％近くまでCPUを消費している。

---

nice値「10」（優先度低）のインスタンスを起動する。

```
$ nice -n 10 sha1sum /dev/zero &
[2] 2184
$ ps -o pid,pcpu,nice,comm
    PID %CPU  NI COMMAND
   2016  0.0   0 bash
   2155 93.2   0 sha1sum
   2184  9.5  10 sha1sum
   2187  0.0   0 ps
```

nice値「0」のプロセスが優先されるので、nice値「10」のプロセスの負荷は上がらない。

---

PIDを指定してnice値を「10」から「-10」に変更する。

```
$ sudo renice -n -10 2184
2184 (process ID) 従来の優先順位は 10 で, 新しい優先順位は -10 です
```

しばらく待つと、nice値が低い（優先度が高い）プロセスの負荷が高くなる。

```
$ ps -o pid,pcpu,nice,comm
    PID %CPU  NI COMMAND
   2016  0.0   0 bash
   2155 37.0   0 sha1sum
   2184 74.3 -10 sha1sum
   2262  0.0   0 ps
```
Arctic Code Vault Contributor -ソースコード1000年保存計画-


# 概要
**Github**が**パブリックリポジトリ**のスナップショットを**1000年保存**することを計画し[北極圏にあるノルウェー スヴァールバル諸島の永久凍土に実際に保存](https://github.blog/2020-07-16-github-archive-program-the-journey-of-the-worlds-open-source-code-to-the-arctic/)したそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/34bdcf1d-8ce1-c120-2bf8-2077e7064470.png)

対象になったリポジトリの何百万人というContributorは**Arctic Code Vault Contributor**のバッジが付与されました。

# どんなかんじなのか。

コードはフィルムに記録（コードボルト）され、そのフィルムはノルウェーのスヴァールバル諸島に飛んだそう。
（地図の↓赤線あたり）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/b3bd9261-7adf-ebb4-1376-07f53c58fd0c.png)


> The code landed in Longyearbyen, a town of a few thousand people on Svalbard, where our boxes were met by a local logistics company and taken into intermediate secure storage overnight. The next morning, it traveled to the decommissioned coal mine set in the mountain, and then to a chamber deep inside hundreds of meters of permafrost, where the code now resides fulfilling their mission of preserving the world’s open source code for over 1,000 years.

- 保存場所
 - コードはロングイェールビーン(Longyearbyen)という町付近の閉山した炭鉱に運ばれ、そこから数百メートルの永久凍土にあるチャンバー内に格納されたそう。
- データ量
 - 21テラバイト
- 保存ストレージメディア
 - piqlFilmというフィルムを186リールぶんに相当

# アーカイブされたコード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/18f96738-b2b6-587d-6de9-f9a70f2beba3.png)


アクティブなパブリックリポジトリのスナップショット。コントリビューターは数百万人ぶん。

私のリポジトリもアーカイブしてもらえてました。なんだか嬉しいですね。
前もってわかっていれば1000年後に見られても恥ずかしくないようもうちょっと手直ししたんだけど:)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/0f0038c6-87a5-f2ed-476b-401918de99c5.png)

# まとめ
Githubさん、ありがとうございました。発想も実行力もさすがですね。
【Rails】credentials.ymlでシークレットキーなどを管理する

## はじめに
Rails 5系から登場したcredentialsについて備忘録的にまとめておきます。


## credentialsって？
秘密鍵などを置いておくファイルです。

このファイルの中身はmaster.keyによって暗号化されているため、正しいmaster.keyを知らない人は中身を見ることができません。

credentialsの中身は、master.keyの情報があれば他のファイルの中で変数として呼び出せるため、このファイルの中にAPIキーなどを入れておくと便利だったりします。

master.keyとcredentialsファイルは`rails new`したときに自動で作られ、master.keyはデフォルトで`.gitignore`に入っているので、githubから流出する心配もありません。

## 事前準備
今回はVScodeを使うことを前提としています。

まずはVScodeで`command + shift + P`でパレットを開いてください。
次に検索ボックスに`shell`と入力してshellをインストールしてください。

これでターミナルからcredentialsファイルの編集をVScodeでできるようになります。

## 設定の仕方
以下のコマンドでcredentialsファイルをVScodeで開きます。

```:ターミナル
$ EDITOR='code --wait' rails credentials:edit
```
デフォルトで最初の3行に例がコメントアウトで書いてあるので、それを真似すればOKです。

```yml:xxxxx.credentials.yml
aws:
  access_key_id: 123
  secret_access_key: 345q
```
1行目はどんなグループなのか、2, 3行目はidやアクセスキーなどを書いてます。
グループの中身はインデントすることが必要です。

一つだけではなく複数設定できるので試しに設定してみます。

```yml:xxxxx.credentials.yml
aws:
  access_key_id: 123
  secret_access_key: 345q

gmail:
  email: 'sample@gmail.com'
  password: 'sample1234'
```

## 保存
credentialsファイルを保存するにはVScodeのタブを閉じる必要があります。
閉じて正しく保存されるとターミナルで以下のようにメッセージが表示されます。
`New credentials encrypted and saved.`

## 呼び出し方
中身を呼び出すためには、rubyファイル内で以下のように書けばOKです。

```rb
Rails.application.credentials[:グループ名][:中身]
```
今回の例では以下のように使えます。

```rb
Rails.application.credentials[:aws][:access_key_id]
Rails.application.credentials[:gmail][:email]
```

ターミナルからコンソールで確認できるので、credentialsファイルを編集したときは確認すると良いです。`rails c`でコンソールを開いて確かめてみます。
<img width="431" alt="cb6ac75e17de6feb8c00047fc7b39d02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/4766373e-0996-c230-21cc-fce64de8e08a.png">
ちゃんと呼び出せていますね。

## 注意
チーム開発するときなどはmaster.keyを共有することで他の人もcredentialsの中身を見れたり編集したりできます。master.keyはメッセージアプリなんかで共有すると良いかと思います。

しかし、信頼している仲間であっても個人で持ってるawsのidとアクセスキーなんかはcredentialsでも共有すべきではないです。（クレジットカードの番号と認証コードを共有しているのと同じだと思ってください。）

共有すべき情報とそうではない情報は慎重に判断しましょう。
万が一裏切られてカイジのような展開になって後悔することのないように！笑
【S3】PythonをつかってS3でCRUDする【Python】

#アクセスするのに必要なキーを取得する
1.AWSのセキュリティ認証情報ページへ移動。
2.アクセス管理タグの「ユーザー」をクリック
3.「ユーザーを追加」を押して、ユーザー名を入力し、プログラムによるアクセスにチェック。
グループが無ければ作成し、AmazonS3FullAccessを選択する。
4.タグの追加はそのまま何も入力せずに次のステップへ
5.「ユーザー作成」で作成完了。CSVダウンロードやアクセスキーIDとシークレットアクセスキーのメモをしておく。

#boto3のインストール

```
pip install boto3
```

#CRUD
ここで利用されるaccesskey及びsecretkeyは、環境変数によって指定してください。
誰かに知られると大変なことになります。
regionは利用している地域名です。例）オハイオならus-east-2
##Create(ファイルの保存)

```python
def create_img_s3(path, img):#画像の保存
    s3 = boto3.client('s3', aws_access_key_id=accesskey, aws_secret_access_key=secretkey, region_name=region)
    img.thumbnail((900, 1200), Image.ANTIALIAS)
    out = BytesIO()
    img.save(out, "PNG")

    s3.put_object(Bucket=bucket_name, Key=path, Body=out.getvalue())

    url = "https://"+bucket_name+".s3-"+region+".amazonaws.com/"+path
    return url

def create_csv_s3(path, dataframe):#DataFrameからCSVに変換し、CSV保存
    out2 = StringIO()
    dataframe.to_csv(out2, encoding='utf_8_sig')
    s3 = boto3.client('s3', aws_access_key_id=accesskey, aws_secret_access_key=secretkey, region_name=region)
    s3.put_object(Bucket=bucket_name, Key=path, Body=out2.getvalue().encode("utf-8_sig"))

    url = "https://" + bucket_name + ".s3-" + region + ".amazonaws.com/" + path
    return url
```

##Read(ファイルの読み込み)

```python
def readFile_s3(path):
    url = "https://" + bucket_name + ".s3-" + region + ".amazonaws.com/" + path
    return url

def readDir_s3(dirpath):#特定のフォルダにあるデータをリストで取得する
    s3 = boto3.client('s3', aws_access_key_id=accesskey, aws_secret_access_key=secretkey, region_name=region)
    res = s3.list_objects_v2(Bucket=bucket_name, Prefix=dirpath, Delimiter='/')
    urls = []
    for data in res["Contents"]:
        data_url = data["Key"]
        if dirpath != data_url:
            url = "https://" + bucket_name + ".s3-" + region + ".amazonaws.com/" + data_url
            urls.append(url)

    return urls
```
【Windows10＋ESET】Railsアプリをlocalhost接続でiPhone実機確認する

#経緯
windows10で開発したRailsアプリをiPhoneで動作確認したいと思いました。
ところが、ESETセキュリティソフトとWindowsファイアウォールに阻まれて接続できず。
しばらく調べてみるものの「MacOS環境やAndroid実機」の記事ばかり。
知りたいのはそうじゃない！！WindowsとiPhone環境なんだ！
というとで、かなり読者を限定した記事ですが、同じ環境で悩んでいる方の助けになれればと思い方法を記します。

#実行環境
*Rails v6.0.3.2*
*OS：windows10 64bit*
*実機：iPhoneX*
*セキュリティソフト：eset Internet Security 13.1.21.0*

#ESETのフィルタリング設定変更
「ルール付き自動モード(デフォ)」➡ 「対話モード」にしていきます。
#####ESETソフトを立ち上げて「設定」をクリック
![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401086/98cdbd1a-08d0-ebd0-ed5c-e88e406ecae2.png)
#####「ネットワーク保護」をクリック
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401086/34e23baf-44a0-0d23-d66e-a527668e89d2.png)
#####「ネットワーク攻撃保護(IDS)」の項の歯車をクリックし「対話モード」に変更
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401086/d7b06e0f-a2dd-ebbf-b2a6-8e19c3f46e20.png)

#Railsサーバを立ち上げる
Railsアプリは指定が無いとポート3000番を解放しません。
オプション`-b 0.0.0.0`付きで起動し3000番を通します。

```Linux:
rails s -b 0.0.0.0
```

#iPhoneからローカルホストへアクセスする
####1.　ローカルホストPCのIPアドレスを確認
コマンドプロンプトを開いて打ち込むとIP構成がずらーっと表示されます。
「IPv4アドレス」が自分のPCのIPになります。

```Linux:
＞ipconfig
イーサネット アダプター イーサネット:
   接続固有の DNS サフィックス . . . . .:
   IPv6 アドレス . . . . . . . . . . . .: xxxx:xxxx:xxxx:x:xxxx:xxx:xxxx:xxxx
   一時 IPv6 アドレス. . . . . . . . . .: xxxx:xxxx:xxxx:x:xxxx:xxxx:xxxx:xxxx
   リンクローカル IPv6 アドレス. . . . .: xxxx::xxxx:xxx:xxxx:xxxxxxx
   IPv4 アドレス . . . . . . . . . . . .: 192.168.x.x
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   デフォルト ゲートウェイ . . . . . . .: xxxx::xxxx:xxxx:xxxx:xxxxxxx
                                          192.168.x.x
```
####2.　iPhoneからSafariでもChromeでもなんでも構わないのでブラウザを開く
先ほど調べたIPアドレスをアドレス欄に入力してアクセス。
この時、localhostのポートはデフォルトで`3000`なのでポート指定も忘れずに。例えば以下のようになります。
例:)192.168.x.x:3000

####3.　Rubyアプリからのアクセスを許可・保存する
「ルールを作成し、永久に記憶」にチェックを入れ「許可」をクリック
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401086/c20f4480-9da1-f50e-1efa-1b6c1ef3c76b.png)

####4.　ESETのフィルタリング設定変更
接続が正しくできたことを確認し、
一番初めにやった手順で「対話モード」➡ 「ルール付き自動モード(デフォ)」に戻します。
FreeWiFiのこと

行政が提供しているFreeWiFiにメール認証を使ったものがあります。その場合最初にページをブラウズしたときにリダイレクトされ、メールアドレスの入力ページになります。

このページで、メールアドレスを入力して、ボタンを押すとメールが送られます。

ノートパソコンを使っている場合など、そもそもインターネットへの疎通が無い状態でメールを送られても見れてません。

しかたがないので、スマホなどでメールを受信して認証のURLをクリックします。

クリックした後にリダイレクトしているケースもあるようです。このときにローカルのネットワークのサーバにリダイレクトされて、グローバルなスマホなどからアクセスできないことがあります。

なんか設計を間違えてると思うのですが、もし自分の管理化のIP以外から認証URLが叩かれた場合はグローバルなサイトにリダイレクトするべきです。

FreeWiFiはいろいろな方式があって、大変わかりにくいと思います。また無効な証明書のサイトで認証するようなケースもあり、ユーザーのセキュリティに対する意識を低下される原因になったりしないでしょうか。

追記：おそらく新しく設定されたアクセスポイントは、メールアドレスアドレス認証以降にグローバルなサイトにリダイレクトされているようです。FreeSpotはメールアドレスとMACアドレスの紐付けをデーターベースにいれて登録されたMACアドレスは認証をスルーするようです。

メール認証するのであれば認証後5分程度はインターネットリーチャブルにして、認証されない場合は該当のMACアドレスからのアクセスを落とすのがよいような気がする。
Firebaseで「Firebase App named '[DEFAULT]' already exists」というエラーがでた

認証にFirebase Authenticationを使ってみたのですが、

```
FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists 
```

何回かログインを繰り返していると、こんなエラーがコンソールに出力されて動かなくなります。
なんでしょう。
Firebaseのバージョンは`7.15.5`となっております。

↓Firebaseはこのような形で初期化しています。

```ts:firebase.ts
import firebase from "firebase/app";
import "firebase/firestore";
import "firebase/firebase-storage";
import "firebase/auth";

// firebaseコンソールから取得
const firebaseConfig = {
  apiKey: "xxxxx",
  authDomain: "sample.firebaseapp.com",
  databaseURL: "https://sample.firebaseio.com",
  projectId: "sample",
  storageBucket: "sample.appspot.com",
  messagingSenderId: "344403761159",
  appId: "yyyyy",
  measurementId: "zzzzz",
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);

export default firebase;

export const auth = firebase.auth();
```

firebase.initializeAppが複数回呼ばれていることが原因でしたので、

```ts:firebase.ts
// Initialize Firebase
if (firebase.apps.length === 0) {
  firebase.initializeApp(firebaseConfig);
}
```

初期化の部分をこのように修正いたしました。
無事コンソールにエラーメッセージは出なくなりました。

## 参考

>if (!firebase.apps.length) {
   firebase.initializeApp({});
}
https://stackoverflow.com/questions/43331011/firebase-app-named-default-already-exists-app-duplicate-app
配列っぽいオブジェクトを任意のキーの配列に変換

配列っぽいオブジェクト

```
{
  8347923: {
    name: 'foo',
    age: '43',
    sort_id: 4,
  },
  349: {
    name: 'bar',
    age: '24',
    sort_id: 2,
  },
  982123: {
    name: 'baz',
    age: '31',
    sort_id: 1,
  },
  23: {
    name: 'qux',
    age: '14',
    sort_id: 3,
  },
  ...
}
```

を`sort_id`順の配列に変換する。

```javascript
sortedArray(listObject) {
  const newArray = Object.entries(listObject).map(([key, value]) => ({
    ...value,
  }))
  return newArray.sort((a, b) => (a.sort_id > b.sort_id ? 1 : -1))
},
```
オブジェクトを適当に配列に変換して評価。
【AWS】【SSM】【Terraform】環境変数の管理

# DBのホスト名、ユーザー名、パスワードを環境変数で管理する場合

`AWS SSMパラメータストア`を用いて管理すると良い
`コンソールやaws-cli`から登録できる

```terminal:aws-cli
# 暗号化した値(--type SecureString)を保存するときに叩くコマンド
$ aws ssm put-parameter --name 'name' --value 'password' --type SecureString

# 暗号化した値を複合して(--with-decryption)参照するときに叩くコマンド
$ aws ssm get-parameter --output text --query Parameter.Value --name 'name' --with-decryption
=> password
```

# Terraformによるコード化を行う場合の注意点

暗号化するコードがソースコードに平文で書かれてしまうと暗号化する意味がなくなってしまうので、`Terraformではダミーの値を設定して、あとでaws-cliから更新する`戦略が有効。

```Terraform:ssm.tf
resource "aws_ssm_parameter" "db_password" {
  name = "/db/password"
  value = "password"
  type = "SecureString"
  description = "DB_PASSWORD"

  lifecycle {
    ignore_changes = [value] # 上書きして変更するので無視する
  }
}
```

```terminal:aws-cli
$ aws ssm put-parameter --name 'db/password' --type 'SecureString' --value 'overwrite-password' --overwrite
```

# 参考

[実践Terraform　AWSにおけるシステム設計とベストプラクティス](https://www.amazon.co.jp/dp/B07XT7LJLC/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
[Resource: aws_ssm_parameter](https://www.terraform.io/docs/providers/aws/r/ssm_parameter.html)
[AWS CLI Command Reference](https://docs.aws.amazon.com/cli/latest/reference/ssm/index.html)
React 学習の備忘録　初日

##初めてのReact

Udemyでフロントエンドの基礎的な講座でCSS(SCSS)
HTML
JS
を使ってある程度のページの作成方法の理解も進んだし、いよいよフロントエンドエンジニアデビュー？と思っていると、どうやら世間的にはフレームワークなりライブラリなりでのweb制作がメジャーのようです。なので、続けてReactの勉強をスタート。
VueとReact迷ったけど、ReactのがいろいろメジャーっぽいってことでReactを選びました。
###当方の技術レベル
HTML,CSS(SCSS)はMDNのリファレンスあればある程度のことはできるレベル、JSは講師の方のコードを読んで理解、要素やパーツの組み換え程度で一から書くのはまだまだです、

##今回の教材
[日本一わかりやすいReact入門（トラハックさん）](https://www.youtube.com/playlist?list=PLX8Rsrpnn3IWKz6H5ZEPWBY8AKWwb9qq7)

なんたって日本一わかりやすいですから期待大です。
入門#1は受講済み、かんたんにReactの概要の説明。

#学習メモ

入門#2よりいよいよ構文の説明など始まりました。
自身の備忘録としてメモって行きますね。

###JSXとは
-Facebookが開発
-React公式ドキュメントはほぼJSXで記述
##Reactでは業界標準

###JSXの基礎文法]
1.Reactパッケージのインストールが必須
`//.jsxファイル内の先頭で宣言
import React from "react"
`

2.HTMLとほぼ同じ記述(classはclassName)
```
const App = ()=>{
  return(
    <div id="hoge" className="fuga">
      <h1>Hello,World</h1>
    </div>
  );
};
```

3.{}内に変数や関数を埋め込める
```
const foo ="<h1>Hello,World</h1>"
const App =() => {
return(
<div id="hoge"className="fuga">
{foo}
</div>
);
```
4.変数名などはキャメルケースで記述

5.空要素は閉じる。
【技術書まとめ】りあクト！ TypeScript で極める現場の React 開発

## 読んだ動機

著者の前著を読み、とてもわかりやすかったので次は実際の開発の際に必要なCSS設計やテストなどを学ぶために手に取った。


## 第１章 デバッグをもっと簡単に

- Degugger for Chrome でのデバッグ方法について
- React Dev Tools について
- Redux Dev Tools について


## 第2章 コンポーネントのスタイル戦略

- CSS Modules の説明
    - ハイフンは使えない
    - `composes`はSassでの`@extends`
- CSS IN JS の歴史
- Emotion の説明
    - 親にJSX Pragma を使ったら子でも使う
    - フラグメントは使用不可
    - ESLint の逃げ設定

```
'@typescript-eslint/no-unused-vars': [ 'error', { varsIgnorePattern: '[Rr]eact' } ],
```


## 第３章 スタイルガイドを作る

- Storybook の説明


## 第４章 ユニットテストを書く

- テストを書く理由
    - 設計者の意図通りに機能が実現されているかの確認
    - 新規に追加した全ての処理に破綻がないかの確認
    - 既存の機能を破壊していないかの確認
    - モジュラリティの確保
- 実際にやること
    - ロジック部分のテスト
        - APIハンドラ
        - Redux-Saga
    - Storybook のスナップショットテスト
    - 正常系のE2Eテスト

- JestでAPI部分をテストする
- Redux Saga Test Plan の説明
- スナップショットテスト
    - Emotionを使っていればハッシュ値が変わるのでCSS変更もわかる
        - CSS in JS の導入理由


## 第５章 E2Eテストを自動化する

Cypress の使い方


## 第6章 プロフェッショナル React の流儀

- Reactの流儀
    1. **UI**をコンポーネントの階層構造に落とし込む
    2. Reactで**静的なバージョン**を作成する
    3. UI状態を表現する必要かつ十分な**state**を決定する
    4. state をどこに**配置**すべきなのかを明確にする
    5. **逆方向**のデータフローを追加する (Reduxを使うときは必要ない）
- 実際の手順
    - 4.まで作る
    - どれを Container にするか決める
        - 親Containerが子Containerを呼ぶのは避ける
    - Presentational Component を Storybook にスタイルガイドとして登録
    - そのContainer が発行するAction とその ActionCreator をつくる
    - Reducerをつくる
    - API通信が必要ならAPIハンドラとそのユニットテストをつくる
        - モック通信によるテスト
    - Actionに対応したSagaをつくる
    - ReduxDevToolsから生テキストのActionをDispatchして動作確認する
    - ReduxSagaTestPlan を使ってSaga とReducer のユニットテストを書く
    - 最後にContainer Component を作成する
    - 仕上げにCypress でE2Eテストを書く

- Store の構造はドメインモデル
    - ページごとだと重複値が出てきてしまうから
    - 正規化が可能なようにしておく

- セッション情報はLocal Storage に持たせる
    - Redux Persist

## 読了後のまとめ

前著のReactそのものの中身からさらに進んで、実際の開発現場の流れを知れたことが何よりよかった。
次作も読もうと思う。
太古の時代から幅を利かせている1,2,3...10のようなページネーションを撲滅したい

Webサイトのページネーションというと、どのようなUIを思い浮かべますか？

昔から様々なWebページで登場する下記のようなページネーションを思い浮かべた方が多いのではないでしょうか。
前へ・次へのリンクが両サイドにあり、あいだにページ番号のリンクがついているものです。
<img width="199" alt="スクリーンショット 2020-07-14 22.35.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/88e9b678-9e23-fcf2-c419-80ca12973147.png">

PCのGoogle検索も下記のようなページネーションですね。
<img width="303" alt="スクリーンショット 2020-07-14 22.33.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/ae5934fb-071b-744f-7599-b4410549d5c6.png">

あとページ数が多い場合は途中のページ番号を省略したり、途中から単位が変わったり・・・
<img width="606" alt="スクリーンショット 2020-07-14 23.00.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/7fd012bc-9559-276a-86bb-9adecc31604f.png">

# このタイプのページネーションについて考えてみる

このタイプのページネーションを見かけたら、ページ番号リンクのユースケースを考えてみてください。

数字のリンクはどういうときに使いたくなるんだろう？

1ページ目からいきなり5ページ目に飛びたいときってどういうときだろう？

ページ遷移するとしても順番に見るから「前へ」 / 「次へ」だけあればよさそうだよなー

・・・と、このようにぱっとメリットが思いつかないことが多くないですか？

『まあ、同じようなページネーションよく見かけるし明確なメリットは思いつかないけど使う人がいるかもしれない。ページ番号リンクつけといて損はないでしょ？』

いいえ、そんなことはありません。
利用者・実装者、どちらの観点でもデメリットがあります。

利用者の観点では、使わないものは画面に表示せずシンプルにしたほうが操作を迷ったり誤操作することがなくなり使いやすくなります。

実装者の観点では、このページネーションは用途が思い浮かばない割に実装コスト高いです。
また、ページネーションに限らずですが、どんなものでも実装するとそれ以降メンテナンスコストがかかるようになります。
「使わないものは実装しない」
これがコードを健全に保つ一番の方法です。

# ではどうするか？

ページ番号リンクのユースケースが思い浮かばないのであれば、素直に「前へ」 / 「次へ」だけにすれば良いと思います。

あとは無限スクロール（下までスクロールしたら次のページが自動で読み込まれて追加表示されるもの）という選択肢もあります。
SNSなどユーザーが連続して読みたい場合はページリンクをクリックする手間がなくなるので無限スクロールのほうが相性が良いです。
何でもかんでも無限スクロールにすればよいというわけではないですが候補に入れましょう。

もしどうしてもページ番号リンクが必要だと言われたときも、必要な理由を深堀りしてみましょう。
深堀りすると、本当に必要なのかが見えてきます。

『ページ番号リンクがあると現在のページがわかっていいよね』
もし現在のページを知りたいだけであれば、リンクにせずに現在のページ番号を表示するだけで良いです。

『あいうえお順に並んでいて、「は」行は５ページ目くらいから始まると覚えているから数字のリンクを使うんだよね』
頭文字で絞り込めるようにしてあげましょう。
ページ番号リンクを活用している理由の大半は絞り込み機能をつけることで解決できると思います。
（絞り込みできないから何ページ先くらいに出てくるか覚えちゃったパターン）

深堀りしていけばページ番号リンクが本当に必要なのか？検索機能など真に必要な機能がないから仕方なくページ番号リンクを使っているではないか？などが見えてきます。

なんでもかんでもページ番号リンクの実装は今後一切やりませんと言っているわけではありません。
必要な理由があるのであればページ番号リンクを実装すればいいと思います。
ただ、このタイプのページネーションは必要なユースケースが思いつかないのによくあるUIだからという理由だけで出てくることが多いと感じたのでこの記事を書きました。

ページネーションに限らずですが、よく見かけるという理由だけで置かれている無駄なUIを見かけたら必要な理由をきちんと洗い出し、本当に必要なものだけ実装するようにしましょう。
Macの中にあるiPhone/iPad/iPodのバックアップデータを削除する方法(Catalina)

長年Macを使っていたり、Macを買い替えて新しいMacに「移行アシスタント」（Time Machine）を使って自分のデータを移行したりしていると、昔使っていたが今は処分したiPhone/iPad/iPodのバックアップデータがMacの中に残ったままとなりディスク容量を圧迫しているかもしれません。

そこで、Mac内に保存されているiPhone/iPad/iPodのバックアップデータの確認方法と不要なバックアップデータを削除する方法をご紹介します。

※バックアップデータを削除する際は、くれぐれも慎重に！！

## macOS Mojave(10.14)まで

1. iTunesを起動し、メニュー「iTunes」をクリックし「環境設定...」を選択します。
2. ダイアログが出現するので、上部にある「デバイス」をクリックします。
3. バックアップが保存されているiPhone/iPad/iPodが表示されます。
4. 不要なバックアップがあればそれを選択して「バックアップの削除」ボタンを押します。


## macOS Catalina(10.15)

1. 画面左上にある「アップル」のメニューをクリックし「このMacについて」を選択します。
2. ダイアログが出現するので、上部にある「ストレージ」をクリックします。
3. ストレージの情報が表示されますので、「管理...」ボタンをクリックします。
4. 新しいダイアログが表示されますので左側にある「iOSファイル」をクリックします。
5. 少し待つとバックアップが保存されているiPhone/iPad/iPodが表示されます。
6. 不要なバックアップがあればそれを選択して右下にある「削除...」ボタンを押します。


## 手元にiPhone/iPad/iPodがある場合

手元にiPhone/iPad/iPodがある場合はAppleが提供している以下の情報も参考にしてみてください。
- [Mac または Windows パソコンで バックアップを削除またはコピーする](https://support.apple.com/ja-jp/HT204215#deleteiTunes)
ディクショナリからタプルの配列を作成する

# はじめに
- Swift には、連想配列的なデータ構造としてディクショナリがあります
- ディクショナリはデータの順序を保証しないので、そのままではテーブルビューやコレクションビューのデータソースとして利用しにくいです
- その場合は、タプルの配列に変換すると上手く行きます

# 検証環境
- Xcode 11.5
- Swift 5.2

# 利用する機能
## sorted(by:)
- ディクショナリのメソッド
- 引数に渡した関数 `by` がソート条件
    - 関数 `by` の引数
        - 2 つのタプル（それぞれディクショナリの n 番目の要素と n + 1 番目の要素に対応）
    - 関数 `by` の戻り値
        - `Bool`（`false` なら並び替え）
- 戻り値は `[(key: ディクショナリの key の型, value: ディクショナリの value の型)]`
    - つまり、ディクショナリとほぼ同じ構造を持った「タプルの配列」

# コード例
- 以下はディクショナリ `[String: Int]` からタプルの配列 `[(key: String, value: Int)]` に変換する例です

```swift:SortedDictionary.playground
import Foundation

var scores: [String: Int] = [
    "Steve Yamada": 34,
    "Jeff Takeshita": 87,
    "Mickey Yoshida": 100,
    "Charly Kinoshita": 53,
    "Anna Saito": 19,
    "Robert Suzuki": 97,
    "Erick Kawakami": 32,
    "John Miyabe": 64,
    "Gregory Goto": 76
]

print("""

    Ascending by key
    ========================
    """)
var sortedByNameAsc: [(key: String, value: Int)] = scores.sorted { $0.key < $1.key }
sortedByNameAsc.forEach { print("\($0.key): \($0.value)") }

print("""

    Descending by key
    ========================
    """)
var sortedByNameDesc: [(key: String, value: Int)] = scores.sorted { $0.key > $1.key }
sortedByNameDesc.forEach { print("\($0.key): \($0.value)") }

print("""

    Ascending by value
    ========================
    """)
var sortedByScoreAsc: [(key: String, value: Int)] = scores.sorted { $0.value < $1.value }
sortedByScoreAsc.forEach { print("\($0.value): \($0.key)") }

print("""

    Descending by value
    ========================
    """)
var sortedByScoreDesc: [(key: String, value: Int)] = scores.sorted { $0.value > $1.value }
sortedByScoreDesc.forEach { print("\($0.value): \($0.key)") }
```

```zsh:出力結果

Ascending by key
========================
Anna Saito: 19
Charly Kinoshita: 53
Erick Kawakami: 32
Gregory Goto: 76
Jeff Takeshita: 87
John Miyabe: 64
Mickey Yoshida: 100
Robert Suzuki: 97
Steve Yamada: 34

Descending by key
========================
Steve Yamada: 34
Robert Suzuki: 97
Mickey Yoshida: 100
John Miyabe: 64
Jeff Takeshita: 87
Gregory Goto: 76
Erick Kawakami: 32
Charly Kinoshita: 53
Anna Saito: 19

Ascending by value
========================
19: Anna Saito
32: Erick Kawakami
34: Steve Yamada
53: Charly Kinoshita
64: John Miyabe
76: Gregory Goto
87: Jeff Takeshita
97: Robert Suzuki
100: Mickey Yoshida

Descending by value
========================
100: Mickey Yoshida
97: Robert Suzuki
87: Jeff Takeshita
76: Gregory Goto
64: John Miyabe
53: Charly Kinoshita
34: Steve Yamada
32: Erick Kawakami
19: Anna Saito
```
# まとめ
- 状況に応じたデータの形式変換をする方法を押さえておくと、いろいろ応用ができそうですね
- 今回のサンプルは [GitHub: aokiplayer/swift-sandbox/SortedDictionary](https://github.com/aokiplayer/swift-sandbox/tree/master/SortedDictionary) に置きました
- なお、この記事は[私のブログ記事](https://yagamo-style.com/posts/dictionary-to-array/)からの転載です
Vue(Nuxt.js)でEnterで送信、Shift+Enterで改行の機能を実装する【textarea,input】

Vue(Nuxt.js)で、textarea・inputで入力したものをEnterで送信、Shift+Enterで改行する機能を実装する方法です。
![Nuxt(vue)enter.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/24c22bbc-e5a2-9a24-5a87-7d712bba92b7.gif)

チャット機能を実装する時などに便利かと思います。

## Vue(Nuxt.js)でEnterで送信、Shift+Enterで改行の機能を実装

```vue
<template>
  <div>
    <p>送信:</p>
    <p>{{ sendMessage }}</p>
    <textarea
      v-model="message" 
      @keydown.enter.exact="keyDownEnter"  <!--enterをkeydownした時のイベント-->
      @keyup.enter.exact="keyUpEnter"  <!--enterをkeyupした時のイベント-->
      @keydown.enter.shift="keyEnterShift" <!--enterとshiftをkeydownした時のイベント-->
    ></textarea>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  data() {
    return {
      message: '',
      sendMessage: ''
    }
  },
  methods: {
    keyDownEnter(e: any) {
      e.preventDefault() //改行を無効化
    },
    keyUpEnter(e: any) {
      e.preventDefault() // 改行を無効化
      console.log(e.keyCode) // 13
      this.send() //送信
    },
    keyEnterShift(e: any) {
      console.log('shift,enter')
    },
    send() {
      this.sendMessage = this.message
      this.message = ''
    }
  }
})
</script>
```

`@keydown.enter.exact`
`@keyup.enter.exact`
のイベントに関しては、e.preventDefault()をすることでEnterで改行するのを防止しています。
また、`.exact`を連結させるとことで、Enterキーのみを押した時にイベントが発生するようにしています。

## 日本語変換時に送信しないように処理を追加

上記のコードでは、Enterで送信、Shift+Enterで改行することはできますが、日本語変換の確定をした時も送信されてしまいます。
日本語変換の確定時のEnterでは、送信しないように処理を追加します。

```vue
<template>
  <div>
    <p>送信:</p>
    <p>{{ sendMessage }}</p>
    <textarea
      v-model="message"
      @keydown.enter.exact="keyDownEnter"
      @keyup.enter.exact="keyUpEnter"
      @keydown.enter.shift="keyEnterShift"
    ></textarea>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  data() {
    return {
      message: '',
      sendMessage: '',
      keyDownCode: 0 //追加
    }
  },
  methods: {
    keyDownEnter(e: any) {
      console.log(e.keyCode)
      this.keyDownCode = e.keyCode //enterを押した時のkeycodeを記録
      e.preventDefault()
    },
    keyUpEnter(e: any) {
      if (this.keyDownCode === 229) { //229コードの場合は処理をストップ
        return
      }
      e.preventDefault()
      console.log(e.keyCode)
      this.send()
    },
    keyEnterShift(e: any) {
      console.log('shift,enter')
    },
    send() {
      this.sendMessage = this.message
      this.message = ''
    }
  }
})
</script>

```
EnterキーのkeyCodeは`13`です。しかし、日本語変換確定時のEnterキーのkeyCodeは`229`になります。
`if (this.keyDownCode === 229)`で日本語確定時は処理を止めています。
これで日本語変換時には、送信しないようにする機能を追加できます。
leafletを鍛える。その28

#概要

leafletを鍛えてみた。
geojsonを表示してみた。
turf使ってみた。

#参考にしたページ

https://qiita.com/ryo-a/items/4f651dbcf82537ac36f1

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/71e5f25a-5a0e-65c6-7a3d-f9fdda0b2a0f.png)

#成果物

https://embed.plnkr.co/plunk/mR7Mk75cNeSfkfn3

以上。
WordPressブロックにカスタムスタイルを追加するregister_block_style ジェネレーター

![blockstyle.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31643/f15abc3d-f96e-3d4b-187a-a2876f473167.gif)

WordPressでは、様々なブロック(投稿編集のための小さな塊)が用意されています。見た目の設定もGUIでできるようになっています。

![core-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31643/27921da7-d0f1-a432-335a-3e7290544893.png)

↑の画像では、スタイル設定が、デフォルト、角丸、影付き、と3つあります。このうち「影付き」は、私がカスタマイズして追加したものです。

カスタムでスタイル設定を追加するコードは↓です。

```PHP
register_block_style(
    'core/image', // ブロック名
    [
        'name'         => 'shadow', // スタイルで付けるクラスに使う名前
        'label'        => '影付き',
        'inline_style' => '.is-style-shadow {
            box-shadow: 10px 5px 5px black;
        }', // 追加するCSS
    ]
);
```

## ブロック名の指定が面倒
上記のコードを見ると、コード自体はそれほど複雑ではありません。しかし、ブロック名を探して入力する、という手間がかかります。

もちろん、[グーテンベルクのブロック一覧](https://php4wordpress.calculator.jp/gutenberg/blocklist/)を見て入力してもよいのですが、手間がかかりますね。そこでregister_block_style ジェネレーターを作りました。

→[register_block_style ジェネレーター](https://php4wordpress.calculator.jp/gutenberg/add-style/#register_block_style-%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF)

こちらのページでは、カスタマイズしたいブロックをプルダウンで選択する &rarr; ブロック名を設定したコードを自動生成する、という仕組みになっています。
円を、ドラッグするコード

```
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseEvent;
import java.awt.Point;
import java.awt.Color;

/*
<applet code="Circle_003.class" width="600" height="400">
</applet>
*/

public class Circle_003 extends Applet implements MouseMotionListener{
  int x, y;
  int X, Y;
  boolean flag;
  int width;
  int width_X;
  int width_Y;

  public void init(){
    x = 100;
    y = 100;
    X = 100;
    Y = 100;
    width = 50;
    width_X = 600;
    width_Y = 400;


    addMouseMotionListener(this);
  }

  public void update(Graphics g){
    paint(g);
  }

  public void paint(Graphics g){
      g.setColor(Color.gray);
      g.fillRect(0, 0, width_X, width_Y);
      g.setColor(Color.blue);
      g.fillOval(x - width, y - width, width * 2, width * 2);
      X = x;
      Y = y;
  }

  public void mouseDragged(MouseEvent e){
    Point point = e.getPoint();
    x = point.x;
    y = point.y;
    if (flag){
      repaint();
    }
  }

  public void mouseMoved(MouseEvent e){
    Point point = e.getPoint();
    x = point.x;
    y = point.y;

    if(((x >= X - width * 2) & (x < X + width * 2)) & ((y >= Y - width * 2) & (y < Y + width * 2))){
      flag = true;
    }
    else flag = false;
  }
}
```
基礎Webアプリケーション作成　Servlet/JSP（ログイン機能）

#はじめに
ServletとJSPで掲示板のような投稿ができるようなWEBアプリケーションを作成します。
まずはJDBC,DB,Mysqlは使用せずに作成していきます。

##実行環境
- Eclipse4.16 
- Tomcat9
- Java11

#機能について
今回実装する機能について考えます。
掲示板のようなアプリを作成するので以下のような機能を作成します。

- 1.ログイン機能
- 2.ログアウト機能
- 3.投稿機能
- 4.投稿閲覧機能

今回はSevletとJSPを使用してWebアプリケーションの作成に慣れることを目標にするため簡単な構成にします。

#ログイン機能作成
この記事ではログイン機能を作成します。

##1. ユーザーのModel作成
ログイン機能にはユーザーが必要なのでユーザーモデルを作成します。
作成するユーザーモデルは名前とパスワードの二つの情報を持っていることとします。

```java:User.java
package model;

import java.io.Serializable;

public class User implements Serializable {

	private String name;
	private String password;

        public User() {}

	public User(String name,String password) {
		this.name = name;
		this.password = password;
	}

	public String getName(){     // 1. ユーザー名取得
		return this.name;
	}

	public String getPassword(){   // 2. パスワード取得
		return this.password;
	}
}

```
メンバ変数name(ユーザー名)とpassword(パスワード)は他クラスから参照できないようにアクセス修飾子はprivateにします。
またコンストラクタでセットした値を取得するための1と2のメソッドを作成します。

##2.トップページのView作成
モデルは作成したのでユーザーがログインするためのビューをJSPで作成します。
まずは簡単なビューを作成します。

```jsp:top-page.jsp
<form action="./login" method="post">
  <div>
    <label>ユーザー名</label>
    <input type="text" name="userName">
  </div>
  <div>
    <label>パスワード</label>
    <input type="text" name="userPassword">
  </div>
  <div>
    <input type="submit" value="登録">
  </div>
</form>
```
##3.ログインに関する処理を行うModel作成

```java:LoginProcess.java
package model;

public class LoginProcess {
	public boolean execute(User user) {
		if (user.getPassword().equals("hoge")) {
			return true;
		}
		return false;
	}
}
```
登録実行されたパスワードが`hoge`だった場合trueを返すログイン処理。

##4.ログインに関するリクエストを処理するコントローラー作成

```java:login.java
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");  // 1
		String name = request.getParameter("userName");
		String password = request.getParameter("userPassword");
		User user = new User(name,password);  // 2

		LoginProcess loginProcess = new LoginProcess();
		boolean isLogin = loginProcess.isLogin(user);  // 3

		if(isLogin) {
			request.getSession().setAttribute("loginUser",user);  // 4
		}

		request.getRequestDispatcher("/WEB-INF/view/login-result.jsp").forward(request, response);  // 5
	}

```

1. リクエストパラメータを取得
2. 取得したパラメータをUserクラスのnameとpasswordをセットする
3. パスワードが正しいかの処理をし真偽値を初期化
4. セッションスコープにUserクラスの情報をセット
5. ログイン結果を表すビュー`login-result.jsp`にフォワード

##5.ログイン結果を表すビューの作成
セッションスコープで指定した`loginUser`をもとにjspを作成します。
※今回はJSTLを使用します。

```jsp:login-result.jsp
<c:choose>
  <c:when test="${loginUser != null}">  // 1
    <p>ログインが完了しました。</p>
    <p>こんにちは!<c:out value="${loginUser.name}"/>さん</p> //2
  </c:when>
  <c:otherwise>  // 3
    <p>ログインに失敗しました。</p>
    <p>もう一度ログインをやり直してください。</p>
    <a href="./login">ユーザーログイン</a>  //4
  </c:otherwise>
</c:choose>
```

1. `loginUser`がnullではない場合（パスワードの入力値が"hoge"である場合）
2. `loginUser.name`でUserクラスのnameを出力
3. 1以外の条件の場合
4. ユーザー登録画面のリンク

##6.実行
ユーザーログイン画面でパスワードに`hoge`かそれ以外かを入力してログイン結果がしっかり表示されれが成功です。

#最後に
次回は投稿画面でのログインしているかしていないかの確認やしていない場合の処理について行います。
h1 - h6 タグに自動的に番号が付くようにする

## 概要

html の `h` タグを使用したとき自動的に見出し番号が付くようにしたい。
とりあえず `h6` まで。

## コード

==> [jsfiddle](http://jsfiddle.net/Sashida/degu27kj/30/)

* `class="num"` が付いている `h1 - h6` タグは自動番号

## 参考

* [StarckOverflow](https://stackoverflow.com/questions/10340276/how-to-add-section-numbers-1-2-3-4-1-automatically-using-css)
競技プログラミング練習記 No.49【ABC113練習】

初回 -> [はじめに](https://qiita.com/easychoco/items/a9ae28aca97cfe47091f)

[ABC113](https://atcoder.jp/contests/abc113)を解きました。
3完です！
D問題は難しくて解けていません。

|問題|時間|アルゴリズム|実行時間
|:-:|:-:|:-:|:-:|
| A |  1min |-| 8ms|
| B |  6min |-| 7ms|
| C | 20min |座標圧縮| 155ms|


# まとめ
先にまとめを載せます。これ自体は最後に書いてます。

C問題は座標圧縮です。解いた後に気付きましたw
入力値をソートする必要があるけれど出力時に入力の順番を使う場合は、
「ソート後の順番」→「入力の順番」に変換する用の変数を用意します。

これはchokudaiさんが記事で紹介している問題ですね。
→[AtCoder（競技プログラミング）の色・ランクと実力評価、問題例](http://chokudai.hatenablog.com/entry/2019/02/11/155904)
60minで解きましょうと紹介されているので、それより早く解けてうれしいです。

D問題むずかしかった。
あみだくじかー。あみだくじは実は代数学(群論)なんだよな。
「数学ガール ガロア理論」で勉強したからけっこう簡単に解けるだろうな。
って思っていたら全く解けませんでした。
動的計画法でした。代数学を使う解法はもっと数学的に複雑な問題を解く場合です。
問題の複雑さによって適切なツールを選択するスキルを身に着けたい。。。

## A - Discount Fare

```c++
  int x, y;
  cin >> x >> y;
  cout << x + y / 2;
```
半額になるバスの運賃は2番目の入力でもらえるので、1番目の入力と2番目入力の半分を足したものが答えになります。

## B - Palace

``` c++
  int n, t, a, h;
  cin >> n >> t >> a;
  int ans = 0;
  double ans_t = 1e9;
  for(int i = 0; i < n; ++i)
  {
    cin >> h;
    double temp = abs(a - (t - h * 0.006));
    if (temp < ans_t)
    {
      ans_t = temp;
      ans = i + 1;
    }
  }
  cout << ans;
```
「各地点の平均気温」は入力をもらった時にわかりますね。
（過去や未来の入力値に影響しません。）
そのため、入力をもらうたびに逐次処理しています。
`abs(a - (t - h * 0.006))`で「平均気温との差」がわかるので、これが最小になるものが答えです。
整数ではなく実数なので型に注意です。


## C - ID

``` c++
using P = pair<ll, ll>;

  ll n, m, p, y;
  cin >> n >> m;
  vector<P> a(m);
  map<P, int> ump;
  map<int, map<int, P> > mp;
  for(int i = 0; i < m; ++i)
  {
    cin >> p >> y;
    P ind = P(p, y);
    a[i] = ind;
    ump[ind] = i;
    mp[p][y] = ind;
  }

  for(const auto& ip : mp)
  {
    int ind = 1;
    for(const auto& im : ip.second)
    {
      a[ump[im.second]].second = ind;
      ind++;
    }
  }

  cout << setfill('0') << right;
  for(const auto& city : a)
  {
    cout << setw(6) << city.first << setw(6) << city.second << endl;
  }
```
[座標圧縮](https://www.google.com/search?ei=VLUTX6qXKJei-QadhYKgCA&q=%E5%BA%A7%E6%A8%99%E5%9C%A7%E7%B8%AE&oq=%E5%BA%A7%E6%A8%99%E5%9C%A7%E7%B8%AE)という処理をする問題です。
与えられた数値を、大小関係を保ったまま小さい数字に直します。
`[10,5,7,3,2] -> [5,3,4,2,1]`というような操作になります。

この問題は、都市番号ごとに分けた後、誕生年でソートします。
ソート後の順番を使ってIDを生成し、元の入力順に出力します。
この「ソート後の順番」→「元の入力順」の変換が複雑でした。
`std::map`は自動でソートをしてくれることを利用しました。

`map[県番号][誕生年] = 「入力のPair」` となる`std::map`と、
`map[入力のPair] = 「入力順」` となる変換用の`std::map`を用意すると、この問題は解けます。
`tuple`を使うと変数を減らせるのですが、慣れていないので使いませんでした。





以上です。ありがとうございました。
ゼロから始めるLeetCode Day92 「4. Median of Two Sorted Arrays」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day91「153. Find Minimum in Rotated Sorted Array」](https://qiita.com/KueharX/items/5b88fb023d7be19e778b)

[Twitter](https://twitter.com/kueharx)やってます。

**[技術ブログ](https://kueharx.blogspot.com/)始めました！！**
技術はLeetCode、Django、Nuxt、あたりについて書くと思います。**こちらの方が更新は早いので**、よければブクマよろしくお願いいたします！


## お知らせ
Day 100でQiitaでの投稿はひとまず区切りを付けようかと思います。
タグの記事が僕の記事ばかりになってしまうのもいかがなものかと思いましたし、他に有益な情報を提供している方の邪魔になってしまうこともあると考えたので、こうすることにしました。
至らない部分は多々ありましたが、今までお付き合い頂きありがとうございました。

問題を解いて記事を書く、というのは上記の個人ブログで続けるつもりですし、興味ある方はたまにそちらを覗いていただけると嬉しいです。
Twitterの方のアカウントはほとんど更新通知用と化しているので、Leetcodeを解く記事について気になる方はそちらも合わせてフォローいただくと良いかもしれません。


# 問題
[4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/)
難易度はHard。

問題としては、サイズ`m`と`n`の2つのソートされた配列`nums1`と`nums2`がある。2つの並べ替え配列の中央値を求めよ。
なお、全体の実行時間の複雑さは，`O(log (m+n))`でなければならず、`nums1`と`nums2`はどちらも空ではないと仮定してもよい。

>Example 1:

>nums1 = [1, 3]
nums2 = [2]
The median is 2.0

>Example 2:

>nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

# 解法

`O(log(m+n))`である、ということは二分探索が使えますね。
ただ、難易度がHardということで、扱うリストが二つになっています。
これで書くコードの量が増えますし、書く量が増えるということは凡ミスも増える可能性が高くなります。
そして、二つとも同じ大きさのリストとは限らないのでその点もきちんと頭に入れておきましょう。

```python
class Solution:
    def obtain_kth_num(self, nums1, nums2, k):
        nums1_len, nums2_len = len(nums1), len(nums2)
        nums1 = [-2**31] + nums1 + [2**31-1]
        nums2 = [-2**31] + nums2 + [2**31-1]
        left, right = max(0, k-nums2_len), min(nums1_len, k)
        while left <= right:
            i = (left+right) // 2
            j = k - i
            if nums1[i] > nums2[j+1]:
                right = i - 1
            elif nums2[j] > nums1[i+1]:
                left = i + 1
            else:
                return max(nums1[i], nums2[j])
            
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        nums_len = len(nums1) + len(nums2)
        mid = self.obtain_kth_num(nums1, nums2, (nums_len+1)//2)
        if nums_len % 2 == 0:
            mid = (mid+self.obtain_kth_num(nums1, nums2, (nums_len+1)//2+1)) / 2.0
        return mid
# Runtime: 116 ms, faster than 35.51% of Python3 online submissions for Median of Two Sorted Arrays.
# Memory Usage: 13.9 MB, less than 92.38% of Python3 online submissions for Median of Two Sorted Arrays.
```

DFSなどと同様に別に関数を実装してからメインで呼び出す、という形式を取りました。
`-2**31`や`2**31-1`というのはPython3にはlong型が存在しないためこういった方式を取っている、というのを以前も解説した気がします。

`obtain_kth_num`関数は与えられた`nums1`と`num2`を入力として受け取り，配列のk番目に小さい数を返すための関数です。

なお、二分探索をする上で根底となる考え方は[この動画](https://www.youtube.com/watch?v=LPFhl65R7ww&feature=emb_title)を参考にしました。
こういう動画を作れるくらい強くなりたい・・・

では今回はここまで。お疲れ様でした。
Rails 6のAssetsログを抑制する

# はじめに
Rails 6にしてからdevelopment環境で大量のAssetsログが出るようになった。Rails 5の時と基本的に同じ設定なのに、どうしてだろうと思って調べたことを記録しておく。

# 1. Quiet assets in Rails 5
Rails 5にはconfig.assets.quietというMonkey Patchがあった。これをTrueにしておくとAssets系のログが抑制される。Rails 6でもTrueにしたが、まだ大量にログが出ていた。

```ruby:config/environments/development.rb
Rails.application.configure do
...
  # Suppress logger output for asset requests.
  config.assets.quiet = true
...
end
```

# 2. `config.assets.debug` を試す
Rails 5.2では`config.assets.debug=true` でも、自分に関係ないログはあまり出なかったのだが、Rails 6では大量に出るのでこれをFalseにしてみた。

```ruby:config/environments/development.rb
Rails.application.configure do
...
  # Debug mode disables concatenation and preprocessing of assets.
  # This option may cause significant delays in view rendering with a large
  # number of complex assets.
  config.assets.debug = false
...
end
```

# 3. 結果
大量のログは出なくなり、自分のアプリの app/assets に関係するログは出ているので、ログが見やすくなった。こんなに簡単ならもっと早くやれば良かったと思いました。

### 参考記事
[Quiet assets in Rails 5](https://rossta.net/blog/quiet-assets-in-rails-5.html)
options has an unknown property 'prependData'. These properties are valid と表示される

``` console:node
options has an unknown property 'prependData'. These properties are valid
```
と表示されてvueの実行ができない

###解決策
[[Bug Report] release 1.0.1 Sass Loader does not match the API schema](https://github.com/vuetifyjs/vue-cli-plugins/issues/119)

上記のリンクを参考に、
`npm install sass-loader`
とした場所で、
`npm -i -D sass-loader@7.3.1`
とすると、解決する
[shellscript]一定周期ごとに同じコマンドを実行続ける

### この記事で紹介するもの
一定周期ごとに任意のコマンドを実行して、その実行結果を標準出力するスクリプトです。

kshで書いた為bashで動くかわかりません。
(たぶん動かない)

### どんな場面で使う？私が使った具体例
・システム環境内でNTP(調時するためのデーモン)でDBサーバ、APサーバ等の時刻が同期されるのを目視確認するのに重宝しました。

### コード
```shell:date_every_second.sh
#!/usr/bin/ksh

count=0

while true
do

echo '==============='
echo "DATE: `date`"

# このあたりで好きなコマンドを実行する

let "count=count + 1"
echo "count: ${count}"

sleep 1

done
```

・起動する時にパイプでteeコマンドを付けたらログ取りもできます。

```shell:標準出力をログ取りしたいときのコマンド
./date_every_second.sh | tee <ログ名>
```

以下はコマンドの出力例です。

```shell:出力例
$ ./date_every_second.sh
===============
DATE: 2020年  7月 20日 月曜日 02:50:19 JST
count: 1
===============
DATE: 2020年  7月 20日 月曜日 02:50:20 JST
count: 2
===============
DATE: 2020年  7月 20日 月曜日 02:50:21 JST
count: 3
```
-----
ソースコードはこちらにもあります。
[https://github.com/Massas/shellscript](https://github.com/Massas/shellscript)
<img width="1022" alt="github_profile#1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580452/ebd1a93d-aeef-509b-ea10-3c60b90e76f1.png">

---
### そのほか
GitHub: [https://github.com/Massas](https://github.com/Massas)
Twitter: kjm@DBサーバー [https://twitter.com/kj53192539](https://twitter.com/kj53192539)