OmniAICreator/Qiita-1.07M huggingface dataset:
[Rails] enumを使って下書き機能を作った

### はじめに
下書き機能を作ろうと思った時にあまり記事がなかったので記録として残しておこうと思いました。

### 開発環境
```
ubuntu(WSL)
Ruby 2,5.1
Rails 6.0.2
```


### 事前準備
以下の機能は作成済みとします。

- 投稿機能・詳細・削除・編集(Post)
- ユーザーの作成・詳細(User)

```models/post.rb
  belongs_to :user
```

```models/user.rb
  has_many :microposts, dependent: :destroy
```

### Postテーブルにカラムを追加する
まずはPostモデルにstatusカラムを追加しboolean型にします。
booleanでなくintergerでも可能です。
以下のコマンドを入力します。

```
bin/rails g migration AddStatusToPost status:boolean
```

マイグレーションファイルを編集します。

```migrationfile.rb
  def change
    add_column :microposts, :status, :boolean, default: true, null: false
  end
```
編集したらマイグレートします。

### Postモデルにenumを追加する。

```models/post.rb
  enum status: { draft: false, published: true }
```

statusカラムのdraft(下書き)をfalseに指定し、statusカラムのpublished(公開)をtrueに指定します

### ユーザーごとの情報を取得

`@user`でuserのidを取得。


```users_controller.rb
  #下書き用
  def confirm
    @user = User.find(params[:user_id])
    @microposts = @user.microposts.draft.page(params[:page])
  end

  #公開用
  def show
    @user = User.find(params[:id])
    @microposts = @user.microposts.published.page(params[:page])
  end

```

### ルーティングを追加
`collection` をつけるとURLにidが付かなくなります

```routes.rb
resources :users do
  get 'confirm'
end
```

### Viewの設定

関係あるところだけを抜粋しました。

```view/users/show.html.slim
//ユーザーの詳細画面
= link_to "投稿一覧", @user
= link_to  "お気に入り", user_likes_path(current_user)
= link_to "下書き一覧", user_confirm_path(current_user)

//自分の投稿を表示する
- if @microposts.present?
  = render "microposts/list", microposts: @microposts
- else
  h4 投稿はありません
```

下書き一覧は自分の好みに合わせて書いてください。

```view/users/confirm.html.slim
h4 下書き一覧

table.table.table-hover
  thead.thead-default
    tr
      th = Micropost.human_attribute_name(:title)
      th = Micropost.human_attribute_name(:content)
      th = Micropost.human_attribute_name(:created_at)
      th
  tbody
    - @microposts.each do |micropost|
      tr
        td = link_to micropost.title, micropost
        td = link_to micropost.content, micropost
        td

```
`icroposts/list`の中身は上記と同じです。

### 終わりに
間違いがありましたら編集リクエスト、コメントをお願いします。

