OmniAICreator/Qiita-1.07M huggingface dataset:
カスタム地図の作成

＃カスタム地図の設定

カスタム地図の追加、編集、削除および geoJSON のアップロードには、「Analytics のカスタム地図を管理」ユーザ権限が必要です。この権限を持つユーザは、すべてのカスタム地図 (他のユーザが作成した地図を含む) を編集および削除できます。組織内のすべてのユーザは、この権限を持たない場合でも、レンズとダッシュボードのすべての地図を使用できます。


#作成手順
![スクリーンショット 2021-04-05 14.24.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/d9e6bca4-ebb6-72ee-b36e-a97fce908570.png)

![スクリーンショット 2021-04-05 14.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/722855df-f62a-4682-fbcd-3d034ac12eb2.png)




# 参考文献
[カスタム地図の作成](https://help.salesforce.com/articleView?id=sf.bi_chart_intro_custom_map.htm&type=5)
AWS Toolkit for VSCodeの設定

AWS Toolkit for VSCodeを入れていたものの、よく見たらちゃんと動いてなかった。
なぜ補完もせずゴリゴリ書いていたのか…
なのでちゃんと設定した記録。

# インストールが必要なもの

VSCode本体、node.js、AWS CLI、AWS CDK、AWS SAM CLI、Docker、あたりは省略。

- [YAMLエクステンション](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)
  AWS ToolkitのSAM対応や、CloudFormation用のエクステンションが依存している。

- [aws-cloudformation-template-schema](https://github.com/aws-cloudformation/aws-cloudformation-template-schema)
  CloudFormationテンプレートの補完と検証を行える。
  VSCodeであれば、下記の[CloudFormation Linter](https://marketplace.visualstudio.com/items?itemName=kddejong.vscode-cfn-lint)を入れればよい。
  [GitHub Actions](https://github.com/marketplace/actions/cfn-lint-action)もあるの、いいじゃないと思った。push した後にチェックしても手遅れ感あるので、ローカルでチェックする前提で最後の防波堤として導入してもいいのかもしれない。

- [CloudFormation Linter](https://marketplace.visualstudio.com/items?itemName=kddejong.vscode-cfn-lint)
  [E3012](https://github.com/aws-cloudformation/cfn-python-lint/blob/master/docs/rules.md#categories)エラーはチェックから外してもよさそう。
  外す場合は、VSCode の設定で `cfnLint.path` に `cfn-lint --ignore-checks E3012` と設定する。
  手元の設定では E3012 は外さず、東京リージョンを指定して `/opt/homebrew/bin/cfn-lint -r ap-northeast-1` と設定した(M1 Macの場合)。

- [cfn-lint](https://github.com/aws-cloudformation/cfn-python-lint)
  CloudFormation Linterが依存している。
  Macなら `brew install cfn-lint` でインストール。
  `@aws-amplify/cli` が `cfn-lint` に依存しているので、Amplify CLIをインストールしていると brew install 中にリンクに失敗する。
  JavaScript 製の `cfn-lint` は deprecated らしく、本人も `cfn-python-lint` 使えって言っているので、素直に `/opt/homebrew/bin/cfn-lint` のリンク(M1 Macの場合)を削除して `brew link cfn-lint` 、か `--overwrite` を付けて上書きし、Python 版にリンクを貼る。

- [pydot](https://pypi.org/project/pydot/)
  CloudFormation Linterが依存している。
  CloudFormation Linterのスタック可視化機能を使いたいならこちらもインストールする。

# 規約など

- CloudFormationテンプレート名
  [公式ドキュメント](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/serverless-apps.html#serverless-apps-debug)には、テンプレート名が `template.yaml` でないと認識しないと書いてある。
  実際は `template.yml` でも認識する場合がある。
  [ソースコード](https://github.com/aws/aws-toolkit-vscode/search?p=2&q=template.yaml)を見た感じ `template.yaml` にしておいたほうが全機能で認識してくれそう。

- ECSタスク定義ファイル名
  サフィックスが `ecs-task-def.json` でないと認識しない。
  `my-ecs-task-def.json` など。

# その他の設定

色々な記事を見ていると `yaml.customTags` を自分で設定しているものが多い。
CloudFormation Linterのソースコードを見ると、内部で自動的に設定をしている箇所があるので、読み間違えてなければ今どきは何もやらなくていいんじゃないかと思う。

https://github.com/aws-cloudformation/aws-cfn-lint-visual-studio-code/blob/master/client/src/extension.ts
Node-RED にて Watson Assistant APIにおける user_id のセット方法

###背景
Watson Assistant 用ノード（[node-red-node-watson 0.94 の 『watson-assistant-v2』](https://flows.nodered.org/node/node-red-node-watson)）において、[ノードの情報（github上ソースコードコード内の data-help-name="watson-assistant-v2"部分 ）](https://github.com/watson-developer-cloud/node-red-node-watson/blob/master/services/assistant/v2.js)を見る限り、**user_id** をセットする機能が提供されていないようだったので、新たに、user_idをセットする機能を含めたAssistant用のfunction ノードを作成したので、備忘録として整理した。

###具体的な方法
今回は、以下の内容を、function内で記述するために、[APIリファレンス（Watson Assistant v2用）](https://cloud.ibm.com/apidocs/assistant/assistant-v2#messagestateless)を参考に、ステートレス形式で作成した。

```
curl -X POST -u "apikey:{apikey}" --header "Content-Type:application/json" --data "{\"input\": {\"text\": \"Hello\"}}" "{url}/v2/assistants/{assistant_id}/message?version=2020-04-01"
```

＜ポイント＞
- apikeyを渡すために、Authorizationヘッダーをセット（**msg.headers** へセット）
- "apikey:{apikey}" の部分（以下の%%%%%）は、base64にてエンコーディングしたものをセットする
- **msg.url**に、エンドポイントを指定
- **msg.payload** 内に、json形式で、**user_id** にセットしたいユーザーIDをセット（例では、test_user をセット）
- 下記のように作成したfunctionノードと、**http request**ノード（post）を接続
- 今回は、ステートレス用として作成（下記の例もステートレス用）

```
Assistant用functionノード

//msg.payload.input には問い合わせする内容がセットされている
input_data = msg.payload.input ;
msg.headers =  {"Authorization": "Basic %%%%%","Content-Type":"application/json"};
msg.url = 'https://api.au-syd.assistant.watson.cloud.ibm.com/instances/xxxxx/v2/assistants/yyyyy/message?version=2020-04-01' ;
msg.payload = '{"input": {"text":"' + input_data + '"},"user_id":"test_user"}' ;
return msg;
```

##関連記事

1.[Watson Assistantの新しいプラン「Plus」と月次ユーザー数課金(MCU)導入のご紹介](https://qiita.com/ishida330/items/86520ffd7b7216d1d471)
2.[BASIC認証の越え方](https://qiita.com/HeRo/items/22751e828791be173529)
3.[Watson Assistant API V1/V2の違い](https://qiita.com/ishida330/items/6dcdb664e4724e27764d)
Gatsbyのテーマをカスタマイズする

GatsbyでCMS構築して、デザインをちょこっと替えたい時にハマったので備忘録的にメモ


今回利用させて頂いたStarters
[gatsbyjs - LekoArts/gatsby-starter-minimal-blog](https://www.gatsbyjs.com/starters/LekoArts/gatsby-starter-minimal-blog/)

# トップページの文字列をカスタマイズする

FYI. トップページの文字の変更について
[Github - Changing the hero text](https://github.com/LekoArts/gatsby-starter-minimal-blog#changing-the-hero-text)

**トップページの「Hi. I'm Lupin - currently...」を変更する対応**

1.上書きするソースをコピーする

```bash
cp -r node_modules/@lekoarts/gatsby-theme-minimal-blog/src/texts/hero.mdx src/@lekoarts/gatsby-theme-minimal-blog/texts/
```

2.hero.mdxを編集する

```md:hero.mdx
-  Hi.
+  Hello!
```

3.ブラウザで表示を確認する

変更前
![スクリーンショット 2021-04-05 13.52.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288712/639b2792-1dee-2d19-f645-dd923806183b.png)

変更後
![スクリーンショット 2021-04-05 13.52.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288712/6bc588eb-d6c5-f014-e796-907a6c024aaf.png)


# footerのレイアウトをカスタマイズする

FYI. デザインのカスタマイズについて
[gatsbyjs - Plugins and themes/shadowing](https://www.gatsbyjs.com/docs/how-to/plugins-and-themes/shadowing/)

**footerのStartersのGithubリンクを消す対応**

1.上書きするソースをコピーする

```bash
cp -r node_modules/@lekoarts/gatsby-theme-minimal-blog/src/components/footer.tsx src/@lekoarts/gatsby-theme-minimal-blog/components/footer.tsx
```

2.use-site-metadataが見つからない系のエラーになるので修正する。

```js:footer.tsx
-    import useSiteMetadata from "../hooks/use-site-metadata"
+    import useSiteMetadata from "@lekoarts/gatsby-theme-minimal-blog/src/hooks/use-site-metadata"
```

3.消したい箇所を削除する
私の場合は、「Theme by LekoArts」というリンクを削除しました。

```js:footer.tsx
-      <div>
-        <Link
-          aria-label="Link to the theme's GitHub repository"
-          href="https://github.com/LekoArts/gatsby-themes/tree/master/themes/gatsby-theme-minimal-blog"
-        >
-          Theme
-        </Link>
-        {` `}
-        by
-        {` `}
-        <Link aria-label="Link to the theme author's website" href="https://www.lekoarts.de/en">
-          LekoArts
-        </Link>
-      </div>
```

4.再度コンパイルする

```bash
gatsby develop
```

3.ブラウザをリロードし、表示を確認する

変更前
![スクリーンショット 2021-04-05 13.49.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288712/d278cca6-3636-509d-917f-8c64fbee1d60.png)

変更後
![スクリーンショット 2021-04-05 13.49.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288712/80f32d7f-fc72-0dc4-57ad-a68821e06fb0.png)

# まとめ

フロントエンド触りなれていなくてもサクッと構築できるGatsbyはとても便利です。
セキュアでカスタマイズ性も高く、今後も活用していこうと思います。
AWS Lambdaの処理を速くする方法

## Lambdaの処理が遅いなーと感じた時にLambda側の設定を変えるだけでスピードを上げることができます。

Lambda画面ではCPUの設定項目はありませんが、メモリ容量に比例してCPUの性能が上がる仕様になっています。
（※注意点※　メモリを増量するとその分、料金も高くなるのでその点は予算に合わせて調整してください。）
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-memory.html

設定はとても簡単です。

マネジメントコンソール画面からスピードアップしたいLamda関数を選択しページを開きます。
[一般設定]->[編集]の順でクリック。
![スクリーンショット 2021-04-05 14.07.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/d30b85e6-fc66-e37c-73c5-4fe826241ac7.png)

メモリを128MBから増やせして保存すれば、完了です。
メモリの容量に比例してCPUのスペックも上がります。
![スクリーンショット 2021-04-05 14.08.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/c21721fb-d10e-bac9-fe89-d97338746c2c.png)
【備忘録】Ubuntu18.04LTSにROS2を導入する方法

# 想定
* ubuntu18.04LTS
* ROS1(melodic)は導入済みの環境
* ROS2はdashingを想定

# ROS1の無効化
OSの文字コードをUTF-8に設定しておく必要あり

```
//ロケールのセットアップ
sudo locale-gen ja_JP ja_JP.UTF-8
sudo update-locale LC_ALL=ja_JP.UTF-8 LANG=ja_JP.UTF-8
export LANG=ja_JP.UTF-8
```

# ROS2のインストール手順
* ROS2のビルド済みバイナリを公開しているAPTパッケージのダウンロード先を登録したのちにROS2(dashing)をインストールする

```
//APTソースリストの設定
sudo apt update
sudo apt install -y curl gnupg2 lsb-release
curl http://repo.ros2.org/repos.key | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64,arm64] http://packages.ros.org/ros2/ubuntu `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list'
sudo apt update

// ROS2パッケージのインストール
sudo apt install -y ros-dashing-desktop python3-colcon-common-extensions python3-rospkg python3-catkin-pkg python3-rosdep python3-argcomplete
sudo rosdep init
rosdep update
```

# 環境設定

```
export ROS_DISTRO=dashing
echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrc
source ~/.bashrc
```

# 動作確認
talkerノードがPublishしたTopicをlistenerノードがSubscribeするデモプログラムがある．これを利用して動作確認を行う．以下が正常に動いているものである．

```:talkerノード
$ ros2 run demo_nodes_cpp talker
[INFO] [talker]: Publishing: 'Hello World: 1'
[INFO] [talker]: Publishing: 'Hello World: 2'
[INFO] [talker]: Publishing: 'Hello World: 3'
[INFO] [talker]: Publishing: 'Hello World: 4'
[INFO] [talker]: Publishing: 'Hello World: 5'
```

```:listnerノード
$ ros2 run demo_nodes_cpp listener
[INFO] [listener]: I heard: [Hello World: 1]
[INFO] [listener]: I heard: [Hello World: 2]
[INFO] [listener]: I heard: [Hello World: 3]
[INFO] [listener]: I heard: [Hello World: 4]
[INFO] [listener]: I heard: [Hello World: 5]
```

以上，インストールが完了
【超基礎】Gitコマンド備忘録

<h1>はじめに</h1>
本記事はGitを学び始めた筆者が、超基本的なGitコマンドをまとめたものです。
文量を抑え、適宜参照しやすくなるよう心掛けました。

また、本記事は備忘録であり、Qiitaへの投稿の練習でもあります。
記事の内容や構成についてご指摘・アドバイスを頂けると、筆者が飛んで喜びます。

<h1>環境</h1>
- OS : Windows10
- Git : 2.31.0
- 使用ツール : Git Bash

<h1>コマンド一覧</h1>
| コマンド| 説明 | 使用例 |
|:-----------|:------------|:------------|
| $git init  [directory name]| 指定したデイレクトリをGitの管理下に置く| $git init ./hogehoge |
| $git clone [URL]| リモートリポジトリをローカルへ複製する| $git clone git@github~|
| $git pull| リモートリポジトリの変更をローカルへ反映する|  |
| $git push| ローカルの変更をリモートリポジトリへ反映する |  |
| $git log| 過去のコミットログの参照| |
| $git log --graph| コミットログをグラフ形式で描画|  |
| $git reflog| コミットログの参照|  |
| $git status| ローカルのステータスを表示|  |
| $git diff| 最新コミットからの差分を表示|  |
| $git add [filename]    | 指定したファイルorディレクトリをステージング| $git add hogehoge.py |
| $git commit -m 'comments'       | コメントを付与してコミット| $git commit -m 'First commit.' |
| $git commit -am 'comments'         | ステージングしつつ、コメントを付与してコミット| $git commit -m 'Fixed hogehoge.py'|
| $git commit --amend| 最新コミットのコメントを修正する|  |
| $git branch| ブランチを一覧で表示|  |
| $git checkout [branch name]| ブランチの切り替え | $git checkout branch-A |
| $git checkout -b [branch name]| 新規ブランチを作成し、そこへ切り替え| $git checkout -b branch-B |
| $git merge [branch name]| ブランチのマージ| $git merge branch-C |
| $git reset --hard [ハッシュ値]| 指定したコミットまで移動する[^1]| $git reset --hard 1195e31|
| $git rebase -i HEAD~[number]| 指定したコミットの範囲を改変する[^2] | $git rebase -i HEAD~2|

<h1>参考文献</h1>

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

https://www.amazon.co.jp/GitHub%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E2%94%80%E2%94%80Pull-Request%E3%81%AB%E3%82%88%E3%82%8B%E9%96%8B%E7%99%BA%E3%81%AE%E5%A4%89%E9%9D%A9-WEB-PRESS-plus-ebook/dp/B07JLJSDMJ/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=github&qid=1617588663&sr=8-2

[^1]: --hardオプションによって、ファイルの内容含め書き換わるので注意
[^2]: コンフリクトを解消等に用いるらしい。チュートリアルということもあり、複数人で開発していない筆者はあまり使う機会がなかった。
【UI】ユーザビリティを考慮したモーダルの文言・デザイン

下記の様なモーダルを作成する際のポイントを記載します。
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924380/d096259c-d8f2-60f5-3531-9709c0b9934e.png)

## 文言
### メッセージは明確なものにする
#### 悪い例
- 警告！
- 本当に良いですか？

#### 良い例
- ストレージを削除しますか？
- アカウントを削除しますか？

### 選択肢はメッセージに対して、短く論理的かつ適切なものとする
#### 悪い例
|| 表記 | 意味 |
|-|-|-|
| メッセージ | 処理をキャンセルしますか？ | 処理を中断しても良いか |
| 同意 | OK | 処理を中断する |
| 拒否 | キャンセル | 処理を続行する |

- ユーザーが処理をキャンセルしたい場合、直観的に同じ表記の「キャンセル」を選択したくなる

|| 表記 | 意味 |
|-|-|-|
| メッセージ | 処理をキャンセルしますか？ | 処理を中断しても良いか |
| 同意 | はい | 処理を中断する |
| 拒否 | いいえ | 処理を続行する |
- 選択後、何が起きるのか明示されていない

#### 良い例
|| 表記 | 意味 |
|-|-|-|
| メッセージ | 処理を中断しますか？ | 処理を中断しても良いか |
| 同意 | 中断 | 処理を中断する |
| 拒否 | キャンセル | 処理を続行する |
- メッセージと同意の表記を揃える

## デザイン
### 破壊的アクションを考慮する
- 「削除」「中断」等の破壊的アクションはユーザーの注意を引き付ける色を使用する
Open CV OAK-D 使ってみた

#OpenCV OAK-Dが届いた！
待ちに待ちまくった、OAK-Dが今日届いた！

今日、4月5日に予定より2日早くアメリカから到着。
paypalで支払いしたのが、3月25日に入金してから10日前後かかりました。

金額は299＄送料諸々含めると、税込みで4万程で購入しました。![S__23486472.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1040271/dc939365-81c2-5bd4-27ee-5db85a9ec458.jpeg)

![S__23486471.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1040271/7a098cad-8ede-7f23-c7ef-4c8cb2b4616c.jpeg)

表面はプラスチックなのかと思いきやアルミダイキャストで重厚感があります。
![S__23486468.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1040271/ad6e9d65-f006-210f-58a4-078db6c4519a.jpeg)

これから、サンプルプログラム動かしてみます！
めちゃくちゃ楽しみ！

ラズパイでの動作状況レビューしていきます！
AngularでDrag&Dropでファイルアップロード実装時参考にした記事まとめ

この文書が書かれた2021年4月時点で、インタネットで検索して実装してみた参考リンクとその効果をメモしたものです。

下記のプラグインは説明通り実施したら一発でできましたので、記録しています。（実はいろいろ検索結果を書いたのですがうまく行かず全部削除して、確実にできる下記の記録のみを残しました）

リンク：[npm: ngx-dropzone](https://www.npmjs.com/package/ngx-dropzone)

このリンクはngx-dropzoneの紹介ページになります。

ほかにプラグイン見つけたら追記しようと思います。
ROSチュートリアルでハマったこと

ROSを勉強してみようと思い、手始めにROS1の[チュートリアル](http://wiki.ros.org/ja/ROS/Tutorials)をやってみることにしました
ROS1はPython2系（既にサポート切れ）なので順次ROS2への移行が進んでいるようですが、最初のとっかかりとしてはいいかなと
チュートリアルを進めていく中でいくつかハマりポイントがあったので、誰かの助けになればと思い対処法を記事にしました

※wsl2がインストール済み、Pythonの使用を前提としています

## ハマり1 : ROSのインストール
`1.初級 > 1.ROS環境のインストールとセットアップ > 1.ROSのインストール`

チュートリアルに記載のあるROSのバージョンはhydroとindigoだったので、どちらをダウンロードした方がいいのか調べました
すると、ROSのバージョンとUbuntuのバージョンは合わせないといけないことがわかりました
  https://faboplatform.github.io/AutowareDocs/07.RC_program/00.about_ros/

ubuntuのバージョンを確認し、そのバージョンに対応したROSをインストールしましょう

```
$ cat /etc/os-release
≈
VERSION="18.04.5 LTS (Bionic Beaver)"
≈
```

私の場合はubuntu18.04.5なのでmelodicでした
  http://wiki.ros.org/melodic/Installation/Ubuntu

## ハマり2 : turtlesim起動時にエラーが出る
`1.初級 > 5.ROSのノードを理解する > 0.1.rosrunの使い方`

turtlesim起動時にXサーバー（Windows X Server）がなくエラーとなる

```
$ rosrun turtlesim turtlesim_node
Error: Can’t open display:
```
そういう場合は以下のURLを参考にインストール・設定をする
https://astherier.com/blog/2020/08/run-gui-apps-on-wsl2/

Xサーバー起動時に「Disable access control」にチェックを入れる必要あり

## ハマり3 : add_two_ints_server起動時にエラーが出る
`1.初級 > 16.シンプルなサービスとクライアントを実行してみる`

モジュールがない旨のエラーが出る

```
$ rosrun beginner_tutorials add_two_ints_server.py
≈
ImportError: No module named beginner_tutorials.srv
≈
```

setup.bashが読み込まれておらず、参照先のディレクトリが正しく設定できていない場合があります
以下のコマンドで設定を読み込み直しましょう

```
$ source devel/setup.bash
```

エラーについて調べると
・PYTHONPATHを設定しましょう
・setup.pyを作りましょう
など色々出てきますが、私は上記コマンドの実行のみで大丈夫でした
【ASP .NET MVC】リアルタイムな画像キャプチャ


# 概要

センサやカメラなど、リアルタイムに計測したイメージデータが撮像できるという条件のとき、そのイメージデータをブラウザ上で随時更新する処理を考えるときに、imgタグでは画像が更新されないことに気づき、ちょっと詰まった。

ASP.NETによる対処法のメモを残す。

## 原因と対応方法

原因を考えていたところ、ブラウザ側でキャッシュが働いていて、画像を一時保存しているため。
主な方法は2つ。両者ともにメリットがあり、設計指針によって決めればよい。

**(1) "Display_20210405_130903.png"などととして、キャプチャ画像をリネームして読み込む。**

**メリット**

- 画像をストレージに自動的に確保でき、キャプチャした画像データを常にログとして自動で残し続けることが出来る。

- 時系列データと画像が残っていることから、作業や管理、デバッグがしやすい。

**(2) キャッシュを持たない設定にすることで対応する。**

**メリット**

- ブラウザのキャッシュの影響を考慮せずに、運用が出来る。例えば、メモリ制限があるPCで動かすことを考えて、キャッシュを持つ設定にすると、キャッシュ分だけ画像を残してしまう＆そのキャッシュを読み取る処理が発生するので、メモリ効率が悪化してしまい、システム全体でのリアルタイムの動きに影響を与えるかも。

- アプリの見た目上、原理的には「画像が更新されていない」という状況を防ぐことが出来る。


今回は(2)で対処することを考える。
　


## 注意

- 実際にセンサやカメラを使う部分はConfidentialなので、違う画像を使って差し替えます。

- 今のところ、オンラインで動かすことは考えていませんので、urlはローカル設定のものを使っています。ご注意を

## ソースコード

(1) Razorページ(View)を以下のように定義

1秒ごとに、サーバサイドにGETリクエストを行ない、画像のみを変更する。

```javascript:OPDebug/Index.cshtml

<img src="@Url.Action( "TestLoad", "OPDebug" )" id="OpTestLoadImage" />

@section Scripts{
    @Scripts.Render("~/bundles/jqueryval")
    <script>
        $(function () {
            setInterval(
                function() {
                    $('#OpTestLoadImage').attr('src', '@Url.Action("TestLoad", "OPDebug")');
                }, 1000);
        });
    </script>
}

```

(2) Controllersでコントローラを以下のように定義

```C#:OPDebugController.cs

using System.Drawing;
using System.Threading.Tasks;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;

using System.Web.Services;
using OPLocal.ViewModels;


namespace OPLocal.Controllers
{
    public class OPDebugController : Controller
    {
        /* --- 既存ソースコードのため、一部省略 */
       public FileContentResult TestLoad()
        {
            /* 次の行がポイント */
            Response.Cache.SetNoStore(); 

            var img = new WebImage(Server.MapPath("..") + @"\display.png");
            return new FileContentResult(img.GetBytes(), string.Format("image/{0}", img.ImageFormat));
        }
    }
}
```

Response.Cache.SetNoStore();がポイントで、これによって、ブラウザ側がキャッシュを持つのを防いでくれるようになる。


(3) ソリューション直下にdisplay.pngと、"org1.png"、"org2.png"を設定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/85293475-e10d-98e3-1d3c-8f107d50f407.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/49b7a919-65a0-34b3-78bb-482a4c67a2c5.png)

カメラから取り込まれたデータが、display.pngとして保存されると想定するが、とりあえずダミーで、リアルタイムのカメラの動きの代わりに、org1.bmpとorg2.bmpのどちらかをリネームして表示できるようにするものとする。


## 実行結果

以下、他のGET命令によるルーティングを行なわない前提で検証

display.pngがない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/502ed53e-3c7f-908e-b003-9408dc83c5cc.png)

org1.pngをdisplay.pngにリネーム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/e50bb990-c7e7-2716-11b9-412231a6fd4b.png)

org2.pngをdisplay.pngにリネーム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/f82bc11a-88b3-39aa-644a-923d4192e568.png)

予想通り動いてくれた。

この後は、リアルタイム処理中は、実際にキャプチャフォルダをローカルに設定し、そのローカルに設定したファイルのうち最新のものを保存する。それを、読み取ることで解決する予定。
JS~forEach~

今回は配列の繰り返し処理のforEach文について学習していきます。

まず、一般的使わえる繰り返し分は以下になります。

```index.js
<script>
    'use strict'

    const cities = ["東京", "大宮", "横浜"]

    for (let i=0; i<cities.length; i++) {
      document.write(city[i]);
    }
  </script>
```

*length　▶主に文字列の長さや配列の要素数を取得することができるプロパティになります。

この記述でもいいのですがもう少し簡単に書くことができます。

```index.js
 cities.forEach((city,index) => {
    document.write(`都市${index}: ${city}`);
    });
```
forEachの引数には、cityとindexを入れました。
そして下の方でそれぞれを呼び出してもらいます。

要素の数がなくなるまで、繰り返し処理することができます👍

![スクリーンショット 2021-04-05 13.03.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/50d8ec05-1f18-d105-5dde-80bf3c4c2e84.png)
【Swift】CollectionViewまとめ

#はじめに
基本的なCollectionViewの扱い方を練習していく中で学んだことをまとめました。
自分のQiitaの記事も貼っていきます。

#GitHub

https://github.com/0429oonishi/CollectionViews

#学んだこと
###HeaderFooterCollectionView

https://qiita.com/REON/items/cd4d997a6a1a063e77f5

###CollectionCompositeLayout

https://qiita.com/REON/items/e69667b9f4bfa7132110



#おわりに
随時更新予定
ActiveSupport::MessageEncryptor::InvalidMessageを解決

herokuでpushした時に、以下のエラーが出たのは、

```
ActiveSupport::MessageEncryptor::InvalidMessage
```

`credentials.yml.enc`をしっかりと、
編集できていないためでした。


ターミナルで、
VScodeで編集するには、

```
EDITOR='code --wait' rails credentials:edit
```

Vimエディタで編集するには、

```
`DITOR=vi rails credentials:edit
```

Vimエディタのなんて使ったことがない人は、
VScodeで編集したほうが簡単です。


参考記事↓
https://hirocorpblog.com/rails-credentials-master/#toc5
Heroku デプロイできない時の解決方法

まずWindowsであれば，
Herokuで必要なgemが足りていないので、
ターミナルで以下を実行する。

```
bundle lock --add-platform ruby
git add .
git commit -m "any message"
```

これでも解決しない場合、
以下のようなエラーが出ていたら、


```
cannot load such file -- bootsnap/setup (LoadError)
cannot load such file -- rake (LoadError)
```

ターミナルで以下を実行して、gemをインストールする。

```
bundle install
```


これでもダメな場合は、
ターミナルで以下を実行してnodeのバージョンを確かめる。

```
node -v
```

nodeが15以上になっていたら、
nodeを14に下げてから再度Herokuにpushする。


＜nodeを14に下げる方法＞
ターミナルで以下を実行

```
brew install nodebrew
/home/linuxbrew/.linuxbrew/opt/nodebrew/bin/nodebrew setup_dirs
nodebrew install 14
nodebrew use 14
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.profile
source ~/.profile
node -v
```
GCCがconstexpr関数のメモ化をやめたっぽい

# はじめに

　なんかGCC9.3とGCC10.1でconstexpr関数の挙動が変わったようです。最近発見したのでちょっとした小ネタとして記事にします。大した記事ではありませんが。

# constexprとは

　constexpr関数とはコンパイル時に評価可能な関数のことです。実行時に評価することも可能です。

```cpp
constexpr int func(int x, int y) {
  return x + y;
}

int main() {
  constexpr int i = func(20, 22);  // コンパイル時に計算される (実行時コストが減って高速)
  int j = func(20, 22);   // 実行時に計算される (最適化によってはコンパイル時に計算される)
  return 0; 
}
```

# constexprのメモ化

　constexpr関数は、C++17までは与える引数に対して戻り値が一意に決まります。そのため、引数と戻り値のペアを保存しておけば、たとえ実行時に呼び出されたとしても保存しておいた値を取り出すだけで良いので速いわけですね。それがメモ化というものです。ClangやMSVCはこの機能を取り入れていませんでしたが、GCCでは9.3までこのメモ化が実装されていました。
　しかし、C++20でnew式とdelete式がconstexprになったため、戻り値が一意ではなくなりました (newの返すポインタはいつも同じではありませんよね？)。なので必ずしもメモ化できるというわけではなくなったのですが、その影響もあってか、GCC10.1以降メモ化できるできないにかかわらず、メモ化するのをやめたようです。`-std=c++2a`だけでなく`-std=c++17`でもこの変更が適用されています。正直このメモ化は高速な代わりに、少しコードの規模が大きくなるとメモリをえげつなく食らいつくすので無い方が有難かったりしますが。
　メモ化をやめたことは以下のコードで確認できます。

```cpp
constexpr long long fib(int i) {
  if (i == 0) {
    return 0;
  }
  if (i == 1) {
    return 1;
  }
  return fib(i - 1) + fib(i - 2);
}

int main() {
  constexpr long long j = fib(50);
  return static_cast<int>(j);
}
```

　実行結果は下のリンクから。

https://godbolt.org/z/6hn3reqax

　関数`fib`は入力の引数$ N $に対して計算量$ O(2^N) $かかり、最大ステップ数制限をオーバーしてコンパイルエラーになりますが、メモ化されていれば計算量$ O(N) $で済み、普通はステップ数オーバーしません。GCC9.3ではコンパイルできていますが、GCC10.1ではコンパイルエラーになっていますね。

おしまい
自作コロナ感染人数自動通知スクリプト

どうもはじめまして、東京在住のwangyです

毎日東京コロナ感染者数の自動通知スクリプトを作成いたしました。実行環境はpython3です。
ChatworkのAPIを使って、通知先がChatworkだけでちょっと適用範囲が狭いですが、よろしければお使いください


### コード

```python
import urllib.request
import urllib.parse
import csv
import pandas
import datetime
import json

def get_cvoid_infect_num(date):

    url = "https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv"
    df = pandas.read_csv(url,header=None)

    df_filtered = df[df[4]==date.__str__()]

    infect_num = len(df_filtered)

    return infect_num

def send_to_chatwork(messgae):
    chatwork_endpoint = "https://api.chatwork.com/v2"
    room_id = 
    API_TOKEN = 

    chatwork_api_url = "{}/rooms/{}/messages".format(chatwork_endpoint,room_id)

    obj = {"body":message}
    data = urllib.parse.urlencode(obj).encode()

    req = urllib.request.Request(url=chatwork_api_url,data=data)


    req.add_header(key="X-ChatWorkToken",val=API_TOKEN)

    with urllib.request.urlopen(req) as res:
        response_body = res.read().decode("utf-8")


    return

if __name__ == "__main__":
    yesterday = datetime.date.today() - datetime.timedelta(1)

    infect_num = get_cvoid_infect_num(yesterday)

    message = "[info][title]コロナ感染者数通知[/title]昨日({})の東京コロナ感染者数: {}人[/info]".format(yesterday.__str__(),infect_num)

    send_to_chatwork(message)
```


send_to_chatwork関数内のroom_idとapi_token変数に自分用のものを入力すればOKです。

```python
def send_to_chatwork(messgae):
    chatork_endpoint = "https://api.chatwork.com/v2"
    room_id = 
    API_TOKEN = 
```

#### スクリプト解析

データ源は東京都ウイルス対策サイトから提供されるCSVファイルです、毎日の午後17時ぐらい更新されるみたいです
https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv

基本的にはこちらのデータから該当する日付の感染者データをカウントします。
pandasというデータ処理のライブラリを使っています、興味ある方は以下を参照してください
https://pandas.pydata.org/

```python
def get_cvoid_infect_num(date):

    url = "https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv"
    df = pandas.read_csv(url,header=None)

    df_filtered = df[df[4]==date.__str__()]

    infect_num = len(df_filtered)

    return infect_num
```

chatworkの送信は以下の関数で処理する、chatwork api tokenやroom_idを入力すればOKです
使用するエンドポイント```https://api.chatwork.com/v2/rooms/{$room_id}/messages```

```python
def send_to_chatwork(messgae):
    chatwork_endpoint = "https://api.chatwork.com/v2"
    room_id = 
    API_TOKEN = 

    chatwork_api_url = "{}/rooms/{}/messages".format(chatwork_endpoint,room_id)

    obj = {"body":message}
    data = urllib.parse.urlencode(obj).encode()

    req = urllib.request.Request(url=chatwork_api_url,data=data)


    req.add_header(key="X-ChatWorkToken",val=API_TOKEN)

    with urllib.request.urlopen(req) as res:
        response_body = res.read().decode("utf-8")

    return
```

chatwork APIの使用方法は以下を参照してください
https://developer.chatwork.com/ja/index.html


###おわり

第二回の緊急事態宣言が終了しましたが、コロナの感染がまだ完全に収束するまでまだ遠いなので
マスクをかけ、手洗いを忘れずにで頑張りましょう
jQueryでaddClass()とfadeIn()を一緒にやる方法

ある要素をクリックし、別の要素を表示させる処理を実装しているときに、おしゃれに表示させたいと思い、fadeIn()を使うことを考えましたが、addClass()と一緒に使う方法に詰まりました。

ここでは備忘録も兼ねてその方法を残しておきたいと思います。

#addClass()とfadeIn()を一緒に使う方法

まずはHTMLです。尚、jQueryはCDNを使用しております。

```index.html
    <div class="js-click-one">1</div>
    <div class="js-two invisible">2</div>
```

次にCSS。

```style.css
.invisible{
    display: none;
}
```

仕組みとしては、1をクリックするとCSSのinvisibleクラスがjs-click-oneに付与され表示されなくなり、js-twoのinvisibleクラスをとり、fadeInで表示させることをイメージしています。

そして、そのイメージをコード化したのが下記です。

```app.js
$(function (){
    $('.js-click-one').on('click', function (){
        $('.js-click-one').hide().addClass('invisible');
        $('.js-two').fadeIn(3000, function (){
            $(this).removeClass('invisible');
        })
    })
})
```

こうすれば、addClass()とfadeIn()を同時に使えます。
ぜひご参考に。
Mailhogでメール送信テスト環境を作成する。(Windows)

Source:
https://github.com/mailhog/MailHog

v1.0.0
https://github.com/mailhog/MailHog/releases/v1.0.0

Windowsは下記いずれかをダウンロードする。
MailHog_windows_386.exe
MailHog_windows_amd64.exe

1.ダウンロードした実行ファイルをどこかに配置する。
2.exeファイルを実行する。
3.Mailhogがウィンドウで表示される。
4.ブラウザでlocalhost:8025にアクセスするとMailhogの画面が表示される。
3.メール送信側で下記を指定する。
 -smtpServer:localhost
 -port:1025

Powershellで下記を実行したらMailhogでメールが受信されます。

```
Send-MailMessage -To "to_mail@test.com" -From "from_mail@test.com" -Subject "Test Dayo" -SmtpServer "localhost" -Port 1025
```

*設定を変更できるとは思いますが、方法が分からないので、ご存知であれば教えていただけると嬉しいです。

参考：
https://kinsta.com/blog/mailhog/
WGCNA::blockwiseModulesのエラーを解決する

`Error in (new("standardGeneric", .Data = function (x, y = NULL, use = "everything",  : 
  unused arguments (weights.x = NULL, weights.y = NULL, cosine = FALSE)`

というエラーが出た場合、基本的にはWGCNAの`cor`関数のconflictが原因なので

```{R}
cor <- WGCNA::cor
```

で`cor`をWGCNAのもので定義してあげると`WGCNA::blockwiseModules`のエラーが起きなくなると思います。いろいろと調べたんですけど、英語のウェブサイトにくつか上がってましたね…。

https://programmersought.com/article/90752004413/
Lambda関数で「AWS-SDK」をローカル環境でのみ読み込み、本番デプロイでは除外する方法

### 結論

こうすればいい

```bash
cd ~
# グローバルパッケージのインストール先確認
npm root -g
# グローバルインストール
npm install -g aws-sdk
# グローバルパッケージが本当にインストールされたかを確認する
npm list -g --depth=0
# ローカルパッケージとして読み込みたいプロジェクトディレクトリに移動する
cd ~/environment/myLambdaProjectName
# グローバルパッケージとローカルパッケージのシンボリックリンクを作成する
npm link aws-sdk
# ローカルパッケージとして読み込まれているかを確認する
npm list --depth=0
```

あとはこれをZIPファイルにまとめてデプロイするなり、なんなりと

### 何がしたいか

私が開発したあるプロジェクトは、DynamoDBからレコードを取り出して、
RdsDBにINSERTするという行為をLambda関数で実現するというものでした。

本番環境のLambdaは最初からAWS-SDKパッケージが用意されているので、
ローカルパッケージとしてZIPファイルに含める必要はありません。ファイルサイズが増えるだけです。

しかし、ローカル環境(Cloud9)にAWS-SDKパッケージがないので、
今までは `npm install aws-sdk` して毎回AWS-SDKをローカルインストールして、
本番デプロイ前に手動でaws-sdkディレクトリを削除するという何ともアレな運用をしていました。

何か、ローカル環境だけAWS-SDKを読み込ませて、
本番デプロイ時は手動削除しないで良い方法を探したら、上の方法を見つけた次第です。

他に良い方法をご存じの方がいましたら、教えてください。

### 追記

Cloud9環境で、ローカルからLambdaにデプロイする場合は、次の手順で行います

```bash
cd ~/environment/myLambdaProjectName
zip --symlinks -r hoge.zip .
```

左サイドバー > AWS > AWS: Explorer > Asia Pacific (Tokyo) > Lambda > {myFunctionName}

アップロードしたいLambda関数名を右クリック、Upload Lambda > ZIP Archiveを選択、
先ほどZIP圧縮したファイルを選択して、OKボタンを押すと、デプロイできます

うまくいけば、画面右上にちっさく `Successfully uploaded Lambda function {myFunctionName} ` が表示されます

本当にAWS-SDKが除外されてアップロードされているかは、以下の手順で確認できます

1. Lambdaコンソール画面に移動

https://ap-northeast-1.console.aws.amazon.com/lambda/home?region=ap-northeast-1

2. Lambda > 関数 > {myFunctionName} に移動

3. 画面右上、アクション > 関数のエクスポート > デプロイパッケージのダウンロード

4. ダウンロードしたZIPファイルを開き、node_modulesディレクトリ内にaws-sdkディレクトリがないことを確認する

Upload Lambda > Directory を使うことでもデプロイはできますが、
そちらはシンボリックリンクを辿って、
実ファイルを含んだ状態でアップロードしてしまうので、
ファイルサイズを抑えることができません。
JS~配列~

今回は、JSで配列を作っていきます！

#配列
```index.js
<body>
  <script>
    'use strict'

    const fruits = ["バナナ", "りんご", "みかん"]
    document.write(fruits);
  </script>
</body>
```

定数にフルーツを代入していきます。今回は、バナナとりんごとみかんを並べました。
ブラウザで表示すると以下のようになります。
![スクリーンショット 2021-04-05 10.23.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/bcd68fa1-5215-d889-d1d1-201d2bd60c7a.png)

#取り出す
では、この配列から１つ取り出して行きたいと思います。

配列は、左から順番に0番目と考えます。
今回は、りんごを取り出したいと思います。

```index.js
<script>
    'use strict'

    const fruits = ["バナナ", "りんご", "みかん"]
    
    document.write(fruits[1]);
  </script>
```
今回のりんごは1番目の配列になります。

![スクリーンショット 2021-04-05 10.27.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/59429129-df0d-f0cb-ea76-49824f7a2ed1.png)

#追加、削除
次に、この配列に追加と削除をしていきたいと思います。

```index.js
<script>
    'use strict'

    const fruits = ["バナナ", "りんご", "みかん"]
    // document.write(fruit);
    // document.write(fruit[1]);
    fruits.pop();
    fruits.push("もも");
    document.write(fruits);
 </script>
```

popで末尾のみかんを削除して、pushで末尾にももを追加しました。

![スクリーンショット 2021-04-05 10.43.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/227090d8-2fe5-c8d0-64d6-ac033952d299.png)

```index.js
const fruits = ["バナナ", "りんご", "みかん"]
    fruits.shift();
    fruits.unshift("マンゴー")
    document.write(fruits);
```
文頭のバナナを削除し、マンゴーを追加しました。

![スクリーンショット 2021-04-05 11.57.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/9c6bc51d-d334-44ba-eb0e-f754bcfe45c5.png)

*pushとunshifyは一度に複数の要素を追加することができます。

#途中の要素を追加、削除

削除数よりも多い数を追加する場合に使います。

```index.js
<script>
    'use strict'

    const fruits = ["バナナ", "りんご", "みかん"]
    fruits.shift();
    fruits.unshift("マンゴー");
    fruits.splice(1,2,"さくらんぼ","ぶどう");
    document.write(fruits);
  </script>
```

以下のようになりました！！
![スクリーンショット 2021-04-05 12.11.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/2cba6382-430e-7241-b7cd-4f5ffe17713b.png)
【備忘録】Migrationファイル変更の際は注意が必要！

Migrationファイルに変更、修正が必要になった際に気をつけなければならないことについて、
備忘録に残しておきます。

# 結論：rails db:rollbackコマンドを実行することでupをdownに変更してから、Migrationファイルを変更、修正する。

流れとしては、
まず以下コマンドで現在のMigrationファイルの状態を調べる。


```ruby:ターミナル
$ rails db:migrate:status
```

するとこのように表示される。

```ruby:ターミナル
database: my_portfolio3_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210404083931  Devise create users
   up     20210404090003  Create articles
   up     20210404093852  Create comments
```


もしカラムを間違えて作成してしまったり、カラムの追加が必要なときに、
upになっているMigrationファイルを単に編集してrails db:migrateをしただけでは、
正しく読み込まれない。
さらに、Migrationファイルの中身とデータベースの中身に差異が生じる危険もあるため、
やってはならない。

ではどういう流れでMigrationファイル変更すればいいのかと言いますと・・・、

「まず$ rails db:rollbackを実行してから」というのが答えになります！

```ruby:ターミナル
$ rails db:rollback
```

```ruby:ターミナル
== 20210404093852 CreateComments: reverting ===================================
-- drop_table(:comments)
   -> 0.0481s
== 20210404093852 CreateComments: reverted (0.0550s) ==========================
```
実行後、現在のMigrationファイルの状態を以下コマンドで調べてみると・・・

```ruby:ターミナル
 $ rails db:migrate:status
```

```ruby:ターミナル
database: my_portfolio3_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210404083931  Devise create users
   up     20210404090003  Create articles
  down    20210404093852  Create comments
```

１個、downになっていますね！

このようにして、１個ずつrollbackしていきます。
私の場合、編集したかったのは「Create articles」だったのであと一回rollback。

```ruby:ターミナル
$ rails db:rollback
```

```ruby:ターミナル
== 20210404090003 CreateArticles: reverting ===================================
-- drop_table(:articles)
   -> 0.0373s
== 20210404090003 CreateArticles: reverted (0.0417s) ==========================
```
実行後、現在のMigrationファイルの状態を以下コマンドで調べてみると・・・

```ruby:ターミナル
 $ rails db:migrate:status
```

```ruby:ターミナル
database: my_portfolio3_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210404083931  Devise create users
  down    20210404090003  Create articles
  down    20210404093852  Create comments
```

「Create articles」もdownになりました！

あとは、単純にMigrationファイルを編集して、そのあとrails db:migrateを実行する。

（補足）ちなみに削除する際は下記コマンドを実行。

```
$ rm db/migrate/20210704125813_create_tweets_rb
```

実行までしたあと、念の為以下コマンドで確認してみると、

```ruby:ターミナル
 $ rails db:migrate:status
```
```ruby:ターミナル
 database: my_portfolio3_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210404083931  Devise create users
   up     20210404090003  Create articles
   up     20210404093852  Create comments
```
ちゃんとまたupの状態に戻っていますね！
これで編集完了です！
rails sでサーバーを立ち上げてみると、ちゃんとエラーが解消されていました^^


【参考記事】
https://pikawaka.com/rails/migration
Nginx not starting: Address already in use (nginx: bind to 0.0.0.0:80 failed)

## 概要
ローカルでnginxを起動しようとするとタイトルエラーになったので解決方法をメモ

## 結論
apacheがすでに起動しており、80番portを使っていたため

```
$ sudo nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
nginx: [emerg] still could not bind()
```

80番portを使用しているプロセスを確認してみると、httpd(apache)を発見

```
$ sudo lsof -i:80
httpd    77 root    4u  IPv6 0xd09cf808e840caf7      0t0  TCP *:http (LISTEN)
httpd   253 _www    4u  IPv6 0xd09cf808e840caf7      0t0  TCP *:http (LISTEN)
httpd   638 _www    4u  IPv6 0xd09cf808e840caf7      0t0  TCP *:http (LISTEN)
httpd   671 _www    4u  IPv6 0xd09cf808e840caf7      0t0  TCP *:http (LISTE
 ```


## やったこと
apacheのstop

```
sudo apachectl stop
```

nginxを起動

```
sudo nginx
```

念の為、起動できているか確認

```
ps -ef | grep nginx
    0 24549     1   0 11:33AM ??         0:00.00 nginx: master process nginx
   -2 24550 24549   0 11:33AM ??         0:00.00 nginx: worker process
```
無事起動できました！
CMSの仕組みが垣間見えた。

備忘録です。
PHP学習してまだ間も無いですが、CMSの仕組みが垣間見えた気がする。
HPによくあるプレスリリースなどのコンテンツを管理したい場合などに便利かなと思います。

例）news記事を読み込んで、画面表示したい。

htdocsの中に格納してあるsample.phpで、別フォルダで管理しているnews.txtを読み込んで表示したい場合は、
sample.php内でfile_get_contents()メソッドを使用。()にはnews.txtのフォルダパスを記載。

$news = file_get_contents('../../news_data/news.txt');
print($news);

※私の場合は、悪意のあるアクセスを避ける為に、news.txtのフォルダをhtdocsの外に移動させました。

注意点：開発環境によってはフォルダへのアクセス権限がなく、画面表示がうまくいかない場合がある。その際は、フォルダ権限を注意深く確認する。

これを使いこなせれば、シンプルかつ強力なCMSが構築できるのでは無いかとワクワクした次第です。

環境：MacOS、MAMP、GoogleCｈｒome
ruby　インスタンスの生成問題

## 初めに
初学者です。rubyの問題を自分なりに解説することによって定着させるのが目的です。間違いなどありましたらご指摘お願いします。

#### 問題
クラスFruitを定義して以下のように出力してください。

```
採れたて新鮮な果実です
リンゴは120円です
オレンジは200円です
イチゴは60円です
```

雛形

```ruby
class Fruit
 def クラスメソッド
   # 正しくメソッドを定義した上で、ここに処理を記入してください
 end

 def initialize
   # ここに処理を記入してください
 end

 def インスタンスメソッド
   # 正しくメソッドを定義した上で、ここに処理を記入してください
 end
end


# 3つのインスタンスを生成してください

# クラスメソッドを呼び出し、「採れたて新鮮な果実です」と表示してください
# インスタンス毎にインスタンスメソッドを呼び出し、「【名前】は【価格】円です」と表示してください
```

####解答
ではまずインスタンスの生成とインスタンス変数を定義します。
今回`initialize`メソッドが使用されています。`initialize`メソッドとは`new`メソッドの引数を受け取ることができます。
そして`initialize`メソッドでインスタンス変数を作り、`new`メソッドで受け取った値を代入します。

```ruby
class Fruit
 def クラスメソッド
   # ここに処理を記入してください
 end

 def initialize(name, price)
   @name = name
   @price = price
 end

 def インスタンスメソッド
   # 正しくメソッドを定義した上で、ここに処理を記入してください
 end
end


apple = Fruit.new("リンゴ", 120)
orange = Fruit.new("オレンジ", 200)
strawberry = Fruit.new("イチゴ", 60)
```
次にクラスメソッド`fresh`を定義します。

```
class Fruit
 def self.fresh
   puts "採れたて新鮮な果実です"
 end
#以下省略
```
次に`initialize`メソッドで作ったインスタンス変数を使用して、`リンゴは120円です`と出力できるようにインスタンスメソッドを定義していきます。

```ruby
#以下省略
 def introduce
   puts "#{@name}は#{@price}円です"
 end
#以下省略
```
ここまで書けたら定義したインスタンスメソッドとクラスメソッドを呼び出します。

```ruby
class Fruit

 def self.fresh
   puts "採れたて新鮮な果実です"
 end

 def initialize(name, price)
   @name = name
   @price = price
 end

 def introduce
   puts "#{@name}は#{@price}円です"
 end
end

apple = Fruit.new("リンゴ", 120)
orange = Fruit.new("オレンジ", 200)
strawberry = Fruit.new("イチゴ", 60)

Fruit.fresh
apple.introduce
orange.introduce
strawberry.introduce
```
ちょっと複雑に見えますが、クラスメソッドとインスタンスメソッドは呼び出す記述をしなければ何も起こりません。
よってクラス定義のあとに呼び出す記述をします。
今回ですと `apple = Fruit.new("リンゴ", 120)` 以降が呼び出す記述です。
`apple = Fruit.new("リンゴ", 120)` の記述で`initialize`メソッドが呼ばれてインスタンス変数に値を代入。
`Fruit.fresh`の記述でクラスメソッドが呼ばれて、`puts "採れたて新鮮な果実です"`が実行されます。
最後に`apple.introduce`の記述で`introduce`メソッドが呼び出され、最初に作られたインスタンス変数が使用されるといった流れになります。
Mac JISキーボードで瞬時に中国語入力に切り替える！

Mac OS (Catalina)には入力言語切替のショートカットがあるが、全然ショートじゃなくてめんどくさい！！
デフォルトだとコントロール＋スペースキーで言語選択ポップアップが出てくるので言語を選択肢て切り替える。いや、「かな」キーで日本語に切り替えるみたいに、１キー操作でやらせてよ！

ということで、これを[Karabiner-Elements](https://karabiner-elements.pqrs.org/)を使って実現する。めっちゃ簡単！

Karabiner-ElementsはMacのキーレイアウトやショートカットなどをかなり高度にカスタマイズさせてくれるアプリ。
使い方はググればいくらでも出てくるので割愛する。

## 概要

今回は shft+かなキー で中国語に切り替える、という設定をする。

もちろん、かなキー単体で日本語入力、英数キーで英数入力になるのは変わらないので、切り替えがめっちゃ楽になる。

JISキーボードで中国語に切り替えるという設定は、[ここ](https://ke-complex-modifications.pqrs.org/)で良さげなルールを見つけてインポートすることでもできるが、shift+かなキーのルールはなかったので作ってみた。でも、非常にシンプルなJSONでできる。


## 設定方法
shft+かなキー で中国語入力に切り替えるルールを作成する。

```JSON
{
  "title": "Chinese input on a JIS keyboard",
  "rules": [
    {
      "description": "Shift + Kana to Chinese input",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "japanese_kana",
            "modifiers": { "mandatory": [ "shift" ] }
          },
          "to": [
            {
              "select_input_source": {
                "language": "zh*"
              }
            }
          ]
        }
      ]
    }
  ]
}
```

このJSONに関しては、シンプルすぎて説明することがない。[公式リファレンスはこちら](https://karabiner-elements.pqrs.org/docs/json/)

このJSONファイルを所定の場所に保存する。

保存する場所はPrefereceを開いて、Miscタブの右下の「Open config folder」で開いて
![Screen Shot 2021-04-05 at 10.44.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/81bea51a-8462-f15b-8233-b7a0808976bf.png)
そのディレクトリ下の `assets/complex_modifications` ディレクトリ。ファイル名は何でも良い。

そして、Complex modificationタブからルールを追加する。
![Screen Shot 2021-04-05 at 14.42.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/0af0e1a9-02dd-b098-48c7-b6e3425cfd9b.png)

追加したJSONファイルのルールが見えているはず。
![Screen Shot 2021-04-05 at 14.43.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/29771af5-c461-d69d-7e4e-bc8c6d6271fb.png)
これのEnableボタンを押せば有効になる。

うまく行かない場合は、Logタブでエラーがないか確認できる。
![Screen_Shot_2021-04-05_at_14_49_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/5eec4d64-1c57-6a0f-637d-84f679bae6ef.png)


もっと詳しく知りたい場合は[こちらの方がよくまとめてくれている](https://qiita.com/s-show/items/a1fd228b04801477729c)。

Karabiner-Elements最高！
【Python】電話番号のハイフンに似ている記号を統一して正規化する

#コード作成のきっかけ
CSVファイルに保存されていた電話番号を読み込み、別のシステムに送る時に事件は起きました。
CSVファイルに保存されていた電話番号は、全角ハイフンだけでなく、マイナス（−）やダッシュ（―）、エンダッシュ（–）などで区切られていたのです・・・。
送り先のシステムでは、電話番号を半角ハイフンでしか読み取る事ができず、このままではエラーが起きてしまいます。
その為、変換するプログラムを作成しました。
これは、phonenumbersを知らなかった時に作成したプログラムになります。
（phonenumbersってすごい。。。 [phonenumbers Python Library](https://pypi.org/project/phonenumbers/)）

#対象の電話番号
CSVファイルを見てみると、様々な電話番号がありました。
全角数字の電話番号、()で数字を分けた電話番号、スペース(空白)で分けた電話番号、国際電話表現になっている電話番号、幸いなことに数字のみの電話番号はありませんでした。
今回は数字だけの電話番号をハイフンで分ける事はできないプログラムになります。
（03とか0120とか、数値によってハイフンの位置を決める必要があります。この規則性をコーディングするのは面倒なので、そのような場合はphonenumbers使うと便利です。）

```number.py
print(number_format('0120-123-123')) #半角
print(number_format('０１２０ー９９９ー９９９')) #全角
print(number_format('03(1111）２２２２')) #()付き 全半角
print(number_format('090 １１１１ 2222')) #空白区切り 全半角
print(number_format('０８０ー1111−2222')) #全角のハイフンとマイナス記号 全半角
print(number_format('+81-90-1234ー５６７８')) #国際電話での表現 全半角
```

#半角ハイフンの電話番号に変換する
半角ハイフンの電話番号に変換する為に、まずは全角の数字を半角に変化します。
また、電話番号を一度数字の固まりごとに分割し、分割した数字を半角のハイフンで連結する事にしました。（電話番号内のマイナスやダッシュを検索し、半角ハイフンにする事も考えましたが、全てのハイフンっぽいものを洗い出すのではなく、今回は記号の部分を半角ハイフンに変換する方向性で進めました）
国際電話の場合は、+81を取り出して、0を先頭につける事にします。
これらの処理をPythonでコーディングしたものが、以下になります。

```code.py
import re

def number_format(call_number):
    format_number = ''
    hyphen = '-'

    hankaku = str.maketrans({chr(0xFF01 + i): chr(0x21 + i) for i in range(94)}) #全角を半角に
    split_number = re.findall(r'\d+', call_number) #数字のみ取り出す

    if call_number[:1] == '+' or call_number[:1] == '＋': #+81の国際電話番号の場合
        del split_number[0]
        format_number = '0' + split_number[0]
    else:
        format_number = split_number[0]

    for i in range(1, len(split_number)): #分割した数字を繋げる      
        format_number += hyphen + split_number[i]
        
    return format_number.translate(hankaku) 
```

#結果
結果としては、以下のように半角数字、半角ハイフンの電話番号に置換する事ができました。

```kekka.log
0120-123-123
0120-999-999 
03-1111-2222 
090-1111-2222
080-1111-2222
090-1234-5678
```

今回は、数字だけの電話番号を半角ハイフンのフォーマットに変換する事はできていませんが、半角ハイフンに似ている記号を使用した電話番号を半角ハイフンの電話番号に変換する事はできました。
Gitを使った作業の流れ


##clone
プロジェクトをローカルにダウンロードすることを、"Cloneする"といいます。
【手順】
1. BitbucketやGitHubの、リポジトリページから、Clone用のコマンドをコピー
2. ターミナル（コマンドプロンプト）でダウンロード先に移動
3. コピーしたコマンドを実行

※注意※
Clone用のコマンドには「HTTPS」「SSH」の2種類があります。
予めSSHキーを設定している場合は「SSH」を選択してからコピーするようにしてください。

##branchをきる

####現在のbranchを確認する

```
git branch
```
「*master」と返ってくると思います。
このbranchが大元になるので、共同開発の場合このbranchを直接編集することは基本しません。


####作業用のbranchを作成し、そこに移動する
masterから、作業用のbranchを作成します。
![branch0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296025/433792ee-1ece-d4d1-136f-dd2ae68cb4eb.png)

下記のコマンドで、新規branchの作成、移動を一気に行います。

```
git checkout -b 新しいbranch名
```


##実作業
作業用のbranchに移動できたら、そのまま実作業を行います。
作業の中で、細かくセーブポイントを置くことができます。（commitするといいます）

### status

```
git status
```
赤い文字でファイルパスのリストが返されると思います。
これが、編集したファイルの一覧です。

### add
編集したファイルをステージングエリアにupします。

```
git add ファイルパス
```
編集したファイルがたくさんある場合、一つずつファイルパスを指定して行くのは大変なので、一括でupするコマンドが以下です。
ただし、このコマンドを使うときは必ず不必要なファイルが含まれていないかstatusコマンドで確認してください。

```
git add .
```

### commit
addした差分ファイルを、セーブポイントとして保存します。
この時、"コミットメッセージ"というものを添えなければなりません。
そのコミットに含まれる編集内容を、他の開発者や未来の自分が見てもわかるように書く必要があります。

```
git commit -m 'コミットメッセージ'
```
![branch1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296025/e4a0f84e-64e7-85f7-e183-11d5858ddffa.png)

##push

作業した内容を、リモートリポジトリ（BitbucketやGitHubのリポジトリ）に送信します。

```
git push origin 作業用branch名
```

##プルリクエスト
リモートリポジトリで、「ブランチ」ページに移動し、自分が作業したbranchから「プルリクエスト」を作成する。

##merge
作業者とは別の確認者が、プルルクエストを確認して問題なければ、作業用branchをmasterに統合します。
この統合のことをマージといいます。
![branch2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296025/e0f37bcc-36a1-7dda-1170-b4f335de8e74.png)


##pull
ターミナル（コマンドプロンプト）に戻り、masterブランチに移動します。

```
git checkout master
```
移動できたことを確認するには以下のコマンドを使用します。

```
git branch
```
*（アスタリスク）がついているbranchが、現在いるbranchです。

以下のコマンドで、リモートリポジトリのmasterの状態を、ローカルリポジトリのmasterに反映させます。

```
git pull origin master
```
これでローカルのmasterが最新の状態になりました。
この状態で、先頭のbranchを切る作業に戻り、新しい作業を始める、というのが全体の流れとなります。
※注意※
branchを切る前にmasterを最新にしておかないと、後々面倒なことになりかねませんので忘れないようにしてください。（最悪の場合、他の人の作業を無かったことにしてしまう可能性も...）
マウスホバー時にボタンを大きくする

LPやHPが寂しい時にボタンを大きくするって考えがちですよね。
それの良し悪しは置いといて、マウスホバー時にCSSでボタンを大きくする方法を見ていきましょう。

#CSSでボタンを大きくする

まずはボタンのHTMLです。

```index.html
<button class="btn">ボタン</button>
```

次にcssです。

```styel.css
.btn{
    /*btnを大きくする処理*/
    transition: all 0.3s ease;
    /*btnのcss*/
    width: 200px;
    height: 60px;
    background: aqua;
    color: black;
    border: none;
}
.btn:hover{
    /*btnを大きくする処理*/
    transform: scale(1.15,1.15);
    /*btnのcss*/
    cursor: pointer;
}
```

以上がマウスホバー時にボタンを大きくする方法です。

ブラウザによってはスタイルが当たらない場合があるので、その際はブラウザごとに必要なwebkitなどの処理を追加してください。
AWS Lambdaで天気予報を毎朝LINEへ通知してみた【Python】

# 背景

偏頭痛の気配を感じて天気予報を調べたら、案の定、天気は下り坂で、、、なんていうことがあり、自身の健康管理のためにも天気予報を毎朝LINEへ通知してみることにしました。

先人たちの知恵をお借りするなどして解決できたことを、この場をお借りして感謝するとともに、大変恐縮ですが**自分のメモ**として、こちらへまとめておきます。

# 開発等

先日、記事とした「[AWS Lambdaで列車運行情報を定期的にLINEへ通知してみた【Python】](https://qiita.com/_whitecat_22/items/1fc804847dce27d5fb94)」の天気予報版です。
詳細は、こちらの記事をご参照ください。
[![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/902793/5b0be47a-9c29-21bd-23ef-d42b1a44f0ae.png)](https://qiita.com/_whitecat_22/items/1fc804847dce27d5fb94)



# 実行

- 実行結果

（...気圧も表示できたらなぁ～😢）

![weather_forecast_tenkijp.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/902793/8172e792-ceba-992a-6ee6-d315689c4486.png)



---
### 参考

- [AWS Lambdaで列車運行情報を定期的にLINEへ通知してみた【Python】](https://qiita.com/_whitecat_22/items/1fc804847dce27d5fb94)

---
### (編集後記)
（お願い）APIを利用できる情報提供者からは、必ずAPIを使いましょう。

みなさんも様々なアイディアで活用いただけたら幸いです。

会社でのコミュニケーションツールは主が Slack のため、今後は、Slack への通知も試してみます。
Ubuntu16.04でLogicoolのワイヤレス機器を使う

#概要
ロジクール ワイヤレスマウス　MX ERGO
ロジクール ワイヤレスキーボード KX1000s
を購入したので、GPU計算用のUbuntu16.04に接続した。

#やり方
1. apt-get でSolaarをインストールする
1.  ログアウトしてインストールされていることを確認する
1.  マウスのスイッチをOFFしてONする

## 1.Sollarのインストール
```shell:
$ apt-get update
$ apt-get install -y solaar
``` 

## 2.GUIでログアウトしてログインする

## 3. 2つ目の記事を参考にマウス裏のスイッチをOFFにしてONにする




#参考記事
Ubuntuでの接続は以下を参考
https://qiita.com/nmatayoshi/items/e57b2b94d8b58746d361
マウスの接続には以下を参考
https://did2memo.net/2017/10/02/mx-ergo-mxtb1s-setup-unifying/
他人のLaravelのプロジェクトの動かし方

他人のLaravelのプロジェクトを `git clone` やダウンロードでローカルに落として動かすことがあるのでその方法を紹介する。

##外部ファイルのインストール

```
$ composer update
```
まず、目的のプロジェクトまで移動して、CLIで必要なライブラリを上記コマンドで取り入れる。

##.envファイルの修正

マイグレーションファイル等を書き換える場合は ` .env` のファイルを書き換える必要がある。
特にDBの設定部分はここによって違うので自身の環境に合わせなければならない。

```:.env
DB_CONNECTION=DBの種類
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=データベース名
DB_USERNAME=ユーザー
DB_PASSWORD=パスワード
```
さらにアプリケーションキーを作成する必要もある。

```
$ php artisan key:generate
```

時々 ` .env` のファイルが反映されない時があるのでその時はこちらの記事を参考にしたらうまく参照させることができました。
https://qiita.com/yukke7624/items/14f29d126e38a7d86646



##マイグレーション

```
$ php artisan migrate:fresh
```
このコマンドで新たにマイグレーションを行う。
また、ローカルサーバーも下記コマンドで立ち上げられる。

```
$ php artisan serve
```
システム・トリガーを試す（２）（Oracle Database 19c)

　ユーザーの接続や切断と同時にPL/SQLプログラムを実行したい場合にはログオン・トリガー／ログオフ・トリガーを作成します。利用用途としては、例えばサードパーティ製のパッケージを使っていてALTER SESSION文が実行できない場合でもログオン・トリガーを設定することでクライアントの接続と同時にSQL文を自動実行することができるようになります。

# ログオン・トリガー
　ログオン・トリガーを使うためにはAFTER LOGON ON DATABASEトリガーを定義します。認証が完了した後にトリガーが実行されます。このため認証に失敗した場合は実行されません。以下はログオン・トリガーlogon_trigger1の実装例です。実行ユーザーを確認するために、SYS_CONTEXT関数とUSER関数を実行してアラートログに書きこんでいます。特定のユーザーが接続した場合のみトリガーを発行する場合は「WHEN (USER='SCOTT')」のようにWHEN句を指定するか、PL/SQLブロック内で接続ユーザーをチェックします。

```
SQL> CREATE OR REPLACE TRIGGER logon_trigger1 AFTER LOGON ON DATABASE
DECLARE
    u VARCHAR2(128);
    c VARCHAR2(128);
    s VARCHAR2(128);
BEGIN
    u := USER;
    c := SYS_CONTEXT('USERENV', 'CURRENT_USER');
    s := SYS_CONTEXT('USERENV', 'SESSION_USER');
    DBMS_SYSTEM.KSDWRT(2, TO_CHAR(SYSTIMESTAMP) || ': AFTER LOGON TRIGGER: ' || u || ' : ' || c || ' : ' || s);
END;
/
トリガーが作成されました
```

USER関数とSYS_CONTEXT関数の実行結果は以下の通りです。SCOTT列はユーザーSCOTTを使って認証を行った場合の出力です。SYS列は「$ sqlplus / as sysdba」接続を行った場合の出力です。基本的には接続したユーザーの権限でトリガーが実行されていることがわかります。

|関数|SYS|SCOTT|
|:---|:---|:---|
|USER|SYS|SCOTT|
|SYS_CONTEXT('USERENV', 'CURRENT_USER')|SYS|SYS|
|SYS_CONTEXT('USERENV', 'SESSION_USER')|SYS|SCOTT|

# ログオフ・トリガー
　ログオフ・トリガーを使うためにはBEFORE LOGON ON DATABASEトリガーを定義します。以下はログオフ・トリガーlogoff_trigger1の実装例です。実行ユーザーを確認するために、SYS_CONTEXT関数とUSER関数を実行してアラートログに書きこんでいます。

```
CREATE OR REPLACE TRIGGER logoff_trigger1 BEFORE LOGOFF ON DATABASE
DECLARE
    u VARCHAR2(128);
    c VARCHAR2(128);
    s VARCHAR2(128);
BEGIN
    u := USER;
    c := SYS_CONTEXT('USERENV', 'CURRENT_USER');
    s := SYS_CONTEXT('USERENV', 'SESSION_USER');
    DBMS_SYSTEM.KSDWRT(2, TO_CHAR(SYSTIMESTAMP) || ': BEFORE LOGOFF TRIGGER: ' || u || ' : ' || c || ' : ' || s);
END;
/
トリガーが作成されました
```
USER 関数と SYS_CONTEXT 関数の実行結果は以下の通りです。SCOTT列はユーザー SCOTT を使った接続を切った場合の出力です。SYS 列は SYS ユーザーの接続を切った場合の出力です。基本的には接続中のユーザーの権限でトリガーが実行されていることがわかります。

|関数|SYS|SCOTT|
|:---|:---|:---|
|USER|SYS|SCOTT|
|SYS_CONTEXT('USERENV', 'CURRENT_USER')|SYS|SYS|
|SYS_CONTEXT('USERENV', 'SESSION_USER')|SYS|SCOTT|

ALTER SYSTEM KILL SESSIONで強制切断された場合はログオフ・トリガーは動作しないようです。

```
SQL> SELECT sid, serial# FROM V$SESSION WHERE USERNAME='SCOTT';

       SID    SERIAL#
---------- ----------
       139      35714

SQL> ALTER SYSTEM KILL SESSION '139,35714';
システムが変更されました。
``
Visual Studio Code 小技集(2021年卯月)

# 初めに
ご覧いただきありがとうございます。
この文書では、よく使いそうな小技を備忘録的に集めています。

# ファイル関連
## コード
### 改行コード
#### 改行コードを確認
ファイルを選択すると、画面右下に、キャレットの位置(Ln 1,Col 1)、インデント数(Space: 2)、改行コード(LF)、ファイル形式(YAML)などが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/c0d1d0f6-2680-57f4-02e3-ef96a95b67d5.png)
Viewメニューから「Render Control Characters」をチェックしておくと、エディタ内でも表示される。表示形式は拡張機能により変更できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/de7343f4-5809-9ced-8d8b-81a6b27d1cd9.png)
以下の表示は、「line-ending」拡張機能を入れてある場合。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/ce24af6c-515d-92e3-0d57-c0d8f31336f7.png)

#### 改行コードを変更
右下の改行コード部分をクリックすると、上部に改行コードの選択プルダウンが表示される。
選択することで、ファイル内すべての改行コードが変換される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/e09fad8a-cc0f-08eb-3d30-06438a51cf70.png)

# その他

# 終りに

親記事：[WSL2とVSCで作るWindowsでのDocker内開発環境(2021年睦月)](https://qiita.com/CinTAKE/items/ee348acec54195ef5bd1)
Qiita UI 改善 要望（限定共有投稿の最後の「…」メニューが切れてる）

# 限定共有投稿の最後に出てくる「…」ボタンで表示されるメニューが、画面の外に出てしまって押しにくい、ってか、押せるけど、メニューが隠れてなんて書いてあるのかわからないので、改善してほしいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/7f1c5ffa-f8a4-8ea4-f8de-986cf9248d3f.png)

Qiita運営のみなさま、すばらしい Webサービスを提供いただきありがとうございます。

メニューの位置を修正していただけるとたすかります。

よろしくお願いいたします。