OmniAICreator/Qiita-1.07M huggingface dataset:
python3 競技プログラミング小技集

# はじめに

paiza取り組んでます。
自分用のメモです。
これからも追記していきます。

2020/11/12 追記
paizaは答えがないのでCodewarsをやってます。

[Sign in \| Codewars](https://www.codewars.com/dashboard)

# 競プロ用 技メモ

## 入力の配列格納処理

```python:
# 入力を分割して配列に格納
x, y, z = [int(x) for x in input_line.rstrip().split()]
print(x + y + z)

# 入力を分割せず配列に格納
tem = [int(n) for n in　input_line.replace(' ', '')]

# 複数行の入力
input_ = [input() for i in range(len_)]

# 辞書型に格納
input_ = int(input())
dic = {input_[i].split()[0]: int(input_[i].split()[1]) for i in range(len(input_))}
```

## 配列のソート

```python:
# reverse=Trueで降順
nums = sorted(input_line, reverse=True)

# listの逆順
# num = [1, 2, 3, 4]
print(num[::-1])
# [4, 3, 2, 1]
```

## for文

```python:
# カウンタと要素でループ
for i, s in enumerate(input):
```

### for文のelse

- elseの中はfor文から抜ける時に実行される
- 途中でbreakした場合は実行されない

```python:
for i in range(3):
    if i == 3:
        break 
else:
    print('a')
```

### 辞書型のfor文

```python:
# {'1': 0, '2': 0, 'neutral': 100}
for key, value in elect.items(), #keys(), values()
```

## リスト内包表記を使ったあれこれ

### 特定のデータの条件をカウント

```python:
data = range(1, 10)
count = len([x for x in data if x % 3 == 0]) # 3の倍数をカウント
print(count)
```

### 二重のリストをフラット

```python:
data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(data)

flat = [flatten for inner in data for flatten in inner]
print(flat)
```

```sh:実行
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```

## リスト回りの操作

### 数値を桁ごと格納

12345 -> [1,2,3,4,5]
[1,2,3,4,5] -> 12345

```python:
# 12345 -> [1,2,3,4,5]
n = [int(x) for x in list(str(num))]

# [1,2,3,4,5] -> 12345
num = int(''.join([str(x) for x in n]))

# 135687 -> 876531
n = int("".join(sorted(str(num), reverse=True)))
```

### 末尾指定

```python:
a = [1, 2, 3, 4, 5]
print(a[len(a) - 1])    # よくある末尾の指定
print(a[-1])            # マイナス値のインデックスを使った末尾の指定
print(a[-2])            # 末尾から2番目
```

```sh:実行
5
5
4
```

### スライス

```python:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[3:7])
print(a[3:])    # 終点の省略
print(a[:7])    # 始点の省略
```

```python:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[2:8:2])     
# 2番目以上8番目未満を2step（1つ飛ばし）で取得
```

## 文字列定数

```python:
print(string.ascii_lowercase)
print(string.ascii_uppercase)
print(string.ascii_letters)
print(string.digits)
print(string.hexdigits)
```

```sh:実行
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
0123456789abcdefABCDEF
```

## 辞書型のあれこれ

### アルファベットと数値の対応表

```python:
lis = {s: str(i+1) for i, s in enumerate(list(abc))}
# {'a':1, 'b':2, 'c':3, …… }
```


## 小技

### 文字列の判定

```python:
# アルファベット判定
if str.isalpha()

# 数値判定
if num.isdigit()
```

### 割り算のエラー処理
ループで割り算してたらキーが存在しないときエラー対処
try-exceptを使えば無理やりできる

```python:
count = []
for k in b_dic.keys():
	try:
		temp_count = a_dic[k] / b_dic[k]
                # math.floor:小数点以下切り捨て
		count.append(math.floor(temp_count)) 
	except KeyError:
		count.append(0)
```


# 参考
Pythonで競プロやるときによく書くコードをまとめてみた
(https://qiita.com/y-tsutsu/items/aa7e8e809d6ac167d6a1)
Git 自分用メモ帳



リモートのリポジトリの名前は、クローンした時点で自動的にoriginという名前になっている

pullを実行すると、リモートリポジトリの内容のマージが自動的に行われてしまう。しかし、単にリモートリポジトリの内容を確認したいだけの時はマージをしたくない場合はfetchを使用する。pullというのは内部でfetch + mergeをしている。
https://backlog.com/ja/git-tutorial/stepup/15/


Git clone [リモートリポジトリのURL]
→リモートリポジトリをローカルに持ってくる。（）



Git branch
→今あるbranchを確認する
→今いるbranch名を確認する。

Git branch [branch名]
→新しいブランチを作成する。

Git branch -b [branch名]
→新しいブランチを作成し、そのブランチに移動する。

Git checkout [branch名]
→[branch名]のブランチに移動する。

・masterではないブランチに切り替えて作業を行った場合、そのブランチに履歴が記録される。
そのため、例えばtest_branchというブランチで作業を行ったらまずはtest_branch上で
Git add [編集したファイル]
Git commit -m “test_branchで～を変更”
を行い
Test_branchでのコミットを行ったらmasterブランチへ移動しmergeを行う。

Git checkout master
Git merge [test_branch(マージを行うブランチ名をここに記述する。)]


ブランチを削除する場合
Git branch -d [ブランチ名]
Android SDK Platform-Toolsのパスを通す方法

## はじめに

`adb` コマンドを使いたいため、Android SDK Platform-Tools（以下「Platform-Tools」）のパスを通します。

## 「Platform-Tools」とは？

Androidアプリの開発に必要なツール群で、 `adb` 、 `fastboot` 、 `systrace` などが含まれています。

## 前提条件

- Android Studioをインストールしている

## 環境

- Android Studio：4.0
- adb：1.0.41

## Platform-Toolsのパスを通す

基本的には参考リンクのやり方と同じです。
私はフォルダが存在する場合のみパスを通したいため、 `if` 文を追加しています。

`.bash_profile` に以下を追記します。
前半部分はAndroid SDKのパスを通していて、Platform-Toolsと直接は関係ないですが、 `ANDROID_HOME` 変数を再利用しているので載せています。

```bash:.bash_profile
export ANDROID_HOME=${HOME}/Library/Android/sdk
if [ -d "${ANDROID_HOME}" ]; then
  export PATH="${ANDROID_HOME}/bin:$PATH"
fi

# Platform-Toolsのパスを通す
export ANDROID_TOOL_PATH=${ANDROID_HOME}/platform-tools
if [ -d "${ANDROID_TOOL_PATH}" ]; then
  export PATH="${ANDROID_TOOL_PATH}:$PATH"
fi
```

`adb version` を実行し、バージョンが出力されたらパスが通っています。

```shell-session
$ adb version
Android Debug Bridge version 1.0.41
Version 30.0.4-6686687
Installed as /Users/{ユーザー名}/Library/Android/sdk/platform-tools/adb
```

## おわりに

これで `adb` コマンドが使い放題になり、Androidアプリ開発が捗ります。

## 参考リンク

- [SDK Platform-Tools リリースノート  |  Android デベロッパー  |  Android Developers](https://developer.android.com/studio/releases/platform-tools?hl=ja)
- [adbをMacのターミナルで使えるようにする - Qiita](https://qiita.com/furusin_oriver/items/f956848788c7a63922bd)
- [dotfiles/.bash_profile at master · uhooi/dotfiles](https://github.com/uhooi/dotfiles/blob/master/.bash_profile#L94-L104)
Rails6 で routes.rb を分割する

# やりたいこと

ルーティングの定義ファイル config/routes.rb を複数のファイルに分割したい。
具体的には lib/my_app/routes.rb というファイルを用意していて、それを読み込またい。

# 昔の解決策

2015年の記事 https://y-yagi.tumblr.com/post/118514473965/ がヒットするが、そのままだとうまく行かない。
draw の定義と実行までは上手くいくけど、リロードさせるあたりの仕組みが古くなっているらしくて失敗する。

# rails 7 の解決策

ralis 7 では標準対応している。

https://railsguides.jp/routing.html#%E5%B7%A8%E5%A4%A7%E3%81%AA%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%88%86%E5%89%B2%E3%81%99%E3%82%8B

# rails 6 の解決策

Rails6 ではルーティングの読み込み方がかなり整理されていて自分でリロードさせたりする必要はなさそう。
https://qiita.com/ryohashimoto/items/7caf905389ccb5d7d8fb#configroutesrb%E3%81%A7%E5%A4%96%E9%83%A8%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80%E3%81%93%E3%81%A8%E3%81%8C%E5%8F%AF%E8%83%BD%E3%81%AB

---

[Rails::Application::RoutesReloader](https://github.com/rails/rails/blob/fe76a95b0d252a2d7c25e69498b720c96b243ea2/railties/lib/rails/application/routes_reloader.rb) というクラスが定義されおり、これに正しいパラメータが渡せればそれで完成する。
config/routes/ 配下に routes.rb を分解していくなら下の記事に書いてある方法がよさそう。

https://medium.com/rubycademy/how-to-keep-your-routes-clean-in-ruby-on-rails-f7cf348ec13b 

ただこれだと任意のファイルを読み込ませることができなかったので自分は別の方法を選択した。

# 他の解決策

ルーティングの読み込みは [initializers](https://guides.rubyonrails.org/configuring.html#initializers) の中の `add_routing_paths` というところでやっている。
なのでその initializers の一個前に path を追加するような設定をかけば良いと思った。

具体的には config/application.rb に下記の設定を追記した。

```config/application.rb
    initializer('add_my_app_routing_paths', before: 'add_routing_paths') do |app|
      routing_path = root.join('lib/my_app/routes.rb')
      app.routes_reloader.paths.prepend(routing_path)
    end
```

これで一応期待したとおり lib/my_app/routes.rb で定義したルーティングが読み込まれるようになっていた。
リロードされないという副作用もなさそうだったのでこれで行くことにした。
AndroidでFragmentを実装するとRunTimeExceptionが発生する

#概要
Fragmentを実装しようとするとjava.lang.RuntimeException: Unable to start activity ComponentInfo｛｝～といったエラーが発生する。
日本語でいい対処法の記事がなかったので備忘録替わりに。

#エラー内容
Fragmentを実装すると

```
java.lang.RuntimeException: Unable to start activity ComponentInfo｛｝～
```

といったエラーが出てくる。
ついでに以下のような原因も記載される

```
Caused by: android.view.InflateException: Binary XML file line #6: Binary XML file line #6: Error inflating class fragment
     Caused by: android.view.InflateException: Binary XML file line #6: Error inflating class fragment
     Caused by: java.lang.IllegalArgumentException: Binary XML file line #6: Must specify unique android:id, android:tag, or have a parent with an id for com.websarva.wings.android.fragmentsample.MenuListFragment
```

#解決方法
エラー内容のCaused byでidが必要と言われていたのでひとまずactivity_main.xlmの<fragment>タグ内に任意のidをつける。
（例；android:id="@+id/fragmentSample"）
nameだけはつけていたのだが、idも別で用意する。
すると正常に動いた。
JST↔UTC変換

# あらすじ

UTCとJST変換ですぐ忘れていたのでメモしました。

# JSTからUTCへの変換

```

Datetime localDt = Datetime.Now();
// {2020/10/29 14:16:19}

★UTCへ変換
localDt = localDt.ToUniversalTime();
// {2020/10/29 5:16:19}
```

# UTCからJSTへの変換

```
Datetime localDt = Datetime.UtcNow();
// {2020/10/29 5:16:19}

★JSTへ変換
localDt = localDt.ToLocalTime();
// {2020/10/29 14:16:19}
```

#追記
特定の時間を定義したい時

```
Datetime now = Datetime.Now();

DateTime dt = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
// {2020/10/29 14:34:34}

DateTime wdt = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
// {2020/10/29 14:00:00}

//各プロパティ設定できる
```
Laravel6 Storageファサードでエラーが出た

# 目的

- Storageファサードを使ってファイルの存在を確認しようとしたときに出たエラーを紹介する

# 原因

- 今回のエラーの原因は単純で筆者がtypoしていただけだった。

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.8 | Homebrewを用いてこちらの方法で導入→[Mac HomebrewでPHPをインストールする](https://qiita.com/miriwo/items/cd54077aad7e139cf518) |
| Laravel バージョン | 6.X | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 問題までの経緯

- Storageファサードとファイルパスを使用してファイルの存在を確認する三項演算子を書いていた。
- ファイルパス先にファイルの存在を確認し真の場合ファイルをダウンロード、偽の場合エラーページにリダイレクトする処理である。

    ```php
    return Storage::exsits(ファイルパス) ? Storage::download(ファイルパス) : redirect(route('error'));
    ```

# 問題

- ファイルが存在しているにも関わらずファイルをダウンロードする事ができない。
- というよりエラーページにリダイレクトされているわけでも無いのでファイルの存在を確認している部分がおかしい。
- エラー内容を下記に記載する。

    ```terminal
    BadMethodCallException
    Call to undefined method League\Flysystem\Filesystem::exsits
    ```

# 問題解決までの経緯

- Storageファサードがuseされているかの確認やファイルパスがnullになってないかなどを確認したが問題はなかった。
- お気づきだとは思うがStorageファサードのメソッド指定部分でtypoしている。
- `exsits`ではなく`exists`が正しい。
- typoしていた部分を正常に記載したところ問題なく処理が実行された。
Next.js: Vercelでカスタムサーバーが使えない…と気づいた時の対処

# Vercelでカスタムサーバーは使えない

## server.js が動いていない？

先日 Vercel にデプロイした Next.js のアプリの挙動確認をしていたのですが、どうやら上手く動いてない箇所がありました。

問題となっていたのは、Express.js で実装していたカスタムサーバーの `server.js`。

これが全く動いていませんでした。

## 「使えません」 by 公式ドキュメント

原因調査しましたが、普通に公式ドキュメントの「[カスタムサーバー](https://nextjs.org/docs/advanced-features/custom-server)」のところに書いていました。

> **A custom server can not be deployed on Vercel**, the platform Next.js was made for.

そう、「**カスタムサーバーはVercelにはデプロイできません**」と…。

公式ドキュメントはしっかり読みましょう！

# 後から気づいた時の対処

デプロイしてからこの事実に気がついた場合、次の2つの対処法が考えられます。

## 1. API Routes で代替する

元のカスタムサーバーで、特に複雑なことをしていなければ、[API Routes](https://nextjs.org/docs/api-routes/introduction) で代替するのが1番でしょう。

### 使い方

`pages/api` 配下に任意のファイルを作り、`handler(req, res)` を書くだけでAPIのエンドポイント（サーバーサイドの処理）が作れます。

例えば、`/api/example` というエンドポイントを作りたい場合、次のようになります。

```javascript:pages/api/example.js
export default function handler(req, res) {
  res.statusCode = 200
  res.setHeader('Content-Type', 'application/json')
  res.end(JSON.stringify({ name: 'Hello World from example.js' }))
}
```

#### TypeScript の場合

TypeScript で書く場合は、次のようになります。

```typescript:pages/api/example.ts
import { NextApiRequest, NextApiResponse } from 'next'

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  res.statusCode = 200
  res.setHeader('Content-Type', 'application/json')
  res.end(JSON.stringify({ name: 'Hello World from example.ts' }))
}
```

#### 環境変数も普通に使える

環境変数も `NEXT_PUBLIC_` なしで普通に使えます。

*[Environment Variables 公式ドキュメント](https://nextjs.org/docs/basic-features/environment-variables) より*

> This loads process.env.DB_HOST, process.env.DB_USER, and process.env.DB_PASS into the Node.js environment automatically allowing you to use them in Next.js data fetching methods and **API routes**.

## 2. 別の PaaS にデプロイする

「**いや、カスタムサーバーが必要なんだ！**」

という場合は、別の Platform as a Service (PaaS) 等にデプロイするしかありません。

Heroku にデプロイするなら次のGitHubページが参考になりそうです。

GitHub: [mars/heroku-nextjs-custom-server-express](https://github.com/mars/heroku-nextjs-custom-server-express)

# まとめ

- Vercelでカスタムサーバーは使えない
- ほとんどの場合、API Routesで代替できる
- カスタムサーバーが必要な場合は、別のPaaSにデプロイする

# References

- [公式ドキュメント](https://nextjs.org/docs/getting-started)
- [Deploy next app with custom express server #4588 - Vercel](https://github.com/vercel/vercel/discussions/4588)
- [mars/heroku-nextjs-custom-server-express](https://github.com/mars/heroku-nextjs-custom-server-express)
Linuxのコマンドで、ディレクトリ名とディレクトリ内のファイル名を、まとめて置換する

# 解決したい課題
`Hoge`というディレクトリの中に`Hoge`という名前のあるテキストが複数存在するケース。
ここで、ディレクトリ名もファイル名も`hoge`に置換したい。

# 置換コマンドの説明
```
find `pwd` -name "*Hoge*" -print | perl -nle 'rename $_, s|Hoge|hoge|r'
```

## printまで
この時点で、対象のディレクトリとファイルの一覧が出る。
`-print0`としないのは、perlで一行ずつ処理させたいから。

```
% find `pwd` -name "*Hoge*" -print                                                 
/Users/omokawayasuaki/test/Hoge
/Users/omokawayasuaki/test/Hoge/Hoge1.txt
/Users/omokawayasuaki/test/Hoge/Hoge3.txt
/Users/omokawayasuaki/test/Hoge/Hoge2.txt
```

## perlの部分
`s|Hoge|hoge|r'` の`r`は、デフォルト変数`$_`を置換し、スカラー値として返却するためのオプション。置換した元の文字列は変更しないのが特徴。

### 参考
https://perldoc.jp/docs/perl/5.18.1/perlreref.pod#OPERATORS


# 変換前の状態
```
% tree                                                                             
.
└── Hoge
    ├── Hoge1.txt
    ├── Hoge2.txt
    └── Hoge3.txt
```

# 変換コマンド２回叩く
``` 
% find `pwd` -name "*Hoge*" -print | perl -nle 'rename $_, s|Hoge|hoge|r'
% find `pwd` -name "*Hoge*" -print | perl -nle 'rename $_, s|Hoge|hoge|r'
```

# 変換後の状態
```
% tree                                                                             
.
└── hoge
    ├── hoge1.txt
    ├── hoge2.txt
    └── hoge3.txt
```

以上

# さらなる課題
古いディレクトリ名を一回で上書きできないため、コマンドを２回叩くという結果になってしまった。正直、面倒臭い。
もっとスマートな解決策があれば、教えてください :bow:
ターミナルで処理が終わった際に通知や音を鳴らす

ターミナル上で少し時間がかかる処理を行っている際、別のアプリを開いたり何か違うことをする場合があると思います。
そんな時に音や通知で処理が終わったことを知れると便利ですね。

# 音を鳴らす

ターミナルアプリ上から音を鳴らすには `afplay` というコマンドを使用できます。
また、beep音だけでいいというなら、 `tput bel` も有効です。

System音が既にいくつか用意されているので、以下のコマンドで参照しているディレクトリをみてみると面白いです。
Hero.aiff という音を鳴らすには以下のコマンドを叩きます。

```shell
afplay /System/Library/Sounds/Hero.aiff
```

また、 `.zshrc` などのプロファイルに以下のエイリアスを登録しておけば、bellコマンドを実行するだけで音が鳴ります。

```zsh:.zshrc
alias bell='afplay /System/Library/Sounds/Hero.aiff'
```

# 通知を表示する
ターミナルアプリ上から通知を表示するには `osascript` というコマンドを使用できます。
以下のコマンドを実行すると、 `Terminal` というタイトルで、 `Process is done!"` というメッセージが表示されます。
`osascript -e 'display notification "Process is done!" with title "Terminal"'`

.zshrcにエイリアスを登録するのは文字列区切りのシングルクォートの関係で難しいため、 .zshrcに関数を記述してそれをエイリアスとします。
以下のエイリアスを登録すると、 `notify-done` コマンドを実行すると通知が届きます。

```zsh:.zshrc
_notify-done() {
　　osascript -e 'display notification "Process is done!" with title "Terminal"'
}
alias notify-done=_notify-done
```

# コマンドが終わった際に音と通知を表示する

コマンドを `＆＆` で繋ぐとコマンドを直列で実行できます。(処理Aが終わったら処理B)
`&` で繋ぐと並列になります。（処理Aと処理Bを同時に実行）


echoコマンドの後に音と通知を表示するには以下のコマンドが使えます。


```shell
echo "Something text" && (notify-done & bell)
```
JavaScript  Storageオブジェクト

初学者のため、学習した内容をまとめていく。
今回は、Storageオブジェクトについて

##Storageオブジェクト
JavaScriptではスクリプトからコンピューターに勝手にアクセスできない仕組みとなっている。ブラウザにアクセスするとPC内のファイルが勝手に書き換えられるわけにはいけないため。
その例外としてクッキーと言う仕組みがあるが、制限もあり使いにくい。
その代替手段としてWeb　Storageと言うものがある。これはブラウザ内蔵のデータストアでkeyとvalueの値の組み合わせでデータを保存する。

クッキーとストレージの違い

| 項目| ストレージ| クッキー|
|:--|:--|:--|
| データサイズの上限| 大きい（５Mb)| 小さい（４KB)|
| データの有効期限| なし| あり|
| データ通信| 発生しない| リクエストの都度、サーバーにも送信|

そして、Storageには２種類あり、ローカルストレージとセッションストレージがある。

２つの違い

| ストレージ| 違い|
|:--|:--|
| ローカルストレージ| ウィンド/タブをまたいでデータの共有が可能。ブラウザーを閉じてもデータは維持される|
| セッションストレージ| 現在のセッション（ブラウザが開いている間）だけ保持される。ウィンド/タブをまたげない・データを共有することもできない|

用途で使い分けるべきだが、ローカルストレージは意図的に削除しないといけない、複数のアプリを使うと変数名が衝突しやすい、と言う問題もあり、基本はセッションストレージを使う方が良い。


###データのセット
２つの使い方はプロパティが違うだけなので、必要なプロパティを当ててもらうと良い。

```javascript
let storage = localStorage //sessionStorage
//変数に定義していると後々ストレージを変更することになっても変更箇所が少なくて良い
storage.setItem('key','value');
```

値のセットの仕方は複数ある。必要に応じて使い分ける。
開発者ツールでストレージの内容も確認することができる。

データのセットの仕方

| 記法| 構文|
|:--|:--|
| プロパティ構文| storage.キー名 = value|
| ブラケット構文| storage['キー名'] = value|
| メソッド構文（取得）| storage.getItem('キー名')|
| メソッド構文（設定）| storage.setItem('キー名','value')|

###データの削除

```javascript
storage.removeItem('キー名');
delete storage.キー名;
delete storage['キー名'];

storage.clear(); //無条件に全てのデータを削除
```

###ストレージにオブジェクトを保存・取得
ストレージへの保存は文字列となる。オブジェクトを保存してもエラーにはならないが、復元不可能な文字列となる。
そのため、オブジェクトを保存する場合は、復元可能な文字列に変換しないといけない。
そのために

| 内容| 構文|
|:--|:--|
| 復元可能な文字列変換| JSON.stringify(変換するオブジェクト)|
| 文字列からオブジェクトへ変換| JSON.parse(元に戻す文字列)|

のメソッドを使う。
例 

```javascript
let storage = localStorage;
let test = { name:'test', point: 80}
storage.setItem('satou', JSON.stringify(test)); //値のセット
let answer = JSON.parse(storage.getItem('satou')); //値の取り出し
```

なぜ、オブジェクトで保存？
ローカルストレージはオリジン単位でデータを保存するため、複数アプリが起動すると名前の衝突が起きる危険がある。そのため、アプリごとにオブジェクトとして保存する方がいい。


ストレージはログイン状態の保存など使うことが多いと思うので、気をつけて使っていきたい。
システムモニターアプレットを Ubuntu 20.04 タスクバーに表示する

:::note info
(2023/05/25追記：)
Ubuntu22.04 の場合の記事はこちら
「システムモニターアプレットを Ubuntu 22.04 タスクバーに表示する」
https://qiita.com/nanbuwks/items/435286ca9e9073915d8b
:::

GNOME パネルにシステム負荷表示を常駐表示させる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8e499dd6-ac92-c7a7-d448-876dab3dc032.png)

過去はいろいろ苦労したけれども、今は Ubuntu パッケージであっさり入るというお話。

今回試したのは以下の 2 つ

- gnome-shell-system-monitor-applet 
- indicator-multiload



# gnome-shell-system-monitor-applet 

公式ページ
https://github.com/paradoxxxzero/gnome-shell-system-monitor-applet

では苦労しているが、以下で入った。


```

$ sudo apt install gnome-shell-extension-system-monitor

```

これだけだと有効にならなかったので、以下のように拡張機能マネージャをインストールして、Linux を再起動すると画面が出ました。


```

$ sudo apt install gnome-shell-extension-prefs
```
(20210206追記) 
再起動ではダメで、拡張機能マネージャを以下のように呼び出して、system-monitor をONにする必要がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1d9b332a-d34c-ec8e-f865-bb144710da59.png)


以下に Tips。 

- 拡張機能マネージャはブラウザ版でもいいみたい。
- Ubuntu 18.04 では18.04 だと Ubuntu パッケージがダメだったので gnome パッケージを使ったが、 20.04 だと逆だった。
- 画面が重なるので時計を移動するとして再起動したらうまく行きました。




# indicator-multiload

```

$ sudo apt install indicator-multiload
```

indicator-multiload は、Ubuntu16.04 までは動作していたが 18.04 では動作しなくなっていたもの。
いつの間にかバグFIXしたのか、Ubuntu20.04だから動くようになったのか？



# 比較

そっくりさん！


## アプレット画面
gnome-shell-system-monitor-applet 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e46bdc39-3d75-9150-defb-4f6e103631c6.png)

indicator-multiload

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/fb9de21b-0ce5-8b18-3fe0-ee750844d7f8.png)


## 設定画面
gnome-shell-system-monitor-applet 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a765c7e8-1772-8c08-f4f3-86b99f2a3193.png)

gnome-shell-system-monitor-applet 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/19446b99-d032-4a47-1352-1f1ec2f8527a.png)


ファンや温度表示は標準では gnome-shell-system-monitor-applet でないとできないようだ。
AD環境下でのサーバの時刻同期設定

#AD環境下における時刻同期
業務に使用しているPCの時刻がスマホの時刻に比べて1分だけ遅いことをきっかけに今回の記事を書くことにした。

たかが1分だが、塵積で大きな問題になる前に調査しておいた。
まず分かったことは、時刻同期先のサーバであるNTPサーバは、**「[独立行政法人 情報通信研究機構](http://www.nict.go.jp/JST/JST.html)」が公開している日本標準時に直結しているNTPサーバー(ntp.nict.jp)**を使用すると良いとのこと
次に、AD環境下だとWindwos Server 2016やWindows10は、「日付と時刻」の設定でインターネット時刻のタブが表示されないこと。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/03e62efe-2483-fbab-a412-916c4f0fe81a.png)

その為、コマンドプロントで下記のコマンドを実行することで、時刻同期先を確認することができることが分かった。

```
w32tm /query /status
```
**▼実行結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/49d39e1d-d21b-a820-e709-00cd5ec5f52c.png)
実行結果の「ソース」が時刻同期先のNTPサーバを表示している。上の図は、同期先のサーバが無い状態

時刻同期先が無いので、目的のNTPサーバー(ntp.nict.jp)にするために以下のコマンドで、時刻同期をさせます。

```
w32tm /config /manualpeerlist:ntp.nict.jp,0x8 /syncfromflags:manual /reliable:yes /update
```
**▼実行結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/aef5c4c6-ecf4-10a3-9f49-89723b1e0d79.png)

実行結果の「ソース」がNTPサーバー(ntp.nict.jp)になったので、無事に時刻同期ができました。

#まとめ
・時刻同期には**「[独立行政法人 情報通信研究機構](http://www.nict.go.jp/JST/JST.html)」が公開している日本標準時に直結しているNTPサーバー(ntp.nict.jp)**が良いらしい。
・WindwosServer2016やWindows10は、AD傘下だと日付と時刻」の設定でインターネット時刻のタブが表示されない
・時刻同期を確認するなら

```
w32tm /query /status
```
同期先を追加するなら

```
w32tm /config /manualpeerlist:[同期先のサーバ名] /syncfromflags:manual /reliable:yes /update
```
さぁ、B Tree インデックスを使おう！後々効いてくるMySQLのインデックスの張り方

# はじめに
みなさん、MySQLにインデックス張れてますか？
今回はどういうときにインデックスを張るのかについて紹介します！

動画で確認したい方はこちらをどうぞ！
[【YouTube動画】 今、MySQLのインデックスを見直そう！　MySQLのインデックスを解説！](https://youtu.be/S40zMj4jgoE)
[![今、MySQLのインデックスを見直そう！　MySQLのインデックスを解説！](https://img.youtube.com/vi/S40zMj4jgoE/0.jpg)](https://www.youtube.com/watch?v=S40zMj4jgoE)

# インデックスの種類
インデックスは検索対象やエンジンによって、以下の4種類を使い分けます。

- B Tree (Balanced Tree)
- ハッシュ
- R Tree
- FullText

B TreeインデックスはInnoDBエンジンデフォルトのもので、インデックスを張るというと大抵こちらを指します。
B Treeを使うため、データの偏りが少なく、素早い検索が可能です。

ハッシュインデックスはメモリエンジンのデフォルトのもので、MySQL Clusterで使われます。
ただ、ハッシュ関数を使ってデータを格納するため、一意なデータを保存するのに向いており、範囲検索やワイルドカードを使った検索はできません。

R Treeインデックスは座標にインデックスを張る場合に使います。

FullTextインデックスは全文検索で使われるインデックスです。こちらは過去に記事にしています。
[MySQL 全文検索](https://qiita.com/yassun-youtube/items/09daa057f4653dac2c95)

## インデックスを張ると良いテーブル
インデックスは中 〜 大規模なテーブルに対して張ると良いと言われています。
ここでの大規模なテーブルとは、100 〜 1,000万行のテーブルを指します。

## インデックスを張ると良いカラム
インデックスは短い文字列に対してつけると良いです。長すぎると、インデックスが働かないことがあります。
また、更新頻度の少ないカラムに対して付けると良いです (更新するたびに、B Treeを作り直すことになるため)。

# 有効なクエリ
インデックスを張っているかどうかは、SQLのクエリ文の前にEXPLAINを付けることで確認できます。

```sql
EXPLAIN SELECT xxx FROM xxx WHERE xxxxx
```

WHERE句以降で検索条件を決めますが、インデックスが働くクエリと働かないクエリがあります。
インデックスが働くクエリは、以下の4つです。

- 完全一致 =
- 左端一致 like "ab%"
- 範囲一致 created_at < "2020-10-29"
- ソート ORDER BY xxx

逆にインデックスが働かないクエリは、右端一致、部分一致で検索する場合やカラムに関数がかかる場合です。

# 複数列のインデックス
インデックスは複数列に対して働かせることもできます。
例えば、nameとbirthdayがよく一緒に検索される場合は、これらにインデックスを張ると検索速度が上がります。

| id | name |nickname| birthday | age |created_at | updated_at |
|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|
| 1 | 山田太郎 | やっすん | 8/8 | 88 | 2020-10-29 10:22:22 | 2020-10-29 10:22:22 |

ただ、インデックスの張り方の順序も大切です。
インデックスをname, birthdayと付けた場合、nameで検索したのち、birthdayで検索するようになります。

そのため、初めの段階で絞り込めると、検索速度が上がります。


# 悪いインデックス
複数列のインデックスで、nameにインデックスを付けているにも関わらず、name, birthdayにもインデックスを付ける場合、nameだけのインデックスを外しましょう。
name, birthdayのインデックスはnameやbirthdayのインデックスも含んでいるためです。



# まとめ
今回はMySQLのインデックス (B Tree) について解説しました。
他にも解説して欲しいことがあれば、コメントいただけると嬉しいです。

今回説明しませんでしたが、B Treeに関しては以下の記事がわかりやすかったです。
[B-Tree by Java -- B木のすごく簡単な実例](http://wwwa.pikara.ne.jp/okojisan/b-tree/index.html)

なぜ、Treeやハッシュで保存すると速く検索できるの？ と思った方は以下の記事を読んでみてください！
Treeは二分探索法、ハッシュはハッシュ法の部分が対応しています。
[データの探し方 探索アルゴリズム 基本情報技術者 用語解説②](https://qiita.com/yassun-youtube/items/7b0bd970626d596557cd#%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E6%B3%95-o1)


また、[twitter](https://twitter.com/yassun_youtuber)や[youtube](https://www.youtube.com/channel/UCajrdoGzHzDogrNrLYYmGsg/featured?view_as=public)でのコメントもお待ちしています！
Pycharmのデバッグでハマった

Pycharmでdocker-composeからDjangoを使って、デバッグしようとしてハマった。

```
ERROR: The Compose file is invalid because: Service <project> has neither an image nor a build context specified. At least one must be provided.
```

この記事を参考にして、できた。
https://qiita.com/mth1209/items/82678e1cd59c925846b4


[File] >> [Settings] >>[Python Interpreter]
[Add] >> [Docker Compose] >> [Service]でここを指定したら治った。
【Java】データ型②-参照型


#参照型
* **クラス型**
* **インターフェース型**
* **配列型**

##クラス型
* オブジェクトはメモリ上に存在するデータ
    * 文字列の場合
        * 文字列データ
        * 文字列の長さを決める部分を切りだす、検索する機能
* **全部の文字列を普遍的に操作できるように用意されているがクラス**
    * フィールド：データの入れ物
    * メソッド：データ操作
    * クラスは設計図📃
* オブジェクト指向では**クラスからデータを持ったオブジェクトを作成し、オブジェクト経由で操作を行う**
    * オブジェクトは作成したもの⚙

###インスタンス化 
* クラスからものを作成する作業のこと
* インスタンス化によってできるものを**オブジェクト**,**インスタンス**という
* クラスの複製を作成、専用のメモリ領域を確保する
* Javaではnewでクラスをインスタンス化する。引数の()は省略できない
* 生成されたオブジェクトは変数に格納され、オブジェクトへの参照(メモリへのアドレス)が格納

```java
//“Cat”クラスからtamaオブジェクトを作成
Cat tama = new Cat();
```

###クラスフィールド/クラスメソッド（静的フィールド/静的メソッド）
* オブジェクトを生成せずクラスから直接呼び出せる
* 例えば、`Syetem.out.println`は`System.out`フィールドから得た`PrintStream`オブジェクトを介してprintlnメソッド(インスタンスメソッド)を呼び出す

###null型
* 変数がオブジェクトへの参照を持たない状態を表す
* 参照型のフィールドの場合、明示的に初期化しないとnullになる
* nullの変数のフィールドにアクセスするとNullPointException

##配列型
* 配列：言語仕様に組み鋳込まれた仕組み
    * **[]カッコも含めて型名**である
    * 配列の場合はnewして実態を持たせるには**初期化時に大きさ(使うメモリ)を定義する必要**
    * `int[] hoge  = new int[1000];` //4byte×1000=4000byte~4KB
* コレクション：標準ライブラリ（Javaでは優先的に使う）

```Java
// サイズのみ宣言
int [] list  = new int[5]; 
// 初期化して宣言
int [] list  = { 1, 2, 3, 4, 5 }; 
//var でサイズのみ宣言
var list  = new int [5];
// var で初期化して宣言 ※データ型略不可
var list = new int[] { 1, 2, 3, 4, 5 }; 
```

###配列へのアクセス
```Java
System.out.println(list[0]); //1
System.out.println(list.length); //5
//要素の書き換え ※追加は不可能、変更にはArrayListクラスを使う
list[1] = 15;
```

###多次元配列		
```Java
// 3*4*5の三次元配列
init [][][] list = new int [3][4][5]; 
// 2次元配列を初期化して宣言
int [][] list = [
  { 1, 2, 3 },
  { 4, 5, 6 },
  { 7, 8, 9 },
};
//var で初期化して宣言
var list = new int[][] [
  { 1, 2, 3 },
  { 4, 5, 6 },
  { 7, 8, 9 },
};
// 0行1列目にアクセス
System.out.println(list[0][1]); //2
```

##ジャグ配列の扱い
* 長さが異なる多次元配列
* 最初の宣言では外側のサイズのみ指定
* 1次元目は確保しないといけないが2次元目は確保不要
* **2次元以降はダイナミックに変更できる！**
* ユースケース
    * 全人口の給料の配列を作るときに都道府県ごとに作成<br>　`int [][] = salary = new int[47][];` 

```Java
var list = new int [3][];
list[0] = new int[2]; //0番目の配列の要素は2個
list[1] = new int[3]; //0番目の配列の要素は3個
list[2] = new int[4]; //0番目の配列の要素は4個
``` 

```Java
var list = new int [][] {
  { 1, 2 },
  { 3, 4, 5 },
  { 6, 7, 8, 9 },
};
System.out.println(list[1][2]); //5 ※サイズは3
```
Gitの基本2

<font color="Red">リポジトリ</font>
リポジトリとは、変更履歴を管理しておくための入れ物。
このリポジトリにファイルやディレクトリの変更履歴を記録しておく。

<font color="Red">ローカルリポジトリ</font>
ローカルリポジトリとは、自分のPC上(ローカル環境)に置くリポジトリのこと。
自分のPC上にあるファイルやディレクトリのバージョン管理を行いたい時に使う。

<font color="Red">リモートリポジトリ</font>
外部サーバーのネットワーク上に置くリポジトリのこと。

<font color="Red">リモートリポジトリのメリット</font>
ネットワーク上に置くことで、複数人で管理下のファイルやディレクトリを共有することができる。
ローカル環境下で問題が起こったとしても、またリモートリポジトリからダウンロードを行うことで元に戻すことができる。

<font color="Red">クローン</font>
リモートリポジトリを複製してローカルリポジトリを作成すること。
クローンを行うとリモートリポジトリの内容をそのままダウンロードすることができる。
Asperaを使って遺伝研スパコンにファイルを転送する。(windows)

#はじめに
大規模シーケンスデータ(200GB)をAsperaを使って遺伝研の自分のフォルダへ転送しとしたところ、少しつまずいたので備忘録的に残しておきます。コマンドはwindows PowerShellでうちました。


#秘密鍵ファイルの準備
基本的には
[遺伝研の利用ガイド](https://sc.ddbj.nig.ac.jp/ja/guide/usage-for-general-analysis-environment/file-transfer)
に沿ってやっていきます。しかし、Aspera CLI ダウンロード→パスを通した後、

```
$ ascp -l 1G -Z 1500 -P 33001 -i (秘密鍵ファイル名) (送りたいファイル) ユーザーID@ascp.ddbj.nig.ac.jp:（指定ディレクトリ）
```
となっていますが、利用ガイド通りに秘密鍵ファイル(id_sra)を指定すると、パスフレーズ入力後にエラーがでます。

[ユーザーガイド](https://www.ibm.com/support/knowledgecenter/SS4F2E_3.9/cli_user_win/cli_aspera_conf_aoc.html)
を見ると、秘密鍵ファイルの形式が.pem形式でなければならないようです。

#秘密鍵ファイルの変換

[このサイト](https://aws.amazon.com/jp/premiumsupport/knowledge-center/convert-pem-file-into-ppk/)を参考にして、PuTTYgenを使用して.ppkファイルを.pem形式に変換します。

変換がおわったら、(秘密鍵ファイル名)を.pem形式のモノにすれば完了です。

結果は大体178Mb/sで、200GB転送するのに3時間弱かかりました。
【Ruby on Rails】初期データの導入

# はじめに
動作確認の為の初期データを投入することで、
DBをリセットした場合に、seedファイルを基に初期データを再び作成できたり、
一度に大量のデータを作成する事ができるため、
開発段階のアプリケーションには必要な機能となります。

今回はseedファイルを編集して、初期データを投入します。


# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# seedファイルとは
rails new 〇〇コマンドを実行した時に作成されるファイルでdbディレクトリの直下にあります。
db/seeds.rb

# 実際に作成する

```rb:db/seeds.rb
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
#   movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
#   Character.create(name: 'Luke', movie: movies.first)
User.create!(
   email: 'test@tesr.com',
   password: 'testpass',
)
Post.create!(
   title: 'よろしくお願いします',
   content: 'seedファイルについて',
)
```

# データベースに反映
```:ターミナル
$ rails db:seed
```
これでuserのログインも可能になり、Postにはデータが投入されました。
その後確認方法としては、下記のように実行して
データが入っていれば成功です。

```:ターミナル
$ rails c
pry(main)> Post.all
```


# 複数ファイルを作成する場合
for文と内容はにており、指定した回数文処理を繰り返します。
初期数字は0から始まるため、下記の場合は0-9となります。

```rb:db/seeds.rb
  Post.create!(
    title: 'よろしくお願いします',
    body: 'seedファイルについて'
  )

  10.times do |number|
    List.create!(title: 'timesについて',body: number)
  end
```

# まとめ
この他にもcsvからデータの投入方法がありますので、
興味のある方は調べてみてください。

またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら　https://twitter.com/japwork
【Java】データ型①-基本型


#Javaの変数

* 変数宣言:変数の名前をJavaに通知、値を格納する領域をメモリ上に確保
    * `int data (=初期値)`
* 複数変数をまとめて宣言可能
    * `int data1, date2 (=初期値)`
* 初期値を設定するようにしよう
    * `int data1= 108;`
    * `String message = “Hello World”;`
* 識別子
    * Java内部ではUCS2を使っている。
    * 全部のUnicode文字を利用できる
    * 大文字小文字は区別(CaseSensitive)
    * 変数名は基本的にReadableに、英語として読めるのが理想
        * `if (obj.isCompleted()){`
* 慣例的には変数は**camelClass**,クラスは**Pascal**,定数は**大文字＋アンダースコア記法**
* 

##定数
* **再代入できない**変数のこと

```Java
//よくない例
int price = 1000;
double sum = price * 1.08;
```
* 定数を使うことで計算式の意味がわかりやすく、変更作業がしやすくなる
* コードの中に文字列直打ちは避けたい→定数として外にだす

```java
//リファクタ例
final double TAX = 1.08;
int price = 1000;
double sum = price * TAX;
System.out.println(sum);
```

#Javaのデータ型
* 静的型付け言語：変数を宣言する際に型も決定する
* **基本型**：値そのものが格納
* **参照型**：値の格納場所を表す情報を格納。Javaの基本は参照型
* 全てに対して対応する基本型、参照型がある
    * boolean：基本型　Boolean：参照型 
    * int：基本型　Integer：参照型

###整数型：基本intを使う
* byte, char：バイトデータを格納する
* short：小さな整数を表す
* long：intで対応できない数値範囲を扱う場合のみ

###浮動小数点型：基本doubleを使う
* メモリを64bit占有
* 浮動小数点型は絶対地位が大きくなるに従って値の飛び幅も大きくなる
* IEEE 754で値の保持形式を定めている
* 正規化し、仮数、指数の形式に分解して管理
 $123.75_{(10)}=1111011.11_{(2)}=1.11101111*2^{6}_{(2)}$

* $1.23*10^1$ ~ $1.24*10^1$ と $1.23*10^{100}$ ~ $1.24*10^{100}$ で間隔の差がでる！！

###文字型
* **Char 型**：16bit - Unicode(UCS2) 1文字 
* **String 型**：可変長、2の倍数

###真偽値(boolean、論理型)
* 数値型と相互変換できない（true=1,false=0など）

###型推論
* `var 変数名 = 初期値`
* `var i = 48;`
* データ型を省略できる
* 代入された値からコンパイラーが自動的に肩を推論し決定＝型推論する
* 上の例ならintを推論してくれる
* 初期値は省略できない
    * `Cannot use var on variable without initializer`
* 複数宣言できない
* フィールド宣言では使えない、ローカル変数(メソッド内で宣言する変数)のみ

#リテラルとは
* **データ型に格納できる値そのもの、表現方法のこと**
* データ型に応じ、整数リテラル、浮動小数点リテラル、真偽リテラルなど

##整数リテラル
* 10進数/16進数/8進数/2進数リテラル

##浮動小数点リテラル
* $<仮数部>E<符号><指数部>$
* 1.14142e-5 → 0.0000114142

##型サフィックス
* 数値リテラルはしていないと整数はint、浮動小数点はdouble
* データ型が勝手に決められると困る場合に使用
* 数値リテラルに肩を表す接尾辞をつける
* `System.out.println(2147483648L); //longの範囲に入っている`

##数値セパレーター(区切り文字)
* 桁数大きい文字の可読性を上げるため
* `var pi = 3.141_592_653_59;`
* 数値文字列を受け取るメソッド(Integer.parseIntなど)ではセパレータを認識できないので注意

##文字リテラル
* シングルクオートで表す
* unicode文字は`\u3042｀形式で16進数文字コードでかける

##文字列リテラル
* ダブルクオートで表す
* 中にダブルクオートを入れたいときはエスケープシーケンスを使う

```java
System.out.println("You are \"GREATE\" !");
System.out.println("Welcome to wherever you are \nThis is your life, you made it this far");
var str = "Welcome, you got to believe " + "That right here, right now"; //可読性改善の目的で分離
System.out.println(str);
```

#型変換
静的型付けであるが型変換が許される

* **拡大変換**
    * intからlong
    * 整数から浮動小数点への変換すると型落ちが発生することがあるので注意
* **縮小変換(キャスト、明示的な変換)**
    * 明示的に変換の意思を示す
    * int とshort の変換で符号が変わってしまうこともあるので注意


```Java
int i = 10;
// byte b = i ; //NG
byte b  = (byte)i ; //OK 
```
vue.js javascript textarea 指定文字数で改行コードを挿入

指定した文字数で改行を入れたい。
例えば、

`ラーメンつけめん僕イケメン`

を

```
ラーメン
つけめん
僕イケメ
ン
```

にする。
textarea に soft やら hard やら指定しろと書いてあるが、
してもうまく動かないのでjavascriptで整形しちゃお♪

# コード
textLimit に 1行の最大文字数を設定するだけ。
あとはコピペで動く。

```hoge.vue

var textLimit = 4;//ここだけ設定
var tmp = this.form.body.split("\n");

var kaigyouBody = [];


for (var key in tmp) {

    if(tmp[key] != ""){
    
        if(tmp[key].length >= textLimit){
        
            let oneSplit = tmp[key].split('');
            let oneBody = [];
        
            for (var key2 in oneSplit) {
            
            //key2 1文字目でなく、さらに textLimit の倍数の数値なら改行コードを挿入
            if(key2 != 0 && key2%textLimit == 0){
                oneBody.push("\n");
            }
        
            oneBody.push(oneSplit[key2]);
        
        }
        
            kaigyouBody.push(oneBody.join(""));
        
        } else {
            kaigyouBody.push(tmp[key]);
        }
        
    }

}


var result = kaigyouBody.join("\n");

console.log(result);

```

こんな感じ。
集合演算子の使用方法

現在勉強しているオラクルマスターブロンズ（SQL）についてまとめたものです。
自分のアウトプット用なので見やすさなどは期待しないでください。

# 集合演算子の種類と使用方法

集合演算子を使用すると、**複数の問い合わせの結果を1つにまとめる**ことができ、集合演算子を含む問い合わせのことを**複合問い合わせ**と呼ぶ。

集合演算子の種類

| 集合演算子 | 説明 |
|:-:|:--|
| UNION | 2つの問い合わせ結果を連結し、重複した行を排除して戻す。<br>内部的にデータをソートしたうえで重複した行を排除するため、、実行結果も**SELECT句の先頭**に指定されている列の値で**昇順にソート**される。 |
| UNION ALL | 2つの問い合わせ結果を連結し、重複した行も含めて戻す。<br>データの**ソート処理を行わない為**、問い合わせ結果は、明示的にORDER BY句を指定した場合を除き、1つ目の問い合わせ結果の後ろに2つ目の問い合わせの結果を追加したものになる。 |
| INTERSECT | 2つの問い合わせ結果のうち、共通する行だけを戻す。<br>UNION演算子と同様に内部的にデータをソートしたうえで重複した行を排除するため、、実行結果も**SELECT句の先頭**に指定されている列の値で**昇順にソート**される。 |
| MINUS | 1つ目の問い合わせ結果のうち、2つ目の問い合わせ結果にない行を戻す。<br>UNION演算子と同様に内部的にデータをソートしたうえで重複した行を排除するため、、実行結果も**SELECT句の先頭**に指定されている列の値で**昇順にソート**される。 |

UNION演算子やUNION ALL演算子、INTERSECT演算子を使用している場合は、1つ目の問い合わせと2つ目の問い合わせの順番を入れ替えても同じデータが表示されるが、MINUS演算子を使用している場合は、表示されるデータが変わる。

# 集合演算子の使用に関するガイドライン

複合問い合わせでは、1つ目の問い合わせと2つ目の問い合わせで、SELECT句に指定する列の**個数を同数**にする必要がある。
また、2つ目の問い合わせのSELECT句に指定する列のデータ型は、1つ目の問い合わせのSELECT句に指定されている列の**データ型と同じか、同じデータ型のグループ**（文字値や数値、日付値といった同種のデータを扱うデータ型のグループ）である必要がある。
なお、それぞれに指定する**列の名前は異なっていてもかまわない**が、その場合、問い合わせ結果の列見出しには、**1つ目の問い合わせに指定されている列名**が使用される。

複合問い合わせの場合はORDER BY句の使用にあたって次の条件がある。

- ORDER BY句は、複合問い合わせの**最後の問い合わせに指定する**必要がある。
- ORDER BY句には、**最初の問い合わせのSELECT句に指定されている列または列別名**を指定する必要がある。

複合問い合わせでは、**NULL値は無視されず**、UNION ALL演算子以外の複合演算子を使用した場合、重複したNULL値は排除される。

集合演算子の**優先順位はすべて同じ**なため、1つのSQL文に複数の集合演算子を使用した場合は、**前に指定されている複合問い合わせから順番**に実行される。
ただし、**（）**を使用して優先順位を明示的に指定することもできる。
Cognos Analytics DQMモードで監査テーブルにNATIVEQUERY出力

#Cognos Analytics DQMモードで監査テーブルにNATIVEQUERY出力
私の長らくの認識では、CognosでのDQMモードで監査テーブルにNATIVEQUERYをキャッチする事は出来ないので、以前こちら記事を書いていました。
**Cognos AnalyticsでDQMレポート実行時に発行されるSQLクエリーのモニター**
https://qiita.com/shinyama/items/15fc1f2bb11f8e2d4f1a

ところが先日、ある仕事でCognos開発元のNigelさんと会話する機会があったので、「DQMではNATIVEQUERYのキャッチ出来ないですよね～」と言ったところ、「そんな事無いぞ、ボケ」と一喝されてしまいました。

マジかよと思って調べてみたら、ああホントだ、確かにできる方法あるわ、というフィードバックです。

#手順と結果
手順は簡単です。
QueryServiceのログレベルのみ「要求」に設定です。その他のサービスは「標準」で大丈夫です。
![001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/44d2a4cd-4b11-e5e1-01c8-8a519b79d3c6.png)

試しにサンプルにある「従業員満足度」を実行してみました。
動的のGOデータウェアハウス(分析)パッケージを使用です。
![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/1c698216-5512-41b6-f00d-37a01927b6a6.png)

実行前
![005.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/0bb2bac9-9fa3-2789-3677-4fb2c8d185ee.png)

レポートの実行
![004.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/d9ac77b3-108f-26fb-46ee-29fb6de704c5.png)

実行後
![006.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/5970e77b-f0d8-a99f-897f-0898adabdc13.png)

ホンマに出た
![007.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/b8c9c2d1-080e-1350-1999-f241963b66a7.png)

※GOデータウェアハウス(分析)パッケージはDMRのパッケージですが、GOデータウェアハウス(クエリー)のRelationalのパッケージでもきちんとNATIVEQUERY出力されました。

ちなみに、考慮点としては、QueryServiceのログレベルを「要求」にする事で、cogaudit.logの出力が増える事ですかね。
先程の「従業員満足度」のレポートを一回実行した時には、cogaudit.logに124行/51664文字のログが出力されていました。
そこそこログ出るので、ファイルシステム容量とか、ログ消し込みとか、少し注意が必要ですね。

という感じで、DQMで監査テーブルにNATIVEQUERY出力問題は、今後認識を改めたいと思いますので、皆様もこの認識のある方いらっしゃいましたら、一緒にご認識改めて頂ければと思います。
邪魔な拡大鏡を消す（起動しないようにする）

Windowsで画面をロックする時のショートカットで、`Win+L`を使うことが多いと思います。

しかし、このLをたまに隣と間違えて+を押してしまうことがあります。で、`Win+"+"`を押すと「拡大鏡」というものが起動して、画面が拡大してしまって操作もしづらいし見づらいしで大変に邪魔なことになりますよね。

よく誤爆するのに拡大鏡なんて今まで一度も使ったことがないので、起動してほしくないです。
正規の方法で拡大鏡を無効化する方法はないようなので、ここは邪悪な方法を使いました。その時のメモです。

方針としては、拡大鏡アプリのパスを変えて起動しなくします。

1. 拡大鏡の実体は標準なら`C:\Windows\system32\Magnify.exe`にあります
2. このままファイル名を変えようとしても、大体の場合はTrustedInstallerが権限を持っていて、管理者権限をもっているアカウントだとしても操作できません（権限の追加もできない）
3. ということで、まずは所有者を無理やり変更します（[参考](https://qiita.com/aoshirobo/items/f7aa2fcbe461beb202dd)）
    4. 管理者権限でコマンドプロンプトを起動
    5. `C:\Windows\system32\`に移動（標準だと最初からここにいるはず）
    6. `takeown /F Magnify.exe /A`（Magnify.exeの所有者を管理者にする）
7. 所有者が変わったら、あとはプロパティからいつもどおり権限の追加ができます
8. 名前を`Magnify.exe_`とかにしておいて起動しないようにすれば完成

です。もし必要であれば、所有者をTrustedInstallerに戻しても良いと思います。


以上、快適なWindows（ロック）生活を！
【iPad】実機テストってどうやるの？

#やりたいこと
実機デバイス（iPad）の表示確認をしたい．

#条件
- プロキシの設定が必要

#手順

「設定」 -> 「Wi-Fi」 -> 対象のネットワークのℹ️ボタンを選択して詳細設定画面へ
![D282083E-0B1D-4E3D-BBB8-8A45BAB953B1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377231/bfb90eaf-3fae-15f3-1889-17455b5f15e4.png)



「プロキシ」 -> 「手動」 -> サーバとポート番号を設定
![62C24F1A-5437-4EAD-A777-06F27199900A (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377231/dcc82a9b-2a08-f11d-6f02-5eacb5ba9942.png)




「一般」 -> 「プロファイル」
![AB687199-12DA-44CB-B66D-BE3115379067.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377231/3d7b7828-7b80-eef6-0d0c-06f4b1c65de9.png)


対象のプロファイルをON（承認）してSSL認証を無効にする．
![AFAD9902-4559-4DBF-AE4C-D9523D6EF39A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377231/6c7f75ec-b5d5-57b8-db47-bdd2656385c2.png)



「Safari」 -> プライバシーとセキュリティ
![F3361BD8-D9BE-4B81-B118-F183AB3CE776.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377231/91958ece-61bf-2075-e4c8-8bf59a7cd91a.png)


Safariが既に起動していたら一度終了し再度起動します．

Androidも同様の設定でできます．

おわり
[Blueprism]ver6.8にアップデートした際にwebアプリが正常に起動しない件

## 今年６月にリリースされたblueprism6.8
![clipboard-202010161548-rzbpk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/e9ea387e-92d7-57fe-2831-b442cddc3a90.png)



今年６月リリースされたblueprism6.8
新しく追加された機能としては、
* Chrome、Firefox、およびChromiumベースのEdgeの自動化対応
* プロセスやオブジェクトをフィルタして探す機能
* プロセスとオブジェクトスタジオのステージを簡単に比較できるように、
単一のプロセスまたはオブジェクトで複数のステージのプロパティダイアログを同時に開くことが可能に

などが目玉のようです。

## バージョンアップ後にWebアプリを起動すると・・・・
試しにQiitaのトップページを起動してみます。

### オブジェクトスタジオ
中身のオブジェクトには起動の操作ステージだけセットし
CommandLineParamsからQiitaのURLを参照します。
![clipboard-202010271350-099nl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/5f8b9552-7898-d53e-004f-4d0529bb06c4.png)
![clipboard-202010271351-oxwko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/82bdcdaf-0ce5-15d7-600b-4a373b7f7b42.png)


### アプリケーションモデラー
アプリケーションモデラーはこんな感じでブラウザの起動のみに使用します。
![clipboard-202010271350-4klnf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/3af04706-1f2a-9012-2e4d-e48655e1ff10.png)


## そしてQiitaを起動
![clipboard-202010271422-ab6uk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/7089c5a9-a335-0dd3-5a6d-626a7cb6e3f3.png)


#### あれ、おかしいな前のバージョンでは動いていたはずなのに・・・・

## システムを再設定しよう

### 1.開いているプロセス・オブジェクトスタジオを全て閉じる
![clipboard-202010271428-ccpaz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/5b963779-3dc5-19e2-7616-97f764163a58.png)
バージョンアップ後は、一度システムルームで設定を変える必要があります。
設定後に一度PCを再起動する必要がある為、現在開いているプロセス・オブジェクトスタジオが
ありましたら一度閉じてください。


### 2.システムマネージャの「設定」から「固定ブラウザーの拡張ポート（31924）のみを使用」にチェックを入れる
![clipboard-202010271458-vcdpx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/944012a2-4149-aee8-5bb9-2dcdb507bfd6.png)
チェックを入れた後、下記のダイアログが表示されるので
OKをクリックします。
![clipboard-202010271501-jdplp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/a3b69249-e0e2-4cf2-c22a-130824b95a14.png)


### 3.PCを再起動
![clipboard-202010271515-j5nrd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/984fa7be-d44d-3743-0424-c7d9a98b001a.png)


## 設定後に再度Qiitaを起動すると・・・
![clipboard-202010271526-gi35v.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660650/9f55cdf5-e52a-ffab-6fa9-13e1911020f6.png)

#### エラーも無く、無事起動出来ました！！
CookieのSameSite属性がLaxの時の挙動

について調べました。

## same-site とは
same-siteの説明は下記の記事がとってもわかりやすかった。
https://web.dev/same-site-same-origin/
ブラウザが開いているURLと、リクエストが飛ぶ先の `eTLD+1`が同じであれば same-site と判定される。

same-siteなリクエストについてはSameSite属性が何であろうとCookieは付与される。
SameSite属性によって挙動が変わるのはcross-siteなリクエストの時。

## NoneとStrictの挙動

NoneとStrictは理解しやすい。
None: cross-siteなリクエストについて、どんな場合でもCookieは付与される。
Strict: cross-siteなリクエストについて、どんな場合でもCookieは付与されない。

## Laxの挙動

Laxは少し複雑だ。 (なのでこの記事を書きました)
cross-siteなリクエストについてCookieが付与される条件は
1. top-level navigationであること
2. methodが `GET`, `HEAD`, `OPTIONS`, `TRACE` であること

- top-level navigationは「ブラウザのアドレスバーに表示されているURLの変更が伴う遷移」のこと。
    
具体的には下記のようになる。

|リクエスト生成方法  |Cookieがつくか  |note  |
|---|---|---|
|a tag  |🍪  |他サイトからリンクを踏んで遷移する場合  |
|img tag |❌  |  |
|iframe tag  |❌  |  |
|form tag (method=GET)  |🍪  | 検索系のフォーム等で使われている |
|form tag (method=POST)  |❌  | form (method=DELETE) というのはHTMLの仕様としてはない。 `<input type="hidden" name="_method" value="delete" />` のようなフォームは POST をウェブフレームワークが気を利かせて扱っているだけ。  |
|XMLHttpRequest  |❌  |  |
|Fetch  |❌  |  |

Cookieがつく ⇒ 🍪
Cookieがつかない ⇒ ❌
多くのリクエストはtop-level navigationではないので❌になる。
form (method=POST) は top-level navigationだがmethodがsafeではないので❌になる。
same-siteの場合は全て🍪になる。


## CORSについて

CORSは Same Origin Policyをまたぐためのもので目的が異なる。
CORSの許可がない場合でもPOSTのリクエストは飛ぶのでCSRFは防げない。
railsのO/Rマッピングを知らずに使用していたので調べてみた。

##そもそも、O/Rマッピングとは。
>オブジェクト/リレーショナルマッピング(O/RマッピングやORMと略されることもあります)とは、アプリケーションが持つリッチなオブジェクトをリレーショナルデータベース(RDBMS)のテーブルに接続することです。ORMを用いると、SQL文を直接書く代りにわずかなアクセスコードを書くだけで、アプリケーションにおけるオブジェクトの属性やリレーションシップをデータベースに保存することもデータベースから読み出すこともできるようになります。
[Railsガイド](https://railsguides.jp/active_record_basics.html)

要するに、`users`の情報を取得したいときはSQLを使用する場合、

```
SELECT * FROM users ;
```
で本来全件取得するはずですが、O/Rマッピングを使用すると

```
user.all
```
のように、railsではActiveRecordのおかげで、SQLを書かずにusersの中身を全件取得できるようになります。

他にもよく使用する

```
.find_by(name: 'TARO')
```
のようなメソッドは

```
SELECT * FROM users WHERE name = "TARO";
```
このようなSQLと同等の結果が出ます。


上記のように、本来はSQLを書いていた処理のような煩雑なデータベース操作の作業を減らすことができます。

このように便利というメリットがありますが、デメリットもいくつかあります。

#####1. 知っておいて損がないSQLを知らなくてもCRUD処理をかけてしまう。

#####2. 遅い、メモリ消費が大きい。

#####3. 複雑な処理が必要なときはSQLよりも難しい。

他にも、特定DBの機能が使用できない等のデメリットがありますが、直感的にデータの検索ができることや、データベースの変更時にソースコードの修正が必要ない等のメリットもあります。

僕自身SQLの勉強をほとんどせずに勉強を進めていたので、業務でjava、kotlinで開発を進めるにあたり、SQLの知識が必要になる場面が多く初めは全くわからず混乱をしていました。

最近ではWebフレームワークには標準搭載されていることが多く、各言語に合わせた構文を知る必要がありますが、対応できる範囲であれば積極的にO/Rマッパーの使用をしていきたいと思っています。

###参考
https://qiita.com/gomiryo/items/6d448c500749f91242d2
https://railsguides.jp/active_record_basics.html
kotlin対話型実行環境を動作させるまで


簡単にkotlinのコードを試してみたいことがあり環境を整えてみました。

## 手順1. インストール

https://kotlinlang.org/docs/tutorials/command-line.html

上記のURLからインストールが可能です。
普段はhomebrewを使用してインストールをしているので、今回もhomebrewを使用してインストールをします。

homebrewがなければ、[こちら](https://brew.sh/index_ja)からインストール。

```
$ brew update
＄ brew install kotlin
```

インストール完了しました。

##手順2. 起動

```
$ kotlinc-jvm
Welcome to Kotlin version 1.4.10 (JRE 11.0.7+10)
Type :help for help, :quit for quit
>>> 
```
これで起動は完了したので、実際にコードを入力。

```
>>> println("Hello,World!")
Hello,World!
```

```
>>> val map = mapOf("リンゴ" to 80, "ミカン" to 100, "メロン" to 1000)
>>> map.forEach { (key, value) ->
...    println("$key は $value 円です。")
... }
リンゴ は 80 円です。
ミカン は 100 円です。
メロン は 1000 円です。
>>> :quit
```

しっかり動作が確認できました。

使用する機会がほぼないと思いますが、実際にファイルに記述してコンパイル→jarファイルの実行まで出来るとのこと。
JVM上で動くのでJREやJDKが入っていないと動作しないので、注意が必要です。

基本はIDEで進めていきますが、どう処理するべきか悩んだときは、勉強用として、とりあえず対話型の環境で色々試してみています。
【JavaScript】点列を2次ベジェ曲線で滑らかにつなごう【Canvas】

#はじめに
mousemoveで得た点を滑らかにつないだ曲線をcanvasに描画したいとします。
#イメージ
赤〇は得られたデータです。
緑×は点の中点です。
緑× - 赤〇 - 緑× で2次ベジェ曲線を描画したのが青線です。
このようにベジェ曲線を引くと、曲線同士が滑らかにつながります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/6ea2436a-b327-96b4-9bd4-97d1e8ffd068.png)

曲線が端点につながっていませんが、点列が割と近いケースを想定しているのであまり問題になりません。
気になる方は直線で結んでください。

#解説
青色の曲線は3本の２次ベジェ曲線からなっています。
###1本目
![test (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/a11f03a8-2902-2231-8e38-2e853146f6fe.png)
###2本目
![test (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/3c25eb7b-1c94-2817-b1fa-79c5791e24de.png)
###3本目
![test (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/5a4bc94e-ee61-e506-f924-118429d6b77d.png)
###1本目と2本目
1本目の2,3つ目制御点と2本目の1,2つ目の制御点が一直線にあるので、滑らかに接続します。
2本目と3本目の接続も同様です。
![test (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/217935c1-ba7d-052c-cc66-df3d8323dede.png)

#ソース

```js
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>bezier smooth</title>
<script>
document.addEventListener('DOMContentLoaded', e => {
	const vertices = [
		{ x: 30, y: 200 },
		{ x: 100, y: 100 },
		{ x: 150, y: 200 },
		{ x: 280, y: 340 },
		{ x: 300, y: 180 },
	];

	const canvas = document.getElementById('canvas');
	const ctx = canvas.getContext('2d');

	ctx.lineWidth = 2;
	ctx.fillStyle = '#ccc';
	ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);

	// 点群を描画(o)
	ctx.strokeStyle = `red`;
	vertices.forEach(v => {
		ctx.beginPath();
		ctx.arc(v.x, v.y, 5, 0, 2 * Math.PI, false);
		ctx.stroke();
	});

	// 点の中点群を取得
	let pre = null;
	const centers = vertices.reduce((p, c) => {
		if(pre) {
			const center = { x: (c.x + pre.x) / 2, y: (c.y + pre.y) / 2 };
			p.push(center);
		}
		pre = c;
		return p;
	}, []);


	// 点の中点群を描画(x)
	ctx.strokeStyle = `green`;
	centers.forEach(center => {
		const p = center;
		ctx.beginPath();
		ctx.moveTo(p.x - 5, p.y - 5);
		ctx.lineTo(p.x + 5, p.y + 5);
		ctx.moveTo(p.x - 5, p.y + 5);
		ctx.lineTo(p.x + 5, p.y - 5);
		ctx.stroke();
	});
	
	// 2次ベジェ曲線の制御点群を取得
	pre = null;
	let preCenter = null;
	const cps = vertices.reduce((p, c) => {
		if(pre) {
			const center = { x: (c.x + pre.x) / 2, y: (c.y + pre.y) / 2 };
			if(preCenter) {
				p.push([ preCenter, pre, center	]);
			}
			preCenter = center;
		}
		pre = c;
		return p;
	}, []);	

	// 2次ベジェ曲線群を描画
	ctx.strokeStyle = `blue`;
	cps.forEach(cp => {
	    ctx.beginPath();
	    ctx.moveTo(cp[0].x, cp[0].y);
	    ctx.quadraticCurveTo(cp[1].x, cp[1].y, cp[2].x, cp[2].y);
	    ctx.stroke();
	});

});
</script>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
</body>
</html>
```
ApplicationJobからメールを飛ばす時はdeliver_nowを使う

タイトルどおりですが、ちょっとハマったのでメモ

ジョブ実行完了したらメールを飛ばしたくて、以下のように実装しました

```XxxxJob.rb
Mailer.send_mail(user).deliver_later
```

で、軽く動作確認…
ログでキューに入ってるの確認、
rails consoleで上記実行してletter_openerで見れた

ヨシっと思っていざ検証環境に上げたらメールが飛ばない、、、


色々デバッグしたりしてもわからず、ネット検索でも特に引っかからず、参ったなぁとrailsのドキュメントを開くと……

> 一般に、非同期キュー（.deliver_laterでメールを送信するなど）はRakeタスクに書いても動きません。Rakeが終了すると、.deliver_laterがメールの処理を完了する前にインプロセスのスレッドプールを削除する可能性があるためです。この問題を回避するには、.deliver_nowを用いるか、development環境で永続的キューを実行してください。

https://railsguides.jp/active_job_basics.html#action-mailer

思いっきり書いてありましたorz
deliver_nowにしたら何事もなくメール飛んできました

```XxxxJob.rb
Mailer.send_mail(user).deliver_now
```

ちなみに`deliver_later`にしたのは、既存処理がそうなってて、まあ非同期の方がいいよね〜となんとなく引っ張ってきたからでした
というわけで、jobからメール飛ばす時は`deliver_now`を使いましょう
Refusing to install package with name "webpack" under a package

結論から言うと、package.jsonのnameがinstallしようとしているパッケージと同じ名前だとエラーが起きます。

```:ターミナル
 npm install --save-dev webpack
```

でエラーが起きました。

エラー内容は以下のようになります。

```
code ENOSELF
npm ERR! Refusing to install package with name "webpack" under a package
npm ERR! also called "webpack". Did you name your project the same
npm ERR! as the dependency you're installing?
npm ERR! 
npm ERR! For more information, see:
npm ERR!     <https://docs.npmjs.com/cli/install#limitations-of-npms-install-algorithm>
```

エラー3行目の` also called "webpack" ・・・` の部分より同じ名前のパッケージ名があることがわかりました。

```package.json
{
  "name": "webpack",  ←ここがwebpackになっている 
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

```

nameをwebpackdemoと書き換えることで無事エラーを解決できます。