### 参考文献
- [『Rails』enumを使って下書き記事と公開記事を保存できるようにした](https://pgmg-rails.com/blogs/21)
Catalina上でDocker for MacをSSL化

#前提

Docker for Macで開発中に、とあるAPIを利用しようとしたらlocalhostでSSLが無くて弾かれてしまったので、自分SSLを設定しようとした。

#問題（解決する途中で引っかかったもの）
・MacがCatalinaだった(10.15.3)おかげでHomebrewがすんなり使えない。
・XcodeのCommand Line Tools for Xcodeをインストールしてなかった。
・Docker for MacのRootディレクトリがどこにあるか分からなかった。

#解決方法
### Homebrewが全く使えない
```
$ brew doctor
```
でCatalinaを使っていること以外のWarningは一通り潰す。

https://qiita.com/ponsuke0531/items/10bca8aee7534bdefa1f
に習って、XcodeのCommand Line Tools for XcodeをDownloadしてインストールする。

で、どうしても引っかかるCatalinaの問題は、あちこちで紹介されているように

```
$ sudo chown -R $(whoami) $(brew --prefix)/*
```

で解決。この後、無事に

```
$ brew upgrade
```

できた。

### Docker for Macでルートディレクトリが分からない
次に
https://qiita.com/KingSky/items/c407829991cb18a52d99
を参考に、自分SSLを発行。

```
$ brew install mkcert
$ brew install nss

$ mkcert -install
$ mkcert hoge.local
```



で、どう使うのか見ていくと、、、そもそもルートディレクトリ ってどこ？問題にぶち当たる。

そこで行き着いたのがこちら。
https://qiita.com/uni-3/items/9e912d0d8aa87a398cfc
なんだけれど、（Docker for MacがVM上で動いていると初めて知りました。）
https://qiita.com/amuyikam/items/938781ff5898e654fd7c
ここで、ディレクトリの場所変わったよというのを発見し、組み合わせてやっつけてみる。





#参考リンク
・https://qiita.com/KingSky/items/c407829991cb18a52d99
・https://qiita.com/masajiro/items/5473160d89e5096f5b19
・https://qiita.com/3yatsu/items/47470091277d46f3fde2
・https://qiita.com/ponsuke0531/items/10bca8aee7534bdefa1f
VSコードでtypescriptをデバックする方法

VSコードでtypescriptをデバックする方法
https://qiita.com/yuzukaki/items/68ca1aed777b296145d5

VSコードの権限まわり
https://attakei.net/blog/2019/windows-vscode-venv/index.html


●デバック
VSでnpm startを行いnode.jsを起動する

●VSCコマンドパレット
コマンドパレットを表示するキーボードショートカットはWindows／Linuxでは［Ctrl］＋［Shift］＋［P］キー、OS Xでは［Shift］＋［Command］＋［P］キーだ。

●settings.json（ワークスペースを作成してポリシーを変更する。

PowerShell -ExecutionPolicy RemoteSigned


3. 安全・楽にactivateするには
上記の手法を取らなくても、実際には対応が可能となっている。

これは、

PowerShellの起動時には環境変数をちゃんとロードできる

VSCodeではターミナル起動時に環境を設定できる 3

PowerShellの実行ポリシーは、環境変数で切り替えることができる 4

という3点が成立するため、「settings.jsonに実行ポリシーに関する環境変数を設定する」ことで、容易に・他アプリへの影響を与えずに対応が可能となる。

{
  "terminal.integrated.env.windows": {
    "PSExecutionPolicyPreference": "RemoteSigned"
  }
}

●launchJSONに記載した
Launch TypeScriptを実行すること
Laravel6 認証機能 Authのセットアップ

Laravel6以降では、Auth機能を利用するために下記の二つをまず準備する必要があります

・laravel/ui
・Node.js(npm使用のため)


##１　Node.jsのインストール
下記のサイトからインストールを実施
https://nodejs.org/ja/

##２　laravel/uiのインストール
```
composer require laravel/ui
```
※コマンド実行場所は、laravelプロジェクトのディレクトリで。
デスクトップ上で、laravelappというプロジェクトを作成している場合
```C:\Users\PC_User\Desktop\laravelapp>composer require laravel/ui
```

##3　Auth機能関連のファイルを作成
```
php artisan ui vue --auth
```
上記のコマンドを実行すると、web.phpに
Auth::routes();
という、認証機能に必要なルーティングが自動で追加されたりする。
※laravel/uiがないと失敗するので、先にインストールは済ませておく

vendor
-laravel
上記のフォルダに　uiフォルダ　が作成されており、
RegisterUsers.phpとかはこの中に格納されている。


##4　最後に
```
npm install && npm run dev
```
を実行して完了。
windows10だと、完了時にPC画面の左下になんか表示が出ます。
※少し時間がかかります。

##5　確認してみよう
実際にログイン画面と登録画面にアクセスして確認してみましょう。
・登録画面
url
～/register

・ログイン画面
url
～/login

※localhostなら、localhost:8080/registerとか

認証機能のviewは、viewsフォルダのauthフォルダに生成されます。
SlackのtokenとAPI、botの種類をまとめた

Slackには様々な種類のTokenがあり、また複数の種類のAPIがあります。
Tokenに紐付いてBotが作成され、Botの種類によって利用できるAPIが違うので、それぞれは微妙に関わりがあります。

が、その辺りを分かっていないと、Legacy TokenとかClassic BotとかRTM APIとか何がなんだか分からなくなるのでまとめました。
(実際、ネット上でも混同させているような記事を見かけるので)

# Tokenの種類

(Bot関係は)主に3つ、Bot、Classic Bot、Legacyがあります。
https://api.slack.com/authentication/token-types

BotとClassic Botは利用できるAPIに違いがあります。

## Bot

Events APIを利用する最新のTokenです。様々なきめ細かいスコープ(権限)をコントロールでき、Slackとしてはこの種類のBotを推奨しているようです。

以下から普通に作成・管理することができます。
https://api.slack.com/apps

## Classic Bot

RTM APIを利用するTokenです。以下のリンクで管理することはできるのですが、その画面からは作ることができないので、探すことになります。

https://api.slack.com/apps

作成する場合は以下のリンク。
https://api.slack.com/apps?new_classic_app=1
または次のページなどから辿ることができます。
https://api.slack.com/authentication/basics#soon
https://api.slack.com/rtm#classic

## Legacy

既に2020/5/5をもって新規作成は行えなくなっており、既存のものを利用し続けるしかできません。
もしこの種類のTokenを使っている場合、Bot, Classic BotのTokenのどちらかへ切り替えることを検討したほうが良いでしょう。

https://api.slack.com/changelog/2020-02-legacy-test-token-creation-to-retire

もはや当時のことを覚えていませんが、以下を見ると、Legacy Tokenというだけで様々な権限がbotに付与され、あまり細かい権限をコントロールできないようです。(だからこそ廃止されたのでしょうけれども)
https://api.slack.com/legacy/custom-integrations/legacy-tokens

# APIの種類

## Events API or RTM API

どちらのAPIかで、使える種類が微妙に違います。

https://api.slack.com/events



どちらを利用すればよいかは以下に指針があります。

https://api.slack.com/faq#events_api

詳細は上記をご覧いただくとして、大まかな選び方は以下です。

* Events API
  * きめ細やかな権限管理を行いたい
  * Botをスケールアウトしたい(スケールアウトできる)
  * 外部にURLを晒すことが可能 (websocketを使うよりも)
  * リアルタイムの応答が不要
* RTM API
  * 外部にURLを晒せない
  * リアルタイムにデータ(メッセージ)を受け取りたい

※ 以下でもまとめています。
[Slack上で動くChatbotを実現するためのアーキテクチャを考える](https://qiita.com/tkit/items/6471d2436dd610f97a8d)

# 結局どのBotが良いのか(悪いのか)

Bot(with Events API)かClassic Bot(with RTM API)かは、Botの環境や実現したいことによるので、一概にどちらが良いとは言えないと思います。
特にURLを外部に晒す、Websocketと相性が悪いなど、環境的な要因によっていずれかを選ばなければならないことが多いように思います。

とりあえず現時点では、Legacy Tokenを利用しているBotはまずい、BotとClassic Botはどちらでもいい、という程度でしょうか。
Classic Botも、"Classic"だからといって、今後Deprecatedになると辛いなぁ…と思っています(現時点でそのようなアナウンスはありませんが)。
docker-compose ver2.* を使って buildで TypeError が出る人へ

# mem_limitを使いたかった。
ver 3.* では使えないので、2.2仕様に書き換えて docker-compose build

```
Traceback (most recent call last):
  File "/usr/bin/docker-compose", line 11, in <module>
    load_entry_point('docker-compose==1.17.1', 'console_scripts', 'docker-compose')()
  File "/usr/lib/python2.7/dist-packages/compose/cli/main.py", line 68, in main
    command()
  File "/usr/lib/python2.7/dist-packages/compose/cli/main.py", line 121, in perform_command
    handler(command, command_options)
  File "/usr/lib/python2.7/dist-packages/compose/cli/main.py", line 249, in build
    build_args=build_args)
  File "/usr/lib/python2.7/dist-packages/compose/project.py", line 343, in build
    service.build(no_cache, pull, force_rm, build_args)
  File "/usr/lib/python2.7/dist-packages/compose/service.py", line 923, in build
    shmsize=parse_bytes(build_opts.get('shm_size')) if build_opts.get('shm_size') else None,
TypeError: build() got an unexpected keyword argument 'stream'
```

* ぱいそん　の　えらー　が　あらわれた！

# 解決方法
最新のdockerで出るエラーの模様。

```
pip install 'docker<3.0'
```
でとりあえず治ります。

### 参考
https://github.com/ansible/ansible/issues/35612
【Mac向け】 今日から使えるVSCodeのショートカット

# はじめに
VSCodeには各種拡張機能や様々なショートカットキーが用意されています。
普段よりVSCodeを使って開発をしている私ですが、正直その性能のほとんどを使いきれていません。
しかし、周りの人々がキーボードから手を動かさずに手早く開発を行っているのを見て、自分も腰を据えてショートカットキーを使えるようになろうと思いました。

とはいえ、ショートカットキーの数はそれなりに多く、一度に覚えようとするとそれだけで時間が掛かってしまいます。
そこで、独断と偏見で**「これは今日からでも使える」**と思ったVSCodeのショートカットをまとめました。

# 対象読者
- ショートカットキーを使ってみたい人
- ショートカットキーを覚えるのが手間だと思って後回しにしている人
- 最近VSCodeに乗り換えたが、ショートカットキーが覚えらない人

# 今日から使えるショートカットキー
記号とキーの対応は以下の通りです。

**⌘ Command**
**⌥ Option**
**⇧ Shift**
**^ Ctrl**

## 選択・コピー・ペースト
|キー |動作 |
|---|---|
| ⇧←| カーソル左の文字を選択|
| ⇧→| カーソル右の文字を選択|
|⌘c |カーソル行をコピー（選択中の文字をコピー）  |
| ⌘v |貼り付け |
| ⇧⌥↑ |カーソル行を上にコピー |
| ⇧⌥↓ |カーソル行を下にコピー |
| ⌘⇧l |選択中の文字列と一致する文字列を全て選択 |

## 行やインデントの追加・削除・移動
| キー  |動作 |
|---|---|
|⌘⇧ Enter | カーソル行の上に行を追加|
| ⌘ Enter |カーソル行の下に行を追加  |
| ⌘⇧ k |カーソル行を削除 |
| ⌘] |カーソル行にインデントを追加 |
| ⌘[ |カーソル行のインデントを削除 |
| ⌥↑ |カーソル行を上に移動 |
| ⌥↓ |カーソル行を下に移動 |
## カーソル移動
| キー  |動作 |
|---|---|
| ⌘←|カーソル行の先頭に移動 |
| ⌘→|カーソル行の末尾に移動 |

## 検索・置換
| キー  |動作 |
|---|---|
| ⌘f|検索ウインドウを開く |
| ⌘g| 次を検索|
| ⌘⇧g|前を検索 |
|⌥⌘f|文字列を置換|
## ウインドウ操作 
| キー  |動作 |
|---|---|
|⌘\ |エディタを分割 |
|⌘1 |左のエディタにフォーカス |
|⌘2 |右のエディタにフォーカス |
|⌘w |現在のウィンドウを閉じる |
|⌘⇧w |全てのウィンドウを閉じる |
|⌘⇧[|左のタブに移動 |
|⌘⇧]|右のタブに移動 |

## 保存
| キー  |動作 |
|---|---|
|⌘s |ファイルを保存 |
|⌘⇧s |名前をつけて保存 |

# 最後に
今回は「今日から使えるVSCodeのショートカットキー」ということで筆者の独断と偏見で使用率の高そうなものをいくつかまとめました。
VSCodeのショートカットについてまとめてくださっている記事のリンクを[参考](#参考)に貼っていますので、さらに多くのショートカットを覚えたいという方はそちらを参考にされたら良いかと思われます。

# 参考
- [【Windows版】VS Code キーボードショートカット一覧 （オススメ付き）](https://qiita.com/TakahiRoyte/items/cdab6fca64da386a690b)
- [【Mac版】 VisualStudioCode キーボードショートカット](https://qiita.com/naru0504/items/99495c4482cd158ddca8)
- [VS Code の便利なショートカットキー](https://qiita.com/12345/items/64f4372fbca041e949d0)
- [【Mac向け】VSCodeで必ず覚えておきたいショートカット集](https://qiita.com/1coin178/items/1cfa68c41a4e098ea8ae)
docker: mongodb

## image
```.sh:terminal
docker pull mongo
```

## localhost:27017でDBに接続する場合
### docker
```.sh:terminal
# launch
docker run --name mongodb -p 27017:27017 -v `pwd`/db:/data/db -d mongo

# stop
docker rm -f mongodb

# shell
docker exec -it mongodb mongo
```

### docker-compose
```.yml:docker-compose.yml
version: '3.8'
services:
  db:
    image: mongo
    container_name: mongodb
    ports:
      - 27017:27017
    volumes:
      - ./db:/data/db
```

```.sh:terminal
# launch
docker-compose up

# stop
docker-compose down
```

### 他のdockerコンテナから直接アクセスする場合

例、dockerコンテナで動くnode.jsアプリ(localhost:3000でアクセス)から、mongodbに、`mongodb://db:27017` でアクセスする
### docker-compose
```.yml:docker-compose.yml
version: '3.8'
services:
  web:
    image: node:alpine
    working_dir: /home/node/app
    volumes:
      - ./:/home/node/app
    ports:
      - 3000:3000
    command: ash -c "npm run build && npm start"
  db:
    image: mongo #portsの指定は不要.
    volumes:
      - ./db:/data/db
```

```.sh:terminal
# launch
docker-compose up

# stop
docker-compose down
```

```.ts:サンプルコード.ts
import { MongoClient, Collection } from 'mongodb'

const URL = 'mongodb://db:27017'
const NAME = 'mongodb'

export async function insertDocument(collectionName: string, document: object) {
  await crudCollection(
    collectionName,
    async (collection) => await collection.insertOne(document)
  )
}

export async function findDocuments(
  collectionName: string,
  filter: object
): Promise<any[]> {
  return await crudCollection(
    collectionName,
    async (collection) => await collection.find(filter).toArray()
  )
}

export async function updateDocument(
  collectionName: string,
  filter: object,
  newDocument: object
) {
  await crudCollection(
    collectionName,
    async (collection) =>
      await collection.updateOne(filter, { $set: newDocument })
  )
}

export async function deleteDocument(collectionName: string, filter: object) {
  await crudCollection(
    collectionName,
    async (collection) => await collection.deleteOne(filter)
  )
}

/**
 * @private
 */
async function crudCollection(
  collectionName: string,
  method: (collection: Collection<any>) => Promise<any>
) {
  let client: MongoClient
  try {
    client = await MongoClient.connect(URL, { useNewUrlParser: true })
    const collection = client.db(NAME).collection(collectionName)
    return await method(collection)
  } finally {
    client.close()
  }
}

```
「tag:ショートカット tag:ショートカットキー」と「tag:ショートカットキー  tag:ショートカット」はqiita内検索結果は同じ。たぶんです。

「tag:ショートカット」に「tag:ショートカットキー」の全てのページは、含まれません。たぶんです。
私は、髪型を想定していません。keyboard-shortcutsの意味でした。


（参考）タグ一覧(アルファベット順)【直近１年間/上位25,000タグ】【毎日自動更新】
https://qiita.com/j5c8k6m8/items/6b15a81204a1d458e392
（参考）Windows のキーボード ショートカット
https://support.microsoft.com/ja-jp/help/12445/windows-keyboard-shortcuts
投稿ページのビュー画面を直す

アウトプット用です。
今回はこちら<img width="1411" alt="18c7038dfaec3788b2be3c423fd05bc2-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653208/b66d8094-d4ed-f41f-5c59-115b5026081d.png">

投稿はできているが、何故はみ出るんだ？
インデントも問題無い

```top_page>index.html.haml
.top
  %ul.top__side
    ジャンル
    %li.top__side__love
      恋愛
    %li.top__side__work
      仕事
    %li.top__side__money
      お金
    %li.top__side__friend
      友人
    %li.top__side__school
      学校
    %li.top__side__other
      その他
  .top__consultation
    .top__consultation__title
      お悩み一覧
    .top__consultation__text
    - @toppages.each do |top_page|
      = top_page.contents
      .top__consultation__text__time
        = top_page.created_at
```

色々試行錯誤した結果each文の後が元の定義したクラスの中に収まらないことが判明しました。
これ、何ででしょうかね？？

ということでそれならとeach文を一番最初につけました

```top_page>index.html.haml
- @toppages.each do |top_page|
  .top
    %ul.top__side
      ジャンル
      %li.top__side__love
        恋愛
      %li.top__side__work
        仕事
      %li.top__side__money
        お金
      %li.top__side__friend
        友人
      %li.top__side__school
        学校
      %li.top__side__other
        その他
    .top__consultation
      .top__consultation__title
        お悩み一覧
      .top__consultation__text
        = top_page.contents
        .top__consultation__text__time
          = top_page.created_at
```

割愛してますが、インデントを最初の"top"と合わせたらSyntaxError
エラーになったので地味に気をつけたいところ。全て１個インデントを下げる必要があります（当たり前だけど）

<img width="1416" alt="adb62a3f262ca3cb8d40312aba48b4f8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653208/21aa5ee3-c710-83cc-c340-2b6207aa008d.png">


ということで解決です。
ただ何故はみ出てしまうのか原因はわかりましたが、言語化できません。
htmlのルールと言ってしまえば終わりな気はしますが。

訂正
修正したコードで複数投稿したら一番上にeach分があるためにお悩み一覧や左のカテゴリまで
全て表示されていました汗
正しくは下記ですね


```top_page>index.html.haml
.top
  %ul.top__side
    ジャンル
    %li.top__side__love
      恋愛
    %li.top__side__work
      仕事
    %li.top__side__money
      お金
    %li.top__side__friend
      友人
    %li.top__side__school
      学校
    %li.top__side__other
      その他
  .top__consultation
    .top__consultation__title
      お悩み一覧
    - @toppages.each do |top_page|
      .top__consultation__text
        = top_page.contents
        .top__consultation__text__time
          = top_page.created_at
```

ただ要領は変わらないですね。インデント一個下げただけであっさり解決しました笑
MySQLdb(mysqlclient) cursor.execute()でカラム名に変数を指定する

## 環境
##### SQLサーバー
OS: Archlinux
SQL サーバー: mysql  Ver 15.1 Distrib 10.4.13-MariaDB, for Linux (x86_64) using readline 5.1
##### クライアント
OS: Windows 10 build 1909
言語: Python 3.8.4rc1
SQLクライアント: mysqlclient 2.0.1

## ハマったところ
このように書きたかった

```Python3
hash_type = 'md5'
fpath = '/home/me/test.txt'
hash = '0123456789ABCDEF0123456789ABCDEF'

connection = MySQLdb.connect(...略...)
cursor = connection.cursor()
cursor.execute(
    'UPDATE hashes (path, %s) VALUE (%s, %s);',
    (hash_type, fpath, hash)
)
```

次のようなエラーが出る

```TEXT
MySQL Error [1064]: You have an error in your SQL syntax; ...(略)...
```

このときのSQL文は

```SQL
UPDATE hashes (path, 'hash_type') VALUE ('fpath', 'hash');
```

## 原因

カラム名に引用符``''``が含まれているから

## 解決

次のように引用符を取り除いたSQL文を与える

```SQL
UPDATE hashes (path, hash_type) VALUE ('fpath', 'hash');
```

execute()の引数ではなくSQL文にformat()を用いて文字列に置き換える

```Python3
cursor.execute(
    'UPDATE hashes (path, {}) VALUE (%s, %s);'.foramt(hash_type),
    (fpath, hash)
)
```
Google Colab 上でKaggleを使う際、バージョンのアップグレードができない時の対処法

[Google Colab上でKaggleのデータをロード、モデル訓練、提出の全てを行う](https://qiita.com/katsu1110/items/a8d508a1b6f07bd3a243)
上記の記事を参考に、
Google Colab上でKaggleのデータをダウンロードできるように設定していたところ、詰まったところがあったためメモとして残しておく。

Kaggleのインストールまで行い、いざデータをダウンロードしようとすると

**Looks like you're using an outdated API Version, please consider updating (server 1.5.6 / client 1.5.4)**

上のようなエラーが出た。どうやらKaggleのバージョンが古いためアップグレードしてくれということらしい。そのため以下のようにアップグレードしようとしたところ

`!pip install kaggle --upgrade`
`!kaggle -v`
`Kaggle API 1.5.4`

何故かアップグレードすることができなかった。

###対処法###

最終的には[こちら](https://stackoverflow.com/questions/58643979/google-colaboratory-use-kaggle-server-version-1-5-6-client-version-1-5-4-fai)を参考にして

`!pip install --upgrade --force-reinstall --no-deps kaggle`
`!kaggle -v`
`Kaggle API 1.5.6`

強制的に再インストールすることで解決した。どうやらpython2の古いパッケージをインストールしてしまっていることが原因らしい。(詳しくは上記リンクをご覧ください)
MySQLのrootの初期パスワードについて

VPSでLAMP環境構築中、初期設定でrootのパスワードを設定しようとしたところ、パスワードなしでMySQLを使用することができず
調べたところバージョン5.7以降は自動生成されるようになったとのこと。

参考記事を見てみると/var/log配下のmysqld.logにパスワードが出るとのことで確認してみる

#どうしてこうなった

###構築環境

**VPS:さくらのVPS
OS:CentOS7
MySQL:バージョン8.0**

記事では上述の通り/var/log/mysqld.logに自動生成された一時パスワードが出力されると記載があったのですが・・・

```
[root@Tristar ~]# ls -la /var/log | grep mysqld
-rw-r-----   1 mysql  mysql          0 Jul 12 12:11 mysqld.log
[root@Tristar ~]# 
```

**0バイト**
ログ出力されてねぇ・・・

起動していないのかと思いrestartさせるもログファイルのサイズが変わらず
一旦、statusを確認してみると

```
[root@Tristar ~]# systemctl status mysqld
* mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2020-07-12 12:13:37 JST; 2h 31min ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 23317 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 23396 (mysqld)
   Status: "Server is operational"
   CGroup: /system.slice/mysqld.service
           `-23396 /usr/sbin/mysqld

Jul 12 12:13:33 ik1-301-10960.vs.sakura.ne.jp mysqld_pre_systemd[23317]: 2020-07-12T03:13:33.681328Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
Jul 12 12:13:34 ik1-301-10960.vs.sakura.ne.jp mysqld_pre_systemd[23317]: 2020-07-12T03:13:34.720654Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: j!l,>g)*w7oU
[root@Tristar ~]#
```

何故かログに出力されずにstatusのlogの部分に***[Note] [MY-010454] [Server] A temporary password is generated for root@localhost: j!l,>g)*w7oU***の記載が

今度からはログファイルではなくstatusで確認したほうがよさそうです。

#参考記事
[MySQLの初期パスワードのありか](https://qiita.com/RyosukeSomeya/items/c695487588f5ac28d9f4 "MySQLの初期パスワードのありか")
画像はアップロードされたのに、画面には表示されない！？

# 困ったこと

Spring Bootを使って、画像をアップロードする。
アップロード直後は画像がHTML上に表示されず、30秒程待って画面をリフレッシュすると表示される。

# 画像のアップロード方法
画像ファイル -> /resource/static/images/配下
ファイル名(xxx-20200712151409.jpgなどのファイル名) -> DBに格納

#　解決方法
1. ルートフォルダ直下にフォルダ（仮に、imagesとする）を作る
今回は、RamenKingdomというルートフォルダの直下にimagesを作成しています。
![スクリーンショット 2020-07-12 15.17.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577071/7ecb1f23-36ef-4c78-cc04-9b5ee36063db.png)



2. WebConfigurationクラス（仮に、AdditionalResourceWebConfigurationとする）を作成

```java
@Configuration
public class AdditionalResourceWebConfiguration implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("file:images/");
    }
}
```

あとは、画像を格納していたコードをルートフォルダ直下のimagesに変更するだけ。 
ただし、HTML上では、下記のようにする必要があります。

```html

<img th:src="@{'/images/' + ${picture.filepath}}"/>
```

# まとめ

今回のように動的に変化するファイルはstatic配下には格納しない！！！

以上です。最後まで読んでくださり、ありがとうございました。
angularのまとめ

●環境設定


nod.js エキスプレスサーバーの場所
C:\Users\shimizu\Desktop\nodejs-test

nod.js
express
etc

? Would you like to share anonymous usage data with the Angular Team at Google under
Google’s Privacy Policy at https://policies.google.com/privacy? For more details and
how to change this setting, see http://angular.io/analytics.

⇒共有したくないのでNを押す



npm init　⇒必要
npm install body-parser --save
npm install cookie-parser --save
npm install multer --save



npm install -g @angular/cli
デフォルトだと
 C:\Users\shimizu\AppData\Roaming\npm\node_modules\
@angular\cli\bin　に入る

														
ng new my-store
DOSプロンプトだとC:\Users\shimizu>だと上手くいった、パワーシェルだとどうかわからない


※注意点　サーバーを動かす場合などは、JSONファイルがあるカレントドライブで起動する必要がある
　コマンドラインの基礎を勉強するとよいかも


ngサーバー起動方法
cd C:\Users\shimizu\my-store
ng serve --open

TOPバーのインストール
ng g component top-bar


Styles.css

width: 100%;がエラーになったらこちらに変更する。

★デプロイはまだ

エラー
cart.component.htmlの商品の出力が抜けている。



●チェットアプリ
cd C:\Users\shimizu\my-store\chat-app>

●IONICサーバ起動
Visual Studio Codeのコンソールを開いて、以下のコマンドを実行すると、ログイン画面が表示されることを確認出来ます。
駄目ならコマンドラインでも起動OK

ionic serve

●VSコードで管理権限の渡し方
【ターミナル内コンソールが実行できない場合】
PowerShell -ExecutionPolicy RemoteSigned
※権限付与で実行する


●デバック
VSでnpm startを行いnode.jsを起動する
JavaScript(日付)

##JavaScript日付取得一覧

```ruby:js
var dt = new Date();

//年
var year = dt.getFullYear();

//月
var month = dt.getMonth()+1;

//日
var date = dt.getDate();

//曜日
dateT = ["日","月","火","水","木","金","土"];
var day = dateT[dt.getDay()];

//時
var hours = dt.getHours();

//分
var minutes = dt.getMinutes();

//秒
var seconds = dt.getSeconds();
```


参考資料: https://www.sejuku.net/blog/22867
Mac OSのUSキーボード環境で、エレコム マウスアシスタントの「戻る」「進む」ボタンが動作しない


[DEFT PRO](https://www.elecom.co.jp/products/M-DPT1MRBK.html)を買いました。愛用していたMS Trackball Explorerが廃盤になってしまった頃以来のトラックボールです。

DEFT PROを買うにあたって特に良いなと思ったというか、これしかないとなったメリットが以下です。

- 「人差し指トラックボール」 **&** 「有線、2.4GHz無線、Bluetoothの３対応」

この2点をクリアしてるのはDEFT PROだけでした。

接続方式が3種類に対応しているおかげで、自宅のMacbookProはBluetooh接続で、お仕事先のWindowsは2.4GHz無線接続と、どちらでも使うことができます。
無線のトラックボールが欲しかったんですけど、2.4GHzかBluetoothのどちらかにしか対応していない製品が多かったので複数PC間で同じマウスを使いたい自分としてはDEFT PROしかないとなったわけです。
（Windowsも普通Bluetooth対応してるだろ？と思われると思いますが、お仕事先のPCではセキュリティのため使えなくされています）

## 解決したい問題

戻る・進むボタンが動作しない。

![](https://i.imgur.com/DQuK22e.png)

エレコム マウスアシスタントをインストールしますとデフォルトでボタン4に`Safari:戻る`、ボタン5に`Safai:進む`が設定されています。

ところがボタンを押しても動きません。名称の通りSafari専用でChromeで試しているからかと考えましたがSafariでもだめでした。



## 解決

以下のように設定しましょう。

![](https://i.imgur.com/oTDDZV4.png)
上記画像のように設定すれば、ボタン4に`戻る`、ボタン5に`進む`が設定されます。

---

## 調べたこと

任意キー設定で、`戻る`のショートカットーキーである`⌘ + [`を設定しましたが、なぜか`進む`動作となりました。
で、JISキーボードとUSキーボードだと`[`と`]`は位置が一つずれていたなと思い出したので、USキーボード設定で同じような現象が起きてる事例がないか調べました。

> 任意キーで"@"を選択すると" [ "が押せることを発見したので自己解決しました．
ref: [マウスアシスタントの不具合について](https://bbs.kakaku.com/bbs/J0000017504/SortID=23482055/#tab)

予想は的中したようです。JISキーボードの`@キー`の位置がUSキーボードの`[キー`の位置です。
エレコム マウスアシスタントはスキャンコードではなくキー位置を示す値で判断をするロジックになっているみたいですね。


下表は設定の関係性をまとめたものです。


| ボタン | 動作 | ブラウザ上の<BR>ショートカットキー | USキーボードで対応する<BR>ショートカットキー |
|:--|:--|:--|:--|
|ボタン4 | 戻る | ⌘ + [ | ⌘ + @ |
|ボタン5 | 進む | ⌘ + ] | ⌘ + [ |
地理院 dspPos と Mapbox text-anchor のロゼッタストーン

Mapbox GL JS でポイントデータから注記を出すときに、点とテキストとの関係を設定するためには [symbol レイヤのレイアウトプロパティである text-anchor](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#layout-symbol-text-anchor) を使います。

<img width="991" alt="ise.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/aad8e518-1c14-8067-6cb4-7b3277b5ff14.jpeg">

このプロパティの値と、国土地理院の[多言語化用ベクトルタイルデータ](https://www.gsi.go.jp/common/000212661.pdf)の `dspPos` の値との対照表を作ると、次の通りです。

| anchor point closest to | 地理院 `dspPos` | Mapbox `text-anchor` |
| --- | --- | --- |
| the center of the text | CC | center |
| the left side of the text | LC | left |
| the right side of the text | RC | right |
| the top of the text | CT | top |
| the bottom of the text | CB | bottom |
| the top left corner of the text | LT | top-left |
| the top right corner of the text | RT | top-right |
| the bottom left corner of the text | LB | bottom-left |
| the bottom right corner of the text | RB | bottom-right |

## 参考: HOCON 実装
地理院 dspPos を含むデータを Mapbox GL JS で表示する想定で、上記の対応づけを HOCON で表現してみると、次のようになると思います。何らか機会を見つけたら、試してみようと思います。

```hocon
[
  match
  [
    get
    dspPos
  ]
  CC
  center
  LC
  left
  RC
  right
  CT
  top
  CB
  bottom
  LT
  top-left
  RT
  top-right
  LB
  bottom-left
  RB
  bottom-right
  center
]
```

※異常値があったときには center にデフォルトするようにしました。
またファイル末尾の改行挿入を忘れてしまった…

# しょうがないね
じゃあ済まないので、エディターさんに「保存時に自動的に改行を挿入する」設定を追加して頑張ってもらうことにしました。

今回は私が普段使っている「VSCode」と「Eclipse」に設定してみました。

## VSCode
「設定」→「`insertFinalNewline`で検索」→チェックをつける
![VSCodeの末尾改行挿入設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586524/0686d4ad-41b7-2f60-3439-ef7191d0032b.gif)

## Eclipse
「設定」→「一般」→「エディタ」→「AnyEditツール」→「自動変換」タブの「ファイルの末尾に改行を作成」にチェックをつける→「適用して閉じる」で閉じる
![Eclipseの末尾改行挿入設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586524/78b3168c-f71b-50f0-7a28-3741761f010c.gif)
[Windows][Docker] nodeコンテナでnpm installがハングアップする件の対策



nodeにgulpやらbabelやらonsen-uiやら大量にインポートしたサーバーアプリケーション。
いままでVagrantで動いていたこの環境を、Dockerコンテナ化するタスクを受けました。
加えてマルチOS（Windows, Mac, Linux）で動作する必要があります。

# 現状

* ルートディレクトリに package.json は残っていました。
* /node_modules はありませんでした。<br />
（そもそも、違う環境の /node_modules は（環境依存モジュールが有る可能性があるので）流用する気はないですけれども）


# package.json をたよりに npm install を実行してみた

* Mac ... 動いた。
* Linux ... 動いた。
* Windows ... 全然動かない。

```
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /xxxxxxxxxxx/xxxxxxxxxxx/xxxxxxxxxxx
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/xxxxxxxxxxx/xxxxxxxxxxx/xxxxxxxxxxx'
... 
```

```
npm ERR! Maximum call stack size exceeded
```

```
"Failed to load external module @babel/register"
```

これらのエラーが途中で無秩序に発生します。
上記３種のエラーが出て止まればまだマシな方で、最悪、Docker Desktopがハングアップします。

なおコマンドインターフェース上のプログレス表示の傾向としては、<br />

* 最初は快速にnpm installが進行していきますが、
* だんだん遅くなり、
* やがてハングアップします。

現象の傾向から、メモリリークを大リファクタリングした昔の仕事をなんとなく思い出しました。

# トライアンドエラー

ネット上には一見似たような事例が散見されるのですが、

* npm install --no-bin-links
* rm -f package-lock.json
* docker desktopの性能設定を上げる
* npm cache clean --force
* .npmignore を作る
* npm rebuild
* npm config set registry http://registry.npmjs.org/
* package.jsonをすべて手書きのnpm installにする

これらを全部やってみましたが、ダメでした。

# 結果的対処方法

割と泥臭い対応で対応しました。

1. docker-nodeコンテナのワークディレクトリをdocker-compose.ymlなどでvolumeマウントしておく。
1. コンテナの中のシェルにログオンする。
1. /node_modules は絶対削除せずに、何度も`npm install`する。（コンテナの外から直接`docker-compose exec`で`npm install`を実行しない）
1. インストール済のモジュールは飛ばされるので、徐々に/node_modulesの中身が充足していきます。
1. 完成した /node_modules を（volumeマウント経由でdockerコンテナから確保し、）/windows_node_modules などとして確保しておく。
2. ビルドスクリプトを修正し、次回からは npm install を実行させるのではなく、/windows_node_modules を `mv windows_node_modules node_modules` で済ませるようにする。
pythonで解く足し算の覆面算

足し算の覆面算を解きます。可能な解を全て出力します。総当りのアルゴリズムではありません。

pythonで書かれていますが、もっと良いコーディングがあると思います。
アルゴリズムは、奥村晴彦著、「C言語による最新アルゴリズム事典」に依ります。

コードに実行権限を付け、例えば、`./fukumen.py SEND MORE MONEY`のように、コマンドラインに覆面算の各文字列を指定して実行して下さい。

```fukumen.py
#!/usr/bin/python3
import sys

N = 128
s = "0123456789ABCDEFGHIJKLMNOPQRTSUVWXYZ"
word = [['' for i in range(N)] for j in range(128)]
digit = [0 for i in range(len(s))]
l = [0 for i in range(len(s))]
ok = [False for i in range(10)]
ii = 0
jj = 0
carry = 0
solution = 0


def found():
    global solution
    solution += 1
    print("\n解 %d" % solution)
    for i in range(imax):
        if (i == imax-1):
            print("-"*jmax)
        for j in range(jmax):
            k = jmax-1-j
            c = word[i][k]
            if (c == ''):
                print(" ", end="")
            else:
                print("%d" % digit[s.index(c)], end='')
        print("")


def tr(sum):
    global ii, jj
    w = word[ii][jj]
    c = 0 if w == '' else s.index(w)
    if (ii < imax-1):
        ii += 1
        d = digit[c]
        if (d < 0):
            d = l[c]
            while(d <= 9):
                if (ok[d]):
                    digit[c] = d
                    ok[d] = False
                    tr(sum+d)
                    ok[d] = True
                d += 1
            digit[c] = -1
        else:
            tr(sum+d)
        ii -= 1
    else:
        jj += 1
        ii = 0
        carry, d = divmod(sum, 10)
        if (digit[c] == d):
            if (jj < jmax):
                tr(carry)
            elif (carry == 0):
                found()
        else:
            if (digit[c] < 0 and ok[d] and d >= l[c]):
                digit[c] = d
                ok[d] = False
                if (jj < jmax):
                    tr(carry)
                elif (carry == 0):
                    found()
                digit[c] = -1
                ok[d] = True
        jj -= 1
        ii = imax-1


argv = sys.argv
argv.pop(0)
imax = len(argv)
jmax = max(map(len, argv))

for i in range(imax):
    argv[i] = argv[i].upper()
    l[s.index(argv[i][0])] = 1
    a = argv[i][-1::-1]
    for j in range(len(a)):
        word[i][j] = a[j]
        c = word[i][j]
        if (c.isalpha()):
            digit[s.index(c)] = -1
        elif (c.isdigit()):
            digit[s.index(c)] = int(c)
        else:
            print("Invalid parameter.")
            exit(1)

for i in range(10):
    ok[i] = True
tr(0)
if (solution == 0):
    print("解はありません。")
exit(0)

```

#実行例

```
$ ./fukumen.py send more money

解 1
 9567
 1085
-----
10652



$ ./fukumen.py five seven eleven twelve fifteen twenty seventy

解 1
   3209
  59094
 969094
 819609
3238994
 819487
-------
5909487


```
windowsでも快適にPowerlineフォント+fish shellで生活がしたい！


# TL;DR
shellの見た目をきれいにして、補完できるようにするとテンションが上って作業効率が上がる
(ほんまか？)




# はじめに
Windows10のアップデートでWSL2が使えることに歓喜している方も多いと思います。
せっかくLinuxのシェルを不自由なく使用できる状態になっているので、fishやpowerline-fontを使って、たのしいLinuxシェル生活を遅れるようにしていきましょう。

今回は、WSL2 Ubuntu 20.04へ `fish` を導入後、 powerlineフォントを適用して見た目がおしゃれになるところまでやります。

**こんなかんじのが**
![設定前.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407001/3e9f1bbe-8b76-b158-c5ac-4f6fa8a78de5.png)

**おしゃれになります。**
![設定後.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407001/e3aec7a5-3f05-8c71-f97a-0c74e73a087d.png)

関係する資料、リポジトリ類はこちら。
- https://powerline.readthedocs.io/en/latest/
- https://github.com/powerline/fonts
- https://github.com/fish-shell/fish-shell


# 1. WSL2のインストール
今回は説明を省きます。
Windows10 のアップデートなどを適用して、WSL2を使用できる状態までセットアップしてください。

# 2. WSL2対応のディストリビューションをインストール
今回はUbuntu2004を使用します。
Storeからインストール。
インストール後、WSL2モードで起動することを確認してください(wsl -l -v)

# 3. WSL2のセットアップ
今回は、fishでpowerline-fontを使うよう設定していきます。
fish以外にお好みのシェル、bash、zsh等がある場合は適宜読み替えたり、ファイルを変更したりしてください。

また、下記の手順の前に、一度aptをupdateしておくことを忘れずに実施してください。

```shell
$ sudo apt update
```

## 3.1 powerlineのインストール
python3、pip-3などからインストールすることも可能ですが、今回はaptからインストールします。

```sh
$ sudo apt install powerline
```
```sh
$ powerline --version
```

で、ヘルプ類が出ることを確認

```sh
$ cd /usr/share/powerline/bindings
$ ls -l
```
でfish用のbindingスクリプとがあることを確認して終わり。


## 3.2 fishの設定
### fish shellのインストール

```sh
$ sudo apt install fish
$ fish --version
```
これでfishのインストールが完了です。fishコマンドを打つと、fishに切り替えることができます。
fishは補完、テーマの変更などが可能な便利なシェルです。powerlineを適用せずとも、十分に便利。

### fishのカスタマイズ
configファイルの場所に移動

```sh
$ cd ~/.config/fish
```

config.fishファイルが存在しているか、確認

```sh
$ ls -l
```

ない場合は、touchで作成

```sh
$ touch config.fish
```

起動時に、この config.fishが読み込まれるようになっているので、このconfig.fishファイルにpowerlineを使うよ、ということを書く。

参考 : [Shell prompts — Powerline beta documentation](https://powerline.readthedocs.io/en/latest/usage/shell-prompts.html#fish-prompt)

```sh
vim config.fish
```

```sh
set fish_function_path $fish_function_path "/usr/share/powerline/bindings/fish"
powerline-setup
```

---

以上で、設定は終了です。
fishを起動して、見た目が変わっていることを確認してみてください。

※文字化けしている場合は、下記の対処方法を確認してみてください。

今回は説明しませんが、WSL2のシェルでは、fishへのプラグイン導入や、StarShipなどのおしゃれシェル拡張をいれることも可能になりました。

今まで、WindowsのPowershell、GitBash、CygWinだからおしゃれシェルつかえない！！と嘆いていた方も、一度ためしてみてはいかがでしょうか。


**追記**

実際に使ってると、それなりのサイズのgitリポジトリを見ようとするとクソ重たくなるので使い物になりません。
下記の記事などを参考にしてgitオプションをoffにしたりしてください。
[【WSL】Powerline入れたら死ぬほど遅くなった人へ - Qiita](https://qiita.com/willco21/items/fb198bb10b51fd7b0723)

---

# ※文字化けしている場合
windows側にpowerlineフォントがインストールされていない場合は文字化けする可能性があります。

こちらのリポジトリから、powerline対応のフォントをダウンロードし、ttfファイル、otfファイルからフォントをインストール。
https://github.com/powerline/fonts


WSL2のターミナルを開いて、左上のマークをクリックして、「既定値」　「プロパティ」をそれぞれ開いて、設定。
フォントを、先程インストールしたPowerlineフォントに設定する。(DejaVu Sans Mono for Powerline、など)

ターミナルを再起動し、再度fishコマンド実行。
【学生向け】二次関数　その１

#読んで欲しい人
- 二次関数を勉強している人

#目標
- 二次関数の形がわかる

#目次
1. 二次関数の形
2. まとめ

#1. 二次関数の形
まずは二次関数の基本、$y=x^2$のグラフをみましょう。
![figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289374/ec4441bd-264d-29dd-51fd-a6b2f84cccee.png)

ポイントは
1. **(0,0)が頂点であること**
2. **下に凸であること**
です。

今度はこの二次関数のグラフの$x$の前にいくつか数字をつけてグラフがどう変わるかみてみましょう。
$x$の前に$2$や$1/2$をかけてグラフを書くとこうなります。![figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289374/21cffc17-5bc2-eda0-58b7-3e3843454de8.png)

いかがでしょうか？

- $2$をかける（緑グラフ）と元の青いグラフよりスリムになっている
- $1/2$をかける（赤グラフ）と元の青いグラフより広がっている
ことがみて取れるのではないでしょうか。

そして先ほどのポイント
1. **(0,0)が頂点であること**
2. **下に凸であること**
に変化はないことも確認できると思います。

では次に負の数をかけるとどうなるでしょうか。
![figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289374/a030260e-a212-e7c8-2a0b-17bae024cf93.png)

このグラフでは今まで出てきた
$y=x^2$,
$y=2x^2$,
$y=0.5x^2$
に対してそれぞれ
$y=-x^2$,
$y=-2x^2$,
$y=-0.5x^2$
というようにマイナスをかけてグラフにしました。

何が読み取れるでしょうか。
$y=x^2$と$y=-x^2$,
$y=2x^2$と$y=-2x^2$,
$y=0.5x^2$と$y=-0.5x^2$
のグラフがそれぞれ
**x軸（$x=0$）の線を中心に対称になっている**
のがわかるかと思います。

先ほどのポイント
1. **(0,0)が頂点であること**
2. **下に凸であること**
のうち
1番は維持されていますが、
２番は「上に凸」に変わったこともわかるのではないでしょうか。


#2.まとめ
$y=x^2$のグラフは
1. **(0,0)が頂点である**
2. **下に凸である**

**$x$の前に数字をつけるとスリムになったり太ったりする**
**$x$にマイナスをかけるとx軸を中心に対称になる**

ことがイメージできれば今回の目標は達成です。
お疲れ様でした。
フロント側でAPIからのSet-Cookieを無効にする方法

# 背景
[devise](https://github.com/heartcombo/devise)を使って作成したRails製Webアプリのモバイルアプリ版を作成するため、[devise-token-auth](https://github.com/lynndylanhurley/devise_token_auth) でトークン認証出来るようにしようとしたところCookieが効いて別のユーザー情報が返ってきてしまう。

# やっていたこと
devise-token-authで作成したエンドポイントをフロントから叩いてチェックしていました。
直接curlで叩いたら上手くいくのに....

# 解決策
```
import { NativeModules } from 'react-native';

NativeModules.Networking.clearCookies(() => { });
```

参考記事そのままですが、フロント(ReactNative)側でこのようにするとAPIから送られたCookieがフロント側でクリアされ期待した通りの動作をするようになりました。

今回はフロント側で対応しましたが、バックエンド側でdevise-token-authのcontrollerをオーバーライドして対応することも出来るようです。

# なぜCookieが保存されていたか
ネイティブアプリではデフォルトでCookieが保存されるようです。
ちなみに、RailsのAPIモードではデフォルトでCookieが使えないようになっているものの、今回は既存のWebアプリにdevise-token-authでトークン認証をつけようとしていたためCookieが渡されるようになっていました。


# 参考記事
https://qiita.com/kakken1988/items/504e679504b9e710cf21

### ちなみに
[Memopic](https://memopic.herokuapp.com/)というアルバム・写真共有サービスを作っています。是非使ってみてください！
ご意見・ご要望などあればこちら(memopic.bamboo@gmail.com)までお願いします。

ここだけでなくdevise-token-authを導入する時もdeviseとの共存させるのに少しハマったので、そこについての記事も近々書こうと思ってます〜

ご指摘、ご意見お待ちしてます！
初心者によるプログラミング学習ログ 368日目

#100日チャレンジの368日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
368日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>昨日の作業・やったこと⇩<br><br>●ブログ記事1記事作成<br>●プログラミング学習368日目 1.5h<br>・メンターの課題<br>・オンライン勉強会<a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアとつながりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a><a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a></p>&mdash; ぱぺまぺ@社畜✕投資✕ブロガー (@ppmp65) <a href="https://twitter.com/ppmp65/status/1282098242839171072?ref_src=twsrc%5Etfw">July 11, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
ActiveDirectoryについて簡単にまとめてみた

# はじめに
ある日、「ADってなんですか？」と質問を受けました。そのときに、AD（Active Directory）を利用はしているが、殆ど知らなかったことに気づきました。そこで、一度自分で情報をまとめて見ようと考え、整理しようとしたのが本稿のきっかけです。

以降ではADについて自分なりに整理した結果をまとめています。また、その際に出てきたわからない単語についても簡単に説明しています。

なお本稿の目的は、「ADについて分からない人が、ふわっとした理解をする」ことを目的としています。だいぶ端折った説明になってると思いますがご了承ください。

# Active Directory（AD）の特徴
Active Directory（AD）の特徴は以下のことが挙げられます。

- Windows Serverに設けられた機能
- ディレクトリサービスと呼ばれるものの1つ
- ドメインと呼ばれるユーザーがアクセスできる範囲を用いている
- SSO（シングルサインオン）を併用し、社内の各リソースのアクセスを簡単にできる

ADを利用することで、「社内のリソースを一括管理可能。また、ユーザーごとにリソースへのアクセス制御も簡単に実現可能」なため、企業では導入されているんだと思います。

例：
（前提）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586524/eba6255b-26df-2d0b-556b-071d8babf74c.png)

Aさん･･･営業部
ファイルサーバー①、ファイルサーバー②･･･ドメインX内にある、営業部のみが触れるサーバー
ファイルサーバー③･･･ドメインX内にある、開発部のみが触れるサーバー
ファイルサーバー④･･･ドメインY内にある、営業部のみが触れるサーバー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586524/7a9c1290-b287-1dce-af2e-82702207d3d8.png)

1. Aさんがファイルサーバー①にあるファイルを触ろうとする
1. そのファイルサーバーは、Aさんが何者なのかを尋ねる（認証）
1. Aさんは自身のIDとPWを用いて認証を突破する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586524/2230bf1a-b678-d77d-030c-f90019f38421.png)
1. 続いて、Aさんはファイルサーバー②にあるフィアルを触ろうとする
1. 既にファイルサーバー①にて認証が済んでいるので、Aさんは認証を尋ねられることなくファイルサーバー②のファイルを触れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586524/5ca98031-9cd5-f45a-f612-f83bab7c0500.png)
1. 続いて、Aさんはファイルサーバー③のファイルを触ろうとする
1. ファイルサーバー③は、「Aさんは営業部である」という情報を既に持っているので、アクセスを拒否する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586524/aff5cbae-c984-9c85-ecf5-9aba31a8896d.png)
1. 続いて、Aさんはファイルサーバー④のファイルを触ろうとする
1. このドメイン内ではまだ認証されていないので、再び認証を行う必要がある。


次に各単語について説明します。

## ディレクトリサービス
ネットワーク内にある、サーバーやプリンタといった機器（リソース）の情報を一元管理するサービスのこと。

## ドメイン
ADによる認証を一度済ませた後、その認証を利用してアクセスできる範囲のこと。

## SSO
一度の認証で複数のサービスにアクセスできる仕組みのこと。例えば、Qiitaのアカウントを登録する際も、「Googleアカウントでログイン」といったように、他サービスでログインすればOKといったようなことをしてますね。

# ADのメリット
管理者目線と、利用者目線で考えてみました。

## 管理者のメリット
- リソースの管理が楽
一元管理できるため。会社において、各部のネットワーク管理者は自分の部の情報だけ管理すれば良くなるので管理する範囲が狭くなる。

- アクセス制御が楽
人事情報と組み合わせると効率的に各サーバーのアクセス制御が可能。
先程の例においてAさんが営業→開発に移動した場合、人事情報さえ変更すれば各サーバーのアクセス制御は自動的によしなにしてくれる

## 利用者のメリット
- 認証の手間が省ける
一度認証すれば、しばらくは再認証しなくてもアクセスできるので楽

- 端末の違いを意識しなくてすむ、複数のＰＷを覚えなくてすむ
一つの認証情報で各リソースにアクセスできるので。またこの情報は利用端末に依存しないため
共有のPCとかからでも簡単にアクセスできる。

他にも、「配下のPC全てにセキュリティパッチをインストールできるので、セキュリティ強化ができる」等のセキュリティ観点のメリットもあるかと。


# まとめ
ADを利用することで、「各リソースを一元管理できるため、管理が楽になる。また、人の異動が発生してもリソースのアクセス制御が簡単にできる。一度の認証すればよいから利用者も楽」といったように、「リソースの管理・アクセス制御が楽になる」というのがADの特徴（メリット）だと思います。
KiCAD のフットプリントが ?? になったときの対処

KiCADで回路図のコピペなどやったときなどに、開き直すと？？表示になる時がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/23d52aa7-6750-7dea-7507-6ba087ac57be.png)

元の回路図はこれ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2773fd59-16d6-aff4-3c6d-2ee7fa6c282d.png)

# 原因

使用しているフットプリントが KiCad のバージョンアップなどでライブラリが変更になるなどで、該当のものが参照できなくなっているため。
それに対処するために KiCAD はプロジェクトファイルと同じ階層にライブラリのキャッシュファイルを作成するが、キャッシュファイルを含めずに schematics ファイルをコピーして使用したり、Eeschema で回路図間でコピーしたときなどはキャッシュファイルも参照できなくなるためにこのようになる。


 
# 直し方

？？になっているところをダブルクリックしてプロパティを出す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/230a1053-a934-26f9-050c-7f308ca220a8.png)

例では Symbol の Library Reference が C になっているが、その横の本のアイコンをクリック、現行のライブラリの該当品を指定し直す。

ちなみに、例ではコンデンサの C を呼び出す必要があるが、KiCad5においてはそれは 「Device」-「C」として呼び出す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/145fc569-48ee-8a35-4332-91a60d899b4c.png)


画面上部の虫眼鏡で検索しても良い。
全部直したらこのようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9cb800b9-8606-e75c-8f60-3fcbc7e40496.png)
Railsで表示時間を日本時間に設定する方法

## やりたいこと
投稿時間を国際標準時間から日本時間の表示に変更したい

`変更前（GMT標準時間）▼`
[![Screenshot from Gyazo](https://gyazo.com/616dd17079f8930c331517ed55c1ef90/raw)](https://gyazo.com/616dd17079f8930c331517ed55c1ef90)
`変更後（日本時間）▼`
[![Screenshot from Gyazo](https://gyazo.com/54959307fd32e6e1df350cc354c3c322/raw)](https://gyazo.com/54959307fd32e6e1df350cc354c3c322)

## 設定の方法
- `config/application.rb` 内に `config.time_zone = 'Tokyo'` の記述を追加

```ruby:application.rb
# ↑これ以前のコードは割愛
module App
  class Application < Rails::Application
    config.time_zone = 'Tokyo'
  end
end
```
- サーバーが立ち上がっている場合は一度シャットアウトして再度立ち上げ直す<br />
※dockerを起動している場合は、下記でコンテナを立ち上げ直す（ターミナルで下記コマンドを実行）<br />
`docker-compose stop`<br />
`docker-compose up -d`

**これで日本時間で表示されるが、フォーマットを別途変更する必要あり**

- `strftimeメソッド` を使って、表示フォーマットを変えたい箇所にメソッドを当てる

```erb:sample.html.erb
# 下記はサンプル
<td><%= @tweet.created_at.strftime('%Y年%m月%d日 %H時%M分') %></td>
```

## 変換のメソッドを定義する方法
**やること：Initializeにフォーマット変換を定義する**

- `config/initializers配下`に`time_formats.rb`というファイルを作成する
- `Time::DATE_FORMATS[:datetime_jp] = '%Y年%m月%d日 %H時%M分'` と記述する

```ruby:time_formats.rb
Time::DATE_FORMATS[:datetime_jp] = '%Y年%m月%d日 %H時%M分'
```
※ [:datetime_jp] は任意の命名でOK
※ '%Y年%m月%d日 %H時%M分' には変換したいフォーマットを記述する

- 使いたい箇所（viewファイル内）で .to_s(:datetime_jp]) と記述して使う

```erb:sample.html.erb
# 下記はサンプル
<td><%= @tweet.created_at.to_s(:datetime_jp) %></td>
```
[Javascript] API Gateway に対して fetch メソッドでリクエストする

# 概要

「javascript から API Gateway にリクエストできるかどうか、とりあえず試したい」
そんなときは、ブラウザのコンソールを使うとラクチン（^ワ^*）

...というわけで、ブラウザに javascript の `fetch` メソッドを打ち込んでリクエストすることにするぞ！

今回はその方法のメモ

# 環境

API Gateway は `API Key` でアクセス制御を行っているものとする。

## 参考

- [Amazon API GatewayでAPIキー認証を設定する](https://dev.classmethod.jp/articles/apigateway-apikey-auth/)

# ソース

ブラウザコンソールに打ち込むソース

```javascript
fetch('API GatewayのURL', {headers: {"x-api-key": "API key をここに打つ"}}).then(response => response.json());

// sample
fetch('https://hogehoge12345.execute-api.us-east-2.amazonaws.com/xxxxxxx/sample', {headers: {"x-api-key": "abcdefghijklmnopqrstuvwxyz"}}).then(response => response.json());

// もしアクセス制御を一切行っていないのであれば、'headers': {} なしでよい
fetch('https://hogehoge12345.execute-api.us-east-2.amazonaws.com/xxxxxxx/sample').then(response => response.json());
```

## 参考

- [MDN web docs / Fetch を使う](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch)  
fetchメソッドの使い方が書かれている


## リクエスト結果の確認

* ここをクリックすると確認できる  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/691b14fc-0746-6016-8f66-d604701fc7b4.png)
* 中身  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/fd90ba1e-2bc3-81ac-68c3-a62ce8333720.png)


# error対処

コンソールにこんなエラーが出ることがある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/f5da7f75-6462-9716-fb33-4af1af284390.png)

```bash
# エラー文
Access to fetch at 'https://url' from origin 'https://hoge' has been blocked by CORS policy:
  No 'Access-Control-Allow-Origin' header is present on the requested resource.

If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

これは API Gateway の "CORS有効化" という作業を行えば回避できる
※ただし、URLやAPI Keyが間違っているときもなぜかこのエラーが出た...なぜだ

## 参考

* [AWS / API Gateway コンソールを使用してリソースで CORS を有効にする](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors-console.html)  
CORS有効化の方法が書かれている。AWSの公式ドキュメント
* [なんとなく CORS がわかる...はもう終わりにする。](https://qiita.com/att55/items/2154a8aad8bf1409db2b)  
CORSそのものについて理解を深めるのによい記事
* [ReactとAWS API Gatewayの連携方法](http://i-plug-tech.hatenablog.com/entry/2016/10/20/110000)  
CORS有効化以外にも、API Gatewayの全体的な設定についての記述あり

# おわりに

ネットの海の情報だけでなんとかAPI Gatewayへのリクエストが行えました。
今度はReactで問い合わせるぞ( \*˙︶˙\*)وｸﾞｯ!
"RNCWebView" was not found in the UIManager の対応方法

#"RNCWebView" was not found in the UIManager とは
　reactnativeでhello World アプリを作り、いざwebViewを使用してWebブラウザへのリンクなどを貼って本格的にアプリを作っていこうとしたタイミングでこのエラーが起きました。

#解決方法

cliで「react-native link」を実行後
「cd ios」 でiosディレクトリに移動、
「pod install」を実行し、再度ビルドを行うと、無事Webブラウザを開くことができました。

このエラーって一体何のエラーなのでしょうか、詳しい方教えていただきたいです。
Kindle蔵書一覧をPythonで取得するライブラリを開発しました

[Kindle蔵書一覧を取得する方法](https://qiita.com/taka_hira/items/8a9181c0733de2c9f8ee)を読んで、とても便利でした。

この中で、

> @error_401さんから頂いた情報によると
Kindle for PCを利用している場合、本の情報が入ったXMLが生成されるため
このXMLをパースして蔵書一覧を取得することも可能だそうです。詳細は本記事のコメント欄参照。

とあったのでPythonの練習も兼ねて、シンプルなKindle蔵書一覧取得ライブラリを開発してみました。

## 使いかた

下記のGithubを確認ください。 
https://github.com/koboriakira/kindlelamp

## 感想

開発している間に、「あれもやってみたいな」、「こんな機能があったら喜んでもらえるかも」など考えることが多かったのですが、できるかぎりシンプルで再利用できるものを目指してみました。

そのため1,2時間で完成したライブラリですが、これぐらい肩の力を抜いて作ったほうがいいのかなとも感じています。
RでSIRモデルをシミュレーションする

#初めに
大学のゼミで感染症の流行モデルである[SIRモデル](https://ja.wikipedia.org/wiki/SIR%E3%83%A2%E3%83%87%E3%83%AB)について調べたので、記事として残しておく。
コードは https://github.com/icy-mountain/SIR_plot に置いてある。
#実行環境
windows10
Rstudio
R 4.0.1

#本題
##ライブラリの読み込み
```R:SIR_plot.R
library(deSolve)
library(ggplot2)
```
微分方程式を表すためにdeSolve,可視化のためにggplotライブラリを読み込む。
##微分方程式や初期値の定義
```R:SIR_plot.R
parameters <- c(b = 1/2, g = 1/3)# パラメータのセット
initial <- c(s = 1, i = 1.27*10^(-6), r = 0)# 初期条件
times <- seq(1, 180, 1)# 差分刻み

SIR <- function(t, state, parameters) {
  with(as.list(c(state, parameters)), {
    ds <- -b * s * i
    di <- (b * s - g)*i
    dr <- g * i
    list(c(ds, di, dr))
  })
}
out <- ode(y = initial, times = times, func = SIR, parms = parameters)
```
1960年代のNYで起こった香港風邪のシミュレーションを行う。各パラメータや初期値は[このサイト](https://www.maa.org/press/periodicals/loci/joma/the-sir-model-for-spread-of-disease-the-differential-equation-model)を参考にした。
可視化のために微分方程式の結果をoutに代入しておく。
##ggplotで可視化
```R:SIR_plot.R
out_df <- as.data.frame(out)
SIRplot_base <- ggplot(data=out_df) +
  xlab("time")+ ylab("Y value") +
  ggtitle("SIR model")

SIRplot <- SIRplot_base +
  layer(
    mapping=aes(x=time, y=s, colour="s"), 
    geom="line", 
    stat="identity", 
    position="identity",
  ) +
  layer(
    mapping=aes(x=time, y=i, colour="i"), 
    geom="line", 
    stat="identity", 
    position="identity",
  ) +
  layer(
    mapping=aes(x=time, y=r,colour="r"), 
    geom="line", 
    stat="identity", 
    position="identity",
  )
```
微分方程式の結果をdata.frameに変換して、S,I,Rの値をプロットする。
##結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357134/9ffc5130-5c7e-a96f-8908-97f5f11c1821.png)
おわり
リファクタリング　第2章　まとめ


# はじめに

リファクタリング　第2版を読み進めているので、今回は第2章について。
2章では具体的なテクニックに書かれているわけではなく、定義やなぜするのか等がまとめられている。


リファクタリング　第2版
https://www.amazon.co.jp/%E3%83%AA%E3%83%95%E3%82%A1%E3%82%AF%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0-%E7%AC%AC2%E7%89%88-%E6%97%A2%E5%AD%98%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%AE%89%E5%85%A8%E3%81%AB%E6%94%B9%E5%96%84%E3%81%99%E3%82%8B-OBJECT-TECHNOLOGY/dp/4274224546

#リファクタリングの定義

外部から見たときの振る舞いを保ちつつ、理解や修正が簡単になるように、ソフトウエアの内部構造をさせること。
リファクタリングを行うことによって、以前に書いたコードの設計が向上することになる。
リファクタリングの目的は開発スピードを上げていくということであり、コードを「理解や修正が容易になるように」変化させることであり処理速度を上げるためのものではないということを認識しておくべきだと感じています。


#リファクタリングを行う理由

大きく3つの観点で書かれている。

###ソフトウェア設計を改善する

アーキテクチャの全体的な理解をせずに、開発者が部分的な変更を行なった場合、コードは構造を失うことになる。こうなると他のメンバーや自分が見直す時に設計を把握するのが難しくなってしまい累積的に悪影響が出てしまう。設計を維持することが難しくなり急速に劣化してしまう。
だからこそ、重複するコードを削除したり、あるべきコードをあるべき場所に移動させたすることが必要であるとのことでした。

###ソフトウェアを理解しやすくする
理解しにくいコードを書くことで将来の開発者に負担を強いてしまう。動作はするが上手く構造化さていないコードがあったとして、少しの時間をリファクタリングに充てるだけで、コードの目的がより伝わりやすくなる。

###バグを見つけやすく
コードを理解しやすくすることによってバグを発見しやすくなる。自分がそのコードをリファクタリングできれば、プログラムの構造を明確にし、コードに対する推測が正しかったことがわかり、バグ発見に繋がる。

#いつリファクタリングをすべきか

###機能追加をする時
既存のコードを読んで、もし構造が少しでも違っていたら作業は簡単になるはずだと考え、機能追加をする前にリファクタリングできるところはあるのかを考えることは重要である。
最初に完璧な設計を探さなくても、リファクタリングを行う体制があることにより常により良い解を探し出すことができる。リファクタリングをすることで、コードや設計への理解が深まり、それによって設計の改善が行われていくことが可能であることが述べられていました。ここで重要なのは最善の解が常に変わる可能性があるということを受け入れることが必要であるということを頭においておくべきだと思いました。


###ゴミ拾いのためのリファクタリング
現在取り掛かっているタスクに直接関係のないことに時間を奪われたくないと考えるが、将来の変更要求があったときに邪魔になるであろうゴミを放置するのではなく、すぐに実行するべき。修正に手こずりそうな時はメモなどを残しタスクが終わり次第行う。

###コードレビュー時
自分にとってのわかりやすいコードも、チームにとってはそうでもないかもしれない。レビューは示唆に富むアイデアを多くの人から引き出す機会を与えてくれる。
さらにチームでリファクタリングを行わなければ出てこなかったような一歩進んだアイデアが浮かんでくることも。

###リファクタリングを避ける時
いかなる場合もリファクタリングをするべきだと思われているかもしれなが、リファクタリングの価値がない場合もある。
単なるAPIとしてみなせるのであれば放置しておいてもいい。最初から書き直した方がリファクタリングするよりも簡単な時もある。
ただ、このリファクタリングの判断をするには適切な判断能力、豊富ば経験が必要であり簡単に身に付くことはない。


###感想
リファクタリングは開発スピードを向上させるもの、理解しやすい設計、改善、バグ発見など特にチームで開発するには必須であると感じています。

後からコードを読む人、自分も含めてリファクタリングを怠った時はコード設計を把握することも難しくなり、品質の維持に影響が出るためプログラム内部の設計を劣化させることに繋がってしまう。そのためにも常に個人でもリファクタリングをする意識が必要であり、リファクタリングをしながら開発する体制を整えることが重要であると思いました。

読み進めている最中ではありますが、参考になった章をまとめていけたらと思います。