OmniAICreator/Qiita-1.07M huggingface dataset:
[.NET Core] ILをSDKスタイルのプロジェクトでビルドする

.NET Core環境で新しいSDKスタイルのプロジェクト(.ilproj)でビルドする方法です。
[前の記事](https://qiita.com/kenichiuda/items/ce3518c36fe83063a5d9)で「.NET CoreでILをビルドするプロジェクトってどうやるんだ？」って思って調べて見ました。

なお、Visual Studio 2019は対応していないっぽいです。
2020/07/12現在、.NET Core 3.1.301 での情報です。今後も変更は多そうです。

## 結論

https://github.com/jvbsl/ILProj からフォークしてください。

## 大まかな流れ

1. `mkdir ilproj && cd ilproj`
2. global.jsonの作成  
```
echo
{
  "msbuild-sdks": {
    "Microsoft.NET.Sdk.IL": "3.1.4-servicing.20269.1"
  }
}
> global.json
```
3. NuGetの設定  
`curl -OL https://github.com/dotnet/corefx/raw/release/3.1/NuGet.config`
4. ilprojの作成  
`curl -OL https://raw.githubusercontent.com/jvbsl/ILProj/master/ILProj/ILProj.ilproj`
5. ILファイルを作成
6. `dotnet build`

## NuGetの設定とSDK

ilprojファイルの先頭には`<Project Sdk="Microsoft.NET.Sdk.IL">`が定義されていますが、通常の.NET Core SDKには、ILをビルドするSDKが含まれていません。
テンプレートも無いので`dotnet new`ではプロジェクトを作成できません。

ビルドするためのSDKを指定するために、global.jsonを作成します。

```json
{
  "msbuild-sdks": {
    "Microsoft.NET.Sdk.IL": "3.1.4-servicing.20269.1"
  }
}
```

"Microsoft.NET.Sdk.IL"は標準のパッケージソースには存在しませんので、NuGetのパッケージソースに
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json
を追加する必要があります。
面倒なのでdotnet/corefxからコピーしてきましょう。

## ilprojの作成

テンプレートは無いので、これもコピって来ましょう。

```
<Project Sdk="Microsoft.NET.Sdk.IL">

    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
        <MicrosoftNetCoreIlasmPackageVersion>3.1.4-servicing.20269.1</MicrosoftNetCoreIlasmPackageVersion>
        <IlasmFlags>$(IlasmFlags)</IlasmFlags>
    </PropertyGroup>

</Project>
```

複数のターゲットはサポートされていないようで、`<TargetFrameworks>`を書くとエラーになります。

## ビルド

あとは適当な*.ilファイルをディレクトリに追加して、
`dotnet build -c Release`でビルドできます。
Ruby on Railsでデータベースを扱う

#プログラミングの勉強日記
2020年7月13日　Progate Lv.186
Ruby on RailsⅡ


#データベースとは
　テキストや数値などのデータを保存するためのツール。データベースは表でデータを管理している。表のことを<font color=orange>テーブル</font>、縦の列のことを<font color=orange>カラム</font>、横の列のことを<font color=orange>レコード</font>という。必要に応じて複数のテーブルを作成できる。

#データベースの用意
　マイグレーションファイルと呼ばれるデータベースに変更を指示するためのファイルを作成する。`rails g model モデル名 カラム名:型`で作成できる。<font color=blue>モデル名は必ず最初を大文字にして、単数形にする。</font>なので、postsテーブルを作成するが、この場合単数形にする。モデルについては下で記述する。
　マイグレーションファイルは`db/migrate`フォルダの下に作成される。

```:ターミナル
$ rails generate model Post content:text
```
　これを実行すると、`app/models`フォルダにモデルが定義されたファイルと、`db/migrate`フォルダにマイグレーションファイルの2つのファイルが生成される。

##データベースに変更を反映する
　`rails db:migrate`コマンドを実行すると、データベースに変更を反映できる。テーブル作成時には`id`、`created_at`、`updated_at`が自動生成される。データベースに反映されていないマイグレーションファイルが存在する状態でページにアクセスすると、<font color=orange>マイグレーションエラー</font>が発生する。なので、マイグレーションファイルを作成した場合は必ずこのコマンドを実行する。

##Postモデル
　モデルはテーブルを操作するための特殊なクラスである。`rails generate model`コマンドでpostsテーブルを操作するためにPostモデルが定義されたファイル`post.rb`が`app/models`フォルダの中に作成されている。ファイルの中には`ApplicationRecord`クラスを継承する`Post`クラスが定義されている。`ApplicationRecord`を継承したクラスをモデルという。

```ruby:models/post.rb
class Post < ApplicationRecord
end
```

#rails console
　ターミナルで`rails console`と入力し、実行(Enter)するとコンソールを起動できる。コンソールは`quit`を実行すると終了する。コンソールでは変数を定義することができ、`quit`でコンソールを終了するまで使い続けられる。

```terminal:ターミナル
$ rails console
>text="Hello"
=>"Hello"
>text+"World"
=>"HelloWorld"
>quit
```

#テーブルにデータを作成
　postsテーブルにデータを追加するためには、newメソッドでPostモデルのインスタンスを作成し、postsテーブルに保存する。
　1. `rails console`を使ってPostモデルからPostインスタンスを作成する。インスタンスを作成するにはnewメソッドを使う。
　2.  作成したPostインスタンスをpostsテーブルに保存するためにはsaveメソッドを使う。(saveメソッドを使えるのはPostモデルがApplicatuonRecordを継承しているから)

```terminal:ターミナル
$ rails console
>post=Post.new(content:"HelloWorld")
>post.save
```

#テーブルからデータを取り出す
　`Post.first`とすることでpostsの最初のデータを取得することができる。
　`post.content`とすることで、`Post.first`で取得したデータから投稿内容を取得できる。

```terminal:ターミナル
$ rails console
> post=Post.first
> post.content
=> "今日から…"
```
　テーブルに保存されているすべてのデータを取得するには`Post.all`を使う。テーブルにあるすべてのデータが配列で取得できる。投稿の配列から1つのデータを取り出すためには、`Post.all[0]`のようにインデックス番号で1つの要素を取得する。`Post.all[0].content`とすることで投稿内容を取得する。

```terminal:ターミナル
$ rails console
> posts=Post.all[0].content
=> "今日から…"
```

#データベースの表示
　ビューで使う変数はアクションで定義するのが一般的である。通常はアクションで定義した変数はビューで使えないが、変数名を`@`から始めることで特殊な変数となり、ビューファイルでも使うことができる。

　postsコントローラのindexアクション内の`@posts`にPost.allで取得したデータを代入する。ビューでは`@posts`に代入されている配列のデータを1つずつ変数postに代入して投稿内容を繰り返し表示させる。

```ruby:post_controller.rb
def index
  @posts=Post.all
end
```

```erb:osts/index.html.erb
<% @posts.each do |post| %>
  <div class="post-index-item>
    <%= post.content %>
  </div>
<% end %>
```
Puppeteerで検索フォームにテキストを入力してページ遷移する

# はじめに
- 「とあるサイトに文字を入力してボタンを押して結果一覧を表示する」というのを自動化したいケースがあったのでQiitaの検索ページで試してみた。

# ソースコード
- `waitForNavigation` は「呼び出してから次の繊維を待つ」という意味らしく `click` と同期させないと想定通りに動かなかった。
- 後は直感的でとても簡単に書ける。

```javascript
const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();
    await page.goto('https://qiita.com/search');
    await page.type('#q', 'puppeteer');
    await Promise.all([
        page.waitForNavigation(),
        page.click('.searchResultContainer_searchButton')
    ]);
    await page.screenshot({path: 'sample.png'});
    await browser.close();
})();
```

# 実行結果
- ちゃんと検索フォームに文字が入力されて結果が表示されている。
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264912/cf407215-3aa5-6c1d-c6df-1793b0b7a32c.png)

# 参考文献
- [Puppeteer入門 スクレイピング+Web操作自動処理プログラミング](https://www.amazon.co.jp/dp/4798055204)
- https://qiita.com/hnw/items/a07e6b88d95d1656e02f
【Mac】重複したPATHを削除する【zsh】

# zshrcでPATHを通したい
仕事用のメインPCをWindowsからMacに切り替えた。
どうやらMacではプログラムを走らせようとすると何かとPATHを通すように要求されるらしい。
PATHを通すことでどのディレクトリでもそのプログラムをランできるようになる。

# bashとzsh
プログラムを動かすターミナルにはシェルと呼ばれるものがあって、これがMacOSのバージョンによって異なることがわかった。
シェルの種類によって、そもそものPATHの通し方の設定自体も変わってくる。
MacOSのシェルにはbashとzshの２種類があり、自分のシェルはzshだった。
確認するためのコマンドは
```
echo $SHELL
```
**bash**の場合は**bash_profile**ファイル、**zsh**の場合は**zshrc**ファイルを編集する。


# zshでPATHを通す

GoogleでPATHの通し方を調べると、

1. プログラムのインストール

2. /usr/localとかに移す

3. ~/binにPATHを通す

3-1. ホームディレクトリにある.zshrcファイルをテキストエディットで開く。

```
open ~/.zshrc
```
3-2. 以下の文をPATHを通すディレクトリに合わせて編集して.zsfrcに書き込む。/usr/local/binにPATHを通すなら…

```
export PATH="$PATH:/usr/local/bin"
```

3-3.  .zshrcファイルの変更を適用する。

```
source ~/.zshrc
```

3-4. PATHが通っているか確認する

```
echo $PATH | tr ':' '\n'
```

で、できるらしい。

# 同じPATHを2つ通してしまう…
上記の方法でやると、PATHが上書きされるのではなく、追加されてしまう。つまり、PATHを書き込むごとにどんどんPATHが増えていってしまう。そもそも、.zshrcには追加したいPATHのみを書き込み、次回新たにPATHを追加するときは.zshrcの内容を全てクリアしてから使うものである。だが、PATHの全容をテキストとして見られるように.zshrcには全てのPATHを保存しておきたい。

# zshでの解決法がわからん
解決法を探したが、bashでの解決方法はあるものの、zshについての日本語のページが見つからない。Googleでいろいろ調べていると、海外の質問サイトに答えが載っていた。

# zshrcで重複したPATHを削除する
やることはひとつ、

```
typeset -U PATH
```

**これだけ。**
PATH、であって、pathでもPathでもないことに注意。

終わったら、

```
echo $PATH | tr ':' '\n'
```

で確認。
以上。

確かに重複したPATHがきれいになくなっていた。

# ここで一手間

この処理を毎度のPATHを通す度にタイプするのは面倒なので、これを.zshrcファイルに組み込んで.zshrcファイルの更新を適用するごとに重複を削除する様にする。
.zshrcファイルで

```
export PATH=...
export PATH=...
```

と並んでいる文字列の最後の行に先程の


```
typeset -U PATH
```

を追加すればOK。
これで毎回3-3にある処理をするごとに重複したPATHが削除される様になる。

## 参考ページ
https://stackoverflow.com/questions/11635237/osx-zsh-path-usr-bin-duplicated
SSRなNuxt.jsを環境ごとにDocker化する時の環境変数の扱いについて

# やりたいこと

nuxt.config.jsで環境変数をセットしたい。
本番環境でも動作するSSRなDocker Imageを作りたい。

# 結論

nuxt.jsを本番環境用にdocker化するには、.envを使わずに

1. CIないし、ローカルマシンなど、docker buildする環境でで、環境変数を全て展開(export)する
2. 展開したら `yarn build` を実行する
3. `.nuxt` をCOPYする形で `docker build` してimageを作る

# 経緯

## :x: 手法1: Dockerfileのentrypointを `yarn start` にして、docker-compose等で環境変数を渡す

例えば、nuxt.jsでaxiosを使う場合、APIサーバーなどへのリクエストする時にはbaseURLの設定をする必要がある。
baseURLは環境変数を用いて適用したくなることもある。

ここでnuxt.jsを本番環境で公開しようとした時のステップを整理すると

```
$ yarn build && yarn start
```

のように、一度buildして、そのbuildしたデータ(.nuxtディレクトリ)を使って、startすることでserveできるようになっている。

参考: [API: env プロパティ \- NuxtJS](https://ja.nuxtjs.org/api/configuration-env/#process-env-)

nuxt.jsでは、このbuild時に環境変数を全て展開した上で、.nuxtを作成するようになっている。

---

例: HELLO=world という環境変数がセットされていた時
`console.log(process.env.HELLO)` は 具体的な `console.log('world')` という環境変数の中身によって置き換わったjsファイルが生成されることになる。

---

そのため、build時にはすでに環境変数がセットされている必要がある。
逆に言えば、startのタイミングで環境変数を読み込んでいるわけではない、ということである。

ということは、axiosなどのbaseURLを環境変数で指定する場合、buildの時点で環境変数がセットされている必要があることになる。

その前提でいうと、環境変数の読み込みは、`yarn start`時では遅いということになる。

なので、entrypointを指定する形のdockerfileで、外から環境変数を与えて起動しても、タイミング的に環境変数は.nuxtに適用されない。

```Dockerfile
FROM node:10-alpine

WORKDIR /app
ENV NUXT_HOST 0.0.0.0

COPY ./nuxt .
RUN yarn install && yarn build #この時点で環境変数が埋め込まれ済み

EXPOSE 3000

ENTRYPOINT ["yarn"]
CMD ["start"] # この時点では、例えばNUXT_HOSTは文字列の'0.0.0.0'に直接置き換わっている
```

じゃあnuxtをcopyした時に、.envを読み込ませればいいか？というと、またそうでもない問題が発生する。
あと、.envファイルはimageにあんまり載せたくない気持ちもある。

## :x: 手法2: dotenvを使って環境変数を読み込む

一旦、doetnvを使って環境変数を読み込んでみた。
すると、なんとbaseURLは空になった。

いろいろ検証してみると、どうやらyarn buildの時に、読み込まれる順番として

1. exportされた環境変数が、 `process.env` に読み込まれる
2. nuxt.config.js内での環境変数呼び出し部分に値が入る
3. nuxt.config.jsの中のenvオブジェクトに値が入る( `env: { baseURL: process.env.BASE_URL }` などの記述)
4. dotenvファイルの読み込みが発生して、このタイミングで、 `process.env.BASE_URL` などの値がセットされる
5. clientのjsファイルが、 `process.env` の値を具体的な値に置き換えた状態で生成される

という順番になる様子。

つまり、 **dotenvはnuxt.config.jsの中の環境変数呼び出しには間に合わない**　ということになる。(少なくとも再現時はそうでした)

なので、nuxt.config.jsの中で環境変数を展開して欲しいタイミングでは、dotenvはまだ読み込まれていない状態となる。

## :o: 手法3: .nuxtの生成はCIかローカルマシンで行う

結局この方法をとった、もしかしたら常識だったかもしれないし、もっといい方法があるかもしれないけど、あんまり経験がなかったのでこの方法で実装することにした。

結論と同じだが、環境変数の読み込みは`yarn build`するよりも前に実行する必要がある。
そのため、buildする環境では予め環境変数をセットしておいて、その中でbuildを行うことにする。

なので、ローカルマシンでyarn buildまでは実行しておいてその.nuxt込みでDockerfileにCOPYするようにする。

すると、docker buildしてできたdocker imageは、yarn startするだけでproduction環境として実行可能なnuxt.jsサーバーとなる。

それが結論に書いた方法になる。

build環境で環境変数を予めセットしておかないといけないという煩わしさは、ローカルマシンでbuildできる環境が必要ということはあるものの
いったんこの方法に落ち着きましたので、忘備録として残しておきます。

誰かの役に立つと良いなーと思います、もっといい方法があれば是非教えてください！
Laravel 最小限の記載でルーティングとコントローラの記載が正しいか確認する

# 目的

- 最小限のコードでルーティングとコントローラの記載が正しいことを確認するコードを紹介する。

# 実施環境

- ハードウェア環境

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

- ソフトウェア環境

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

# 紹介

- ルーティングの記載とコントローラ、アクションの作成後、アクション内に下記のコードを記載する。

    ```php
    //var_dumpで出力する文字列はaaaでなくても構わない。
    var_dump('aaa');
    exit;
    ```

- 当該コントローラのアクションと紐づいているURLのリンクにブラウザからアクセスして下記の表示が出ればルーティングの記載、コントローラの記載、アクションの記載が正しいということとなる。

    <img width="837" alt="localhost_8080_item_1_1_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e60c2484-b4f7-981d-243c-edc8d2a80a09.png">
Vue.js3.0移行（is属性を使ったカスタム要素）

# Vue.js 2.x の is 属性を使ったカスタム要素の移行

`is` 属性を使っている箇所を `v-is` に置き換えます。
※Vue.js 3.1で `v-is` は非推奨になっていて、代替構文は `is="vue:xxx"` です。
https://github.com/vuejs/vue-next/blob/master/CHANGELOG.md#310-2021-06-07
https://github.com/vuejs/vue-next/commit/af9e6999e1779f56b5cf827b97310d8e4e1fe5ec

## Vue.js 2.x

```html
<tbody>
  <tr is="my-component" v-for="(foo, index) in bar" :baz="foo" :key="index">
</tbody>

components: {
  'my-component': myComponent
},
```

## Vue.js 3.x

```html
<tbody>
  <tr v-is="'my-component'" v-for="(foo, index) in bar" :baz="foo" :key="index">
</tbody>
```

※componentオプションを使ってコンポーネントを登録した場合
コンポーネントの登録方法によって、記述方法が変わることに注意。
詳細はRFC参照。
https://github.com/vuejs/rfcs/pull/149
Windowsエクスプローラで見えないSDカードをフォーマットして使えるようにする

Jetson Nanoの起動イメージを書き込んで使ったSDカードをWindowsでフォーマットしてもう一度使いたいと思った...が、普通にカードリーダーに差し込んだだけではWindows Explorerから見えない…

ウェブ検索したところ、ラズパイでも同じとのことで、やり方が結構見つかったのでメモしておく。

DiskPartというのがWindowsに入っているので使う。
Windows10では左下の「ここに入力して検索」に「diskpart」と入力したらすぐに見つかった。

DISKPART> list disk　　　（HDDやSDのリストが表示される）
DISKPART> select disk 4　（フォーマットする対象のDISK番号を指定）
DISKPART> clean　　　　　（Windowsがドライブを認識してカードを入れるように言うが無視）
DISKPART> exit　　　　　　（終了）

Windows Explorerからは「不明なサイズ」などと表示されてフォーマットできないので、[SD Card AssociationのSD Card Formatter](https://www.sdcard.org/jp/downloads/formatter/)でフォーマットする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641874/4e024045-a5b1-50ba-930c-c1fad6ad90d9.png)

無事、Windowsで認識されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641874/98f90673-c05f-c1bd-fa91-027c7fc86efb.png)
Unity 学習　3日目

#セッション3　基本のミニゲームを作ろう！
昨日、ダウンロードしたデータをもとに使って早速チャレンジ

###オブジェクト操作
①移動
②回転
③縮尺
変更したオブジェクトを元に戻すときは、inspect_transfome 歯車アイコン_Reset (オブジェクトが形を記憶しているね)


###マテリアルとテクスチャー
Del：削除
Ctrl+z：元に戻す
Ctrl+y：やり直し
ショートカットキーは大体同じだよね・・・

テクスチャーはProject_+_texture
マテリアルは画像から作成…ほかの3Ｄソフトと同様だよね

![スクリーンショット 2020-07-13 00.10.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671354/17157c16-291b-f154-f3ce-13ec2a500c81.png)


###プログラミングに挑戦1
本格的になってきました
プログラムとは手順の指示書
Ｃ＃がUnityで使われているプログラム言語
プログラミングをするのにVisual Studio が必要
インストール時にセットとしてインストールされているはずらしいが、入っていない…最新版ではインストールされないのか？？？

インストールとソフトの関連付けと動作確認までで30分使ってしまったのこで今日はここまで…。
プログラミングまで学びたかった(/ω＼)

#追記
最後のプログラム用アプリケーションがインストールされていなかった問題がちょっと不安
このチュートリアル動画が2018版を想定して作成されているため2020年度版では改良され対応した機能がついていたりするのでは？
とか思ってしまう
とりあえず動作確認と関連付けはできたので、明日以降プログラムを学習していきたい。
フォームの書き方いろいろ

#前提条件

- laravelで書いています。
- blade.phpの書き方




#一般的なフォーム
フォームの中に、サーバーに送りたいデータ（inputタグ）があって、それをbuttonタグでサブミットしている。


```php
<form action="{{ route('create') }}" method="post">
    @csrf
    <div class="md-form">
      <label for="name">名前</label>
      <input  class="form-control" type="text" id="name" name="name" value="{{ old('name') }}" required>
    </div>

    <button class="btn btn-block" type="submit">送信</button>
</form>
```

#ボタンを外出ししたもの。

formタグをblade.phpの下の方にまとめておいて、どのフォームとどのボタンが連携しているのかを


```php
<form id="buttonタグのform属性と同じ名前"></form>
<button form="formタグのidと同じ名前">送信</button>
```

formタグの、id属性
buttonタグのform属性
で連携させているもの。


```php

<form id="buttonタグのform属性と同じ名前" action="{{ route('hoge') }}" method="post">
    @csrf
    <div class="md-form">
      <label for="name">名前</label>
      <input  class="form-control" type="text" id="name" name="name" value="{{ old('name') }}" required>
    </div>
</form>

<button form="formタグのidと同じ名前" class="btn btn-block" type="submit">送信</button>
```




#formタグ、inputタグ、buttonタグをそれぞれ別にしたもの。

一つの画面で、何箇所もボタンがあったり
登録するデータの量が膨大なとき
以下のように書いている現場があった。

formタグ、inputタグ、buttonタグをまとめるのではなく、
別々にすることで、コードを見やすくすることが目的。


書き方の雛形としては、こう。

```php


<button form="formタグのidと同じ名前" class="btn btn-block" type="submit">送信</button>


<form id="buttonタグのform属性と同じ名前" action="{{ route('hoge') }}" method="post">
    @csrf
</form>

<input form="formタグのidと同じ名前" type="text" id="name" name="name" value="{{ old('name') }}" required>


```

なにか登録用のデータを流したいんだとしたら、自分ならこうする。（その現場に合わせるなら）

```php


<button form="store" class="btn btn-block" type="submit">保存</button>

<button form="search" class="btn btn-block" type="submit">検索</button>


<form id="store" action="{{ route('store') }}" method="post">
    @csrf
</form>
<form id="search" action="{{ route('search') }}" method="post">
    @csrf
</form>

<input form="store" type="text" id="name" name="name" value="{{ old('name') }}" required>
<input form="store" type="text" id="email" name="email" value="{{ old('email') }}" required>
<input form="store" type="text" id="address" name="address" value="{{ old('addless') }}" required>
<input form="store" type="text" id="tel" name="tel" value="{{ old('tel') }}" required>
<input form="search" type="text" id="hoge" name="hoge" value="{{ old('hoge') }}" required>
<input form="search" type="text" id="fuga" name="fuga" value="{{ old('fuga') }}" required>


```
コードレビューの指摘から棘をとる言葉（募集中）

いつも使っているテクニックというわけでなく、開発チームの平和に貢献できればと、（もちろん自戒も込めて）今思いついたことです。

やさしさあふれるコメントでのご提案を歓迎します。

# ■間違っているのは私かもしれない系

## 勘違いだったらすみません
実際勘違いのことも（私は）多い。

## 私もあまり自信はないのですが
信頼性の高いサイトの記載を引いてこうありました、とか続く。

## 細かく追ってはいないので問題なかったらすみません
コードレビューにかけられる時間は限られている。
全レビューアが細かい仕様まで把握するのは現実的ではない。
Diff だけでレビューすることもあるでしょう。

# ■一理を認める系

## どちらがいいと一概に言えませんが
前置きしたうえで、代替案のメリットはしっかり伝えた方がいいと思う。

## ～という観点からは、確かにこの方法がいいですね
～という観点からは～という方法がいいと思いましたが。
検討していただく。

# ■私も仲間系

## 私もよく間違えます
レビューイからリスペクトを得られていないと逆にいらだたせてしまうので注意。

## これ紛らわしいですよね
軽く言語仕様やコンポーネントのせいにしてしまう。（ごめんなさい）

## 悩ましいですね
一緒に考える。

# ■質問でワンクッション系

## こういう案もあるかと思いましたが、いかがでしょう
指摘でなく提案。
どれだけ立場、技術力の差があっても、プログラマは自分の書いたコードに関して主導権を奪われたくはない。

## このように実装された意図を教えていただいてもよろしいでしょうか
何か汲み取れなかった意図があるかもしれない。
指摘の精度を高めるためにも。

# ■プログラマの職人性を刺激系

## これ実現できたらすごいですよね
燃える。

## ここだけ直ればなお素晴らしいです
一般的には、先輩が後輩に。

## どちらも解決できる、そんなうまい話はないですかね…
燃える。

# ■細かい指摘でいらだたせない系
## [重要度：低]
実際に低くて受け入れられなくても大勢に影響はない場合。
重要なのに嘘をつく必要はない。

## 細かいところでたいへん恐縮ですが
本当に恐縮なことも多い。

## あえて言うなら
基本的にはOK。
少し上からなので関係性に注意。

## これくらいしか見つかりませんでした
ほかは完璧です！

## ほかは問題ありませんでした
指摘を終えて最後に。
Rails6でGemを使わずシェアボタンを実装する

Railsでページ内に共有シェアボタンがあればいいなっと思いネットでいろいろ調べたのですが
Gemに依存したものが多かったので、自分用のためにも記事を残すことにしました。

# 環境

Rails: 6.0.2.1

# シェアボタン用のアイコンを用意
まずシェアボタン用のアイコンを用意しましょう。
今回はFont Awesomeを使います。

Font Awesomeはyarnからインストールします。

```
yarn add @fortawesome/fontawesome-free
```

まだプロジェクトにWebpackerをinstallしていない場合は下記のコマンド後にインストールを行ってください。

```
rails webpacker:install
```
インストールが完了したら、`app/javascript/`の配下のファイルにインストールしたFont Awesomeをインポートしていきます。

application.js

```
require("@fortawesome/fontawesome-free/js/all")
import '../stylesheets/application';
```
scss側にも読み込んでいきます。

```
mkdir app/javascript/stylesheets
touch app/javascript/stylesheets/application.scss
```

application.scss

```
$fa-font-path: "~font-awesome/fonts/";
@import '@fortawesome/fontawesome-free/scss/fontawesome';
```

`views/application.html.erb`のstyle_sheet_link_tagとjavascript_pack_tagの部分も下記のように変更しましょう。

```
  <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  <%= stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' %>   
```

最後にさきほどのapplication.scssのアイコンカラー用にcssを追加してあげて準備完了です。

```
/* Twitter icon */

.twitter{color: #1da1f2}

/* Facebook icon */

.facebook{color: #4267b2}
```

# リンクの設置

今回はviews側に下記のようにシェアボタンを設定しました。

```
<%= link_to "https://twitter.com/intent/tweet?url=http://localhost:3000/" do %>
  <i class="fab fa-twitter-square fa-4x twitter"></i>
<% end %>

<%= link_to "https://www.facebook.com/share.php?u=http://localhost:3000/" do %>
　　<i class="fab fa-facebook-square fa-4x facebook"></i>
<% end %>
```

TwitterのシェアボタンはTweet Web Intentを使ってシェアできるようにしています。
今回はurlのみの設定になっていますが、他にも下記の設定ができるみたいです。

|  option  |  内容  |
| :----: | :----: |
|  text  |  本文の設定  |
|  hashtag  |  ハッシュタグの設定  |
| url | URLの設定 |

※複数設定する場合は`&`で繋げる

Facebook側のシェアボタンは`https://www.facebook.com/share.php?u=`末尾にシェアしたいURLを記載することでシェアボタンの実装ができるようになります。

# 最後に
今回設定してあるURLはどちらもlocalhostのURLになっています。
実際に実装するときは各自シェアしたいリンクに変えること忘れないように注意しましょう。
"ld: warning: Could not find or use auto-linked library 'XCTestSwiftSupport'"

「RxSwiftやってみよー！」と思い、SwiftPMでRxSwiftをインストール、適当なところでimportしてビルドしようとするも、コンパイルエラーで`Build Failed`に... :cry: 

## エラーログ
```
ld: warning: Could not find or use auto-linked library 'XCTestSwiftSupport'
ld: warning: Could not find or use auto-linked framework 'XCTest'
Undefined symbols for architecture x86_64:
  "__swift_FORCE_LOAD_$_XCTestSwiftSupport", referenced from:
      __swift_FORCE_LOAD_$_XCTestSwiftSupport_$_RxTest in RxTest.o
  "XCTest.XCTFail(_: Swift.String, file: Swift.StaticString, line: Swift.UInt) -> ()", referenced from:
      RxTest.XCTAssertRecordedElements<A where A: Swift.Equatable>(_: [RxTest.Recorded<RxSwift.Event<A>>], _: [A], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
  "XCTest.XCTAssertEqual<A where A: Swift.Equatable>(_: @autoclosure () throws -> A, _: @autoclosure () throws -> A, _: @autoclosure () -> Swift.String, file: Swift.StaticString, line: Swift.UInt) -> ()", referenced from:
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxSwift.Event<A>], _: [RxSwift.Event<A>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxSwift.SingleEvent<A>], _: [RxSwift.SingleEvent<A>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxSwift.MaybeEvent<A>], _: [RxSwift.MaybeEvent<A>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual(_: [RxSwift.CompletableEvent], _: [RxSwift.CompletableEvent], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxTest.Recorded<RxSwift.Event<A>>], _: [RxTest.Recorded<RxSwift.Event<A>>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertEqual<A where A: Swift.Equatable>(_: [RxTest.Recorded<RxSwift.Event<A?>>], _: [RxTest.Recorded<RxSwift.Event<A?>>], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      RxTest.XCTAssertRecordedElements<A where A: Swift.Equatable>(_: [RxTest.Recorded<RxSwift.Event<A>>], _: [A], file: Swift.StaticString, line: Swift.UInt) -> () in RxTest.o
      ...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```

## 原因
Xcode 11.4のバグらしい。11.5で直っていないとのことですが、そこまで調べてはいません...

## 解決策
Swift Package Managerのターゲットを見直して、インストールし直すことで、`Build Succeed`になりました:smile_cat:

|Package Product|Target|
|:-----------------|:-----------------|
|RxSwift|作ったプロジェクト|
|RxCocoa|作ったプロジェクト|
|RxRelay|作ったプロジェクト|
|RxBlocking|作ったプロジェクトの**テスト**|
|RxTest|作ったプロジェクトの**テスト**|

<img width="730" alt="スクリーンショット 2020-07-12 23.52.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532881/59eda69f-b00c-480e-da1a-d7414dabb779.png">

## 参考
https://github.com/ReactiveX/RxSwift/issues/2127#issuecomment-592330682
https://twitter.com/freak4pc/status/1233560587176681472
hpe Microserver Gen8のMicroSDカードにFreeBSDをインストール

hp Microserver(初代)にFreeBSDを入れて使っていたNASを、hpe Microserver Gen8で更新。
FreeBSDのバージョンは12.1、インストーラはmemstic.imgを選択。
##ディスクの認識
インストール時には、インストーラの入っているUSBメモリがda0、MicroSDカードがda1となり、da1にインストールされ、fstabには、

``` :/etc/fstab
# Device	Mountpoint	FStype	Options	Dump	Pass#
/dev/da1p2	/		ufs	rw	1	1
/dev/da1p3	none		swap	sw	0	0
```
と書き込まれる。
インストール後にUSBメモリを抜いて再起動すると、MicroSDがda0となるので起動中にカーネルを見失ない、

```
mountroot> ufs:/dev/da0p2
```
としてルートディレクトリの位置を指示しないと起動できなくなる。
起動後に/etc/fstabを編集して、

``` :/etc/fstab
# Device	Mountpoint	FStype	Options	Dump	Pass#
/dev/da0p2	/		ufs	rw	1	1
/dev/da0p3	none		swap	sw	0	0
```
として再起動するとブートに成功するようになる。
Gatlingのシナリオ作成のTips


## はじめに
負荷試験ツールとしてGatlingを検証してまして、シナリオを作る時に使用したtipsをシェアします。
今後Gatlingを使う方の参考になれば幸いです。

## シナリオで使う変数を共通変数化する
負荷試験のシナリオを複数作成していると、試験先URLなどは共通変数化したくなってきます。
（URL変更するのに全シナリオファイルを書き換えるのは手間なので）
今回はScalaのtrait（トレイト）機能を使用して実装しました。

まず共通変数を管理するファイルを用意します。
以下の例ではhttpBaseUrlという変数にURLの値を定義しています。

```config.scala
trait Config {
  val httpBaseUrl = "https://hogehoge.com"
  :
}
```

次に各シナリオファイルですが、シナリオを定義する時にtraitも読み込むように`with <trait名>`を追加します。
URLを定義する箇所には、先ほど定義した`httpBaseUrl`を入力します。

```BasicSimulation.scala
class BasicSimulation extends Simulation with Config {
    val httpProtocol = http  // 共通のhttps設定
      .baseUrl(httpBaseUrl)  // ベースURLを設定
      .disableAutoReferer    // refererを指定した値のみとするため
    :
}
```

## 負荷パターンの設定を変数化する
先ほど共通変数化したファイルに負荷パターンも定義してみたいと思います。

先に各シナリオファイルの記載を見ていきます。
Gatlingでは`scn.inject`で負荷パターンを指定します。
今回は`constantConcurrentUsers`という、指定した並列数でアクセスし続ける負荷パターンを使用しています。

以下の例では、負荷パターンの並列数・実行時間の部分をそれぞれ`execUser`・`execDuration`と定義します。


```BasicSimulation.scala
    scn.inject(
      constantConcurrentUsers(execUser) during(execDuration)
    )
```

共通変数ファイルには以下のように記載します。<br>
ポイントはduring部分の変数を定義する時にFiniteDurationで変換をするということです。
またFiniteDurationを使用するために`import scala.concurrent.duration._`が必要です。
以下の例では、10並列で5分間（300秒）実行するように定義しています。


```config.scala
import scala.concurrent.duration._

trait Config {
  :
  val execUser        = 10
  val execDuration    = FiniteDuration(300, SECONDS)
  :
}
```

## 1から順にカウントアップするfeederを設定する
GatlingにはfeederというCSVファイルを読み込んで変数を定義することができます。
シナリオで1から順にカウントアップしていくような変数を使いたい場合、feederとfor文を組み合わせて使用する方法があります。


```BasicSimulation.scala
val feeder_ichiman = (for (i <- 1 until 10000 ) yield {Map ("number" -> i )})
:
.feed(feeder_ichiman.circular)
```

今回の例ではは`.circular`を使用しているので1から順にカウントアップしますが、
`.random`を使用すれば1〜10000の中でランダムに数値を与える事もできます。

## まとめ
Gatlingはインストールしてからテストを実施するまで非常に簡単に実行できる素晴らしいツールですので、
自分の実施したい負荷試験に合わせて、シナリオを定義できる様になっていきたいです。
（...そして、そんな方々の手助けになったら嬉しいです。）

## 参考
- Gatling公式サイト
  - https://gatling.io/
1つ以上の引数を受け取る可変長引数

python の 可変長引数, *variable length argument* は引数が省略され得る。

```python
def func1(*items):
    return items


assert func1() == tuple()
```

引数が省略されると困る場合は、引数が省略された場合に ```TypeError()``` を送出するなどの実装を検討する。

```python
def func2(*items):
    if len(items) > 0:
        return items
    else:
        raise TypeError("At least one argument required.")


func2()
-> TypeError
```

確かに```func2``` は安全になったが、*Runtime error* が送出されるまで引数が省略されたことが分からない。そこで、以下のように実装すると、1つ以上の引数を強制できる。（*Syntax error*）

```python
def func3(item, *items):
    return (item, ) + items
```

なお、```itertools.chain``` を使うと効率的にできる。

```python
from itertools import chain


def func4(item, *items):
    return tuple(chain((item, ), items))
```
いずれの実装でも1つ以上の引数をとる場合には同じ出力になる。もし、引数の省略を許さないなら、```func1``` よりも ```func3``` や ```func4``` がやさしい。
練習のためにSwiftをUdemyで勉強してみた(4日目)

#今日やったこと

 - ARKitを使ったアプリ制作のチュートリアル
 - 信頼されていないデベロッパと表示される現象の解決

#ARKitを使ったアプリ制作のチュートリアル

受講している講座が古いためか、プロジェクトを新規作成時に新たに「Reality Composer」という項目が増えていることに気がついた。
調べてみると、まだまだ旧来のもののほうが細かなところまで手が届くのだが、どうやら簡単にARの導入ができるらしい。
が、そうやって訳もわからないままテキストを外れていっていいことは一つもないので、とりあえずテキストどおりに進める。

https://note.com/northsand/n/nb245a2d4ab1f

どうやら、プロジェクトを作って、早速ARのビルドができるらしい、早速実機ビルドしてみたところ、ビルドはできたのだが、なぜか実機で起動しない。。。

#信頼されていないデベロッパと表示される現象の解決
どうやら許可されていないデベロッパなのが、いけないそうでiPhoneの「設定」から許可することができるらしい。
が、その設定項目が見つからず。

調べてみると、どうやら他の人も困っているらしい。

https://blog.integrityworks.co.jp/2020/01/23/ios-verify-the-developer-app-certificate-for-your-account-is-trusted-on-your-device/
https://teratail.com/questions/207230

よくわからないまま試行錯誤した結果、Xcode自体のTeamを一度ログアウトし再度ログインしなおし＆実機の再起動などを繰り返していたら解消した。
なんだったんだ。


#明日やること
 - ARアプリ制作を終わらせたい
 - 詳細Swift第5版を購入したので、少しでも読み進めていきたい

https://www.amazon.co.jp/dp/B081GK7636/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
3Dプリンタ(ADVENTURE3)の初めてのフィラメント交換でエクストルーダー分解が必要になったお話

購入した時に付属していたフィラメントが切れたので、マニュアル通りに新しいフィラメントに交換しようとしたら、いきなり分解が必要となったお話です。

## 環境

使用している３Dプリンタは[FLASHFORGE ADVENTURER3](https://flashforge.co.jp/adventurer3/)です。


## 初めてのフィラメント交換

プリントをしていると途中で止まってしまいました。
ADVENTURE3についているディスプレイをみると「フィラメントが切れたので交換してください」と表示されていました。

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

早速購入しておいたフィラメントを挿入して、[上図のマニュアル](https://flashforge.co.jp/wp/wp-content/themes/accesspress-parallax/software/Adventurer3UserGuide.pdf)を参考に「樹脂交換」を行います。

**ガガガガッ**

とても嫌な音がしました。
音はすぐ止んだので聞かなかったことにしましたが、新しいフィラメントがいくら待ってもノズルから出てきません。

一回フィラメントを取り外してもう一度「樹脂交換」を行いますが同じように異音がなります。
ググって見るとフィラメントが詰まって出てこないという現象は他にも起きた人がいるみたいです。
どうもこう言うケースで疑うべきは`ノズル`か`エクストルーダー`みたいです。

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

ノズル側(上図5番)かエクストルーダー側(上図23番)のどちらが怪しいかなと色々試してみると、エクストルーダーのフィラメントを巻き上げるためのローラーが回っているのに全くフィラメントが巻き上げられていかないところから、エクストルーダーが詰まっていると判断しました。

---
## 手探りで分解していきます

分解写真とかネットで探せば出てくるかなと思いましたが見つからなかったので、写真をたくさん載せておきます。


まず上図１９番のフィラメントカバーを外します。


![](https://i.imgur.com/aAcvIcp.jpg)

左上の黒いのがエクストルーダーです。銀色のホイール部分が回転することでフィラメントを巻き上げます。

今回はホイールが回ってもフィラメントが微動だにしないことから、エクストルーダーの先についている白いチューブの入り口付近で詰まっているのではないかと予想しました。

で、分解手順がわかる資料がないのでその辺を適当に外していった結果。

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


写真赤丸の６角穴付きボルトを外せば、白いチューブ付近を見れることがわかりました。

で、スプリングにも赤丸をつけている理由ですが、ボルトを外した後に本体から外せるのは下の写真のように３つの部品です。
このスプリングが**本体の中に落ちてしまうと**取り出すのに難儀します。私は落としてしまって、ADVENTURE3を上下逆さまにしたりしてやっと取り出すことができました。

![](https://i.imgur.com/sz5us9v.jpg)

ですので、スプリングはこんな感じでラジオペンチで挟みながら作業しましょう。

![](https://i.imgur.com/kPA86U0.jpg)


![](https://i.imgur.com/YHXDThq.jpg)

どうにか分解してみると前のフィラメントのお尻が見えました。
「樹脂交換」を何度もしたのにこれが見えるということは、お尻が引っかかってるわけですね。

![](https://i.imgur.com/39QmL3z.jpg)
引っ張り出してみるとお尻が変形してました。これのせいでフィラメントが先に進まず、新しいフィラメントを追加しようとしても前の樹脂が先に進まないからホイールが空回りして ガガガガッ と異音がなっていたわけですね。

フィラメントを引っこ抜いて、分解したパーツを付け直します。

---
## 付け直す時の注意点

![](https://i.imgur.com/VM7llA4.jpg)

取り外したパーツを付け直す時、スプリングと黒いパーツを先に本体にはめると、ボルトを挿入することができなくなります。
黒いパーツは本体と下部から1mmほど隙間を空けてボルトで固定するのですが、スプリングのせいで下側に黒いパーツが押しつけられるためボルトがまっすぐ入りません。
なので、写真のように付属のピンを本体と黒いパーツの間に挟んだ状態で、黒いパーツとスプリングを嵌めればボルトもまっすぐ挿入できるようになります。


## 無事終わりました

![](https://i.imgur.com/vnrO9fD.jpg)

![](https://i.imgur.com/ahgMVyu.jpg)

最初は焦りましたが無事プリントができるようになりました。
SAAに合格するためにセルフマネジメントをTrelloでしてみました

タイトルの通り、先日SAA-C02を受験し合格しました。
ですが、本記事の主題としてはSAAそのものではなく、どう学習を計画し、その進捗を測るかということです。
私の場合、学習って何かしらでモチベートしないと結局中途半端になりがちなので、何かいい方法はないかなと思っていました。
そう考えた時、[Trello](https://trello.com/ja)で必要なアクションを管理するのってピッタリなんじゃね？と思い、Trelloを活用してみたら結構ハマりました。

# まずはSAA取得に関する諸々情報

- 勉強に使った教材
  1. Udemy(レクチャーとして)
  <br>[これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）](https://www.udemy.com/course/aws-associate/)
  2. [Blackbelt](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)
  3. Udemy(問題集として)
  <br>[【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)
  4. 参考書
  <br>[一夜漬け AWS認定ソリューションアーキテクト アソシエイト 直前対策テキスト](https://www.amazon.co.jp/%E4%B8%80%E5%A4%9C%E6%BC%AC%E3%81%91-AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-%E7%9B%B4%E5%89%8D%E5%AF%BE%E7%AD%96%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E5%B1%B1%E5%86%85/dp/4798059463/ref=pd_lpo_14_t_2/357-3588749-9941429?_encoding=UTF8&pd_rd_i=4798059463&pd_rd_r=dcaf359e-8d8b-464f-89dd-28d2ef264f77&pd_rd_w=ttt6v&pd_rd_wg=Lgzzj&pf_rd_p=4b55d259-ebf0-4306-905a-7762d1b93740&pf_rd_r=F5848QAJ6QJBC8EMP8QG&psc=1&refRID=F5848QAJ6QJBC8EMP8QG)

以上。※もうSAAの話はでません笑

# Trelloの活用

## ステータスを定義しましょう

業務を推進する上でも同じことですが、タスクの進捗を計測するにはステータスの定義は重要です。
ここが曖昧だとボードに映るタスクの進捗は実態を映していません。要は甘い判断基準で今この辺〜っていうのと厳しい判断基準で今この辺！っていうのが混在してしまいます。
今回のボードには以下のステータスを用意しました。

1. ToDo・・・やらなければいけない項目
2. NiceToHave・・・優先度は低いが余裕があればやるとなお良い項目
3. InProgress・・・進行中の項目
4. Understand・・・アクションが完了した項目
5. Complete・・・問題演習で正答した項目

なぜ`Understand`と`Complete`があるのか？勉強って「このページ読んだ！」と「このページの内容理解した！」って違いますよね？
これを表現したかったのです。一旦読んだぜ！見終わったぜ！みたいなのは`Understand`、これの問題解けたぜ！は理解したってことで`Complete`にしました。

## 学びはカードのアクティビティログに連ねる

学習していると当然、これメモっときたいなあってことがあります。Udemyにはメモ機能あるし、ノートに手書きのメモも取れるし〜ってあっちこっちにナレッジが点在するのって基本よろしくないと思っています。そこで、何か気づきがあればとにかく、関連するカードのアクティビティログに書き連ねました。これで、「この時なんか気になることあったよな〜」って時にはとにかくTrelloを確認すればいい状態を作りました。

## カードの粒度

いくつかの教材を使っているので、当然「UdemyのS3」「参考書のS3」「BlackbeltのS3」ってな具合にS3に関するそれぞれのコンテンツがあります。この単位でカードを作って進捗を管理したいので、カードの粒度は教材×AWSサービスにしました。ただ、カードの名前を「XXXのXXX」ってするのは見た目的にごちゃごちゃするので、教材軸はラベル機能を使って分類しています。赤のラベルはUdemy、黒はBlackbelt、黄色は参考書って具合です。他にもハンズオンしてみる時は緑のラベルでそのアクティビティのカードを作ったりなどもしています。

## 実際のボードの様子

以下のような感じでTrelloを活用していました。個人的に大事にしていたのは何よりもカードの総数です。試験に合格するって絶対的にこれだけの学習をこなさなければならないっていうラインがあると思っているので、それをカードの数で測定していました。
その数のなかで、ToDoの割合やCompleteの割合をなんとなく見て、今こんくらいかなあ〜っていうのを管理していました。管理していたといっても個人でやってる世界の話なので、かなりざっくりふわっとですが。。。
※どうでもいいですが背景を山にしたのは、山を登り切って合格を掴もうぜ！っていう意味です笑
<img width="1403" alt="スクリーンショット 2020-07-12 23.22.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480978/5d003c07-2bc7-bf50-143c-8a95b3d978e1.png">



# 割とおすすめ

ツールを使って進捗を管理するのは試験勉強において結構オススメな気がしています。今回のSAA取得は学習期間大体1ヶ月ですが、決められた（あるいは決めた）タイムボックスの中で成果を出すのってやっぱり予実の管理が重要だと感じます。
この取り組みを通して、Doneの定義やカンバンボードの活用などのスクラム開発なんかに使えそうなエッセンスもある気がしていて、けっこううまみの多い活動のように思いました。
【Rails】rails g migrationコマンドのオプションで注意したいこと

#### ターミナルでrails g migrationコマンドを実行する際に、オプションとして**「カラム名:データ型」**を付け加える際には`必ず：(コロン)の直後にはスペースを入れないようにする！`

```:terminal

rails g migration add_user_id_to_posts user_id: integer
                                               ⬆️
                                              半角スペースを開けない！
```

上記のように「user_id:」の直後に半角のスペースを入れてしまうと、余計なカラムが作成されてしまうエラーが発生する為。
HTML5で音楽を流す方法

サイトやアプリで音楽が流れるようにしたいと思い、その方法を調べてできた方法を備忘録として残します。

HTML5には音楽を流すようにする`audio`タグというものがあります。

準備するのはhtmlファイルと今回はmp3の拡張子の音楽ファイルです。

```:ターミナル
$ mkdir hoge
$ cd hoge
$ touch index.html
```

と簡単に`hoge`ディレクトリと`index.html`を準備して、`hoge`ディレクトリの中に好きな`mp3`の音楽を入れましょう。

次に`index.html`の中身を以下のように書きます。

```html:index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utg-8">
  <title>hoge</title>
</head>
<body>
  <audio src="sample.mp3" controls></audio>
</body>
</html>
```

これでhtmlファイルを開き、以下のように表示されたら成功です。

<img width="698" alt="スクリーンショット 2020-07-12 23.35.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555962/a346d14b-f644-4e95-6bc4-9504cd617acb.png">

これでアプリで音楽を流すことができました。
単一カラム取得

## array_column()　

こちらの関数が便利そうなので使ってみる

[PHPマニュアル(array_column)](https://www.php.net/manual/ja/function.array-column)

多重配列用意

```php
emperor = [
      [
        'id' => 1,
        'name' => 'シャンクス',
        'nickname' => '赤髪',
        'wanted' => 4048900000
      ],
      [
        'id' => 2,
        'name' => 'エドワード・ニューゲート',
        'nickname' => '白髭',
        'wanted' => 5046000000
      ],
      [
        'id' => 3,
        'name' => 'カイドウ',
        'nickname' => '百獣',
        'wanted' => 4611100000
      ],
      [
        'id' => 4,
        'name' => 'シャーロット・リンリン',
        'nickname' => 'ビッグマム',
        'wanted' => 4388000000
      ],
```

-----------------------------------

array_collum()をつかってみると

```php
 $want = array_column($emperor, 'name', 'nickname');
  
 var_dump($want);
```

実行

```
Array
(
    [0] => シャンクス
    [1] => エドワード・ニューゲート
    [2] => カイドウ
    [3] => シャーロット・リンリン
)
```

。。。なるほど第2引数に指定されたkeyを入れれば
valueさんが取得できる

ちなみにechoで出力も可能だった。

## 引数は複数指定可能

```php
$want = array_column($emperor, 'name', 'nickname');
```

引数は複数指定できる

----------------
```
Array
(
    [赤髪] => シャンクス
    [白髭] => エドワード・ニューゲート
    [百獣] => カイドウ
    [ビッグマム] => シャーロット・リンリン
)
```

ただしechoで出力はできなかった。
そして引数3つ以上指定するとエラーが出た。
TECH CAMP学習　個人アプリ④git ignore

# ５Kって何だ！？

個人アプリを作成中に、Git Hubにプルリクエストをしてない事をユーザー管理作成中の時に気づいてしまいました。
かなりデータが溜まっていって、ワークスペースになんか『５K』と表示されてしまい全てをプルリクエストできません、と注意で書かれてありました。

Git Hubデスクトップにもchangesが**500**と表示されてしまい**500!!??**となりました。５Kの意味はこれの事なのかな？？

そしてやはり遅かったのか、どうすればプルリクエストできるのか、ファイルのどれかを消さないといけないのかと思い何となく一部のファイルを消去。

ただそれだけでは全くうまくいかず、少なくならず、ひたすらにググってググって、やっと見つけたのが**git ignore!!!**
VS code　内で.git ignoreファイルを作り、以下のコードを入れました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613470/4d5fb16b-ca2f-2bae-fd4e-e953767138ce.png)

これで一気にchangesが91まで縮小され、プルリクエストができるようになりました。
IMのドキュメント内にあるパラメータをまとめてみる その1

# IM開発備忘録
## IMのドキュメント内にあるパラメータをまとめてみる その1
## システムパラメータ

画面アイテム「関数」や前処理・後処理プログラム、アクション設定の条件式として、システムパラメータを利用することができます。

#### FormaのUI操作による開発では要件を実現できない！なんてこともある

Formaは高速かつバグが少ないという強みがある反面、
複雑な要件に標準で対応しきることができないこともある。

LDやカスタムスクリプトで複雑な処理を実現するにはFormaを構成している様々なデータが必要だったりする。
ということで覚えておくべきFormaを支えるシステムパラメータを紹介。

**システムパラメータは使いようによってはIM側が想定していない要件や処理も実現可能です。自己責任での使用をお勧めします。**

##### imfr_application_id
- アプリケーションID

そのまんま。アプリケーションIDを取得。
似たようなアプリがめちゃくちゃ増えたりするので、「アプリによって処理を分けたいｗ」みたいな無理目な要件も実現できる。
##### imfr_application_no
- アプリケーション履歴番号


##### imfr_application_type
- アプリケーションタイプ

アプリケーション種別・BIS作成種類を返却。
##### imfr_display_client_type
- 表示クライアントタイプ

PCかスマホで表示しているか教えてくれる。
とんでもなく便利。

##### imfr_form_id
- フォームID

一つのアプリから複数のフォームへ枝分かれする要件などで絶大な効力を発揮するパラメータ。
フォームを一意に特定できる。

##### imfr_form_id_tab
- タブのフォームID

フォームIDと同じ
##### imfr_insert_id
- データ登録ID

アプリ展開時に自動採番される。
登録内容を一意に特定するもので
Forma開発者なら必ずお世話になるパラメータ

##### imfr_next_page_exist
- 次ページ存在フラグ

まあまあ便利。フォームごとで処理を共通化するときにこいつを持たせておくだけで途端に柔軟なLDが組める
##### imfr_process_key
- プロセスキー

IM-FormaDesigner が画面作成毎に一意で作成している値を返却。

##### imfr_recycle_data_id
- リサイクルデータID

「WF申請書再利用」から申請した場合、再利用元の案件の「データ登録ID（insertID）」を返却。

##### imfr_recycle_id
- リサイクルID	
「WF申請書再利用」から申請した場合、再利用元の案件の「アプリケーションID」を返却。

##### imfr_response_type
- レスポンスタイプ（アプリケーションページ種別）

これは本当によく使う。
登録、更新、参照すべて同じアクションが動いたりする場面もあるので
こいつが制御してくれるのが本当に助かる

##### imfr_transition_id
- 遷移ID

フォーム遷移（imfr_m_transition）の遷移ID（transition_id）の値を返却。

##### imfr_version_no
- データバージョン

画面表示時の登録データのバージョンを返却。
更新時にDB登録値と異なる場合、排他制御によるエラーが発生。

#### 参考URL
https://www.intra-mart.jp/document/library/forma/public/forma_specification/texts/spec/system_parameter.html
Vuetifyでダークとライトテーマを切り替える機能を実装する


下記の画像のように、Vuetifyでダーク（dark）とライト（light）テーマを切り替える機能を実装する方法です。

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/f9466a37-0ef3-0520-dff6-8609355ee361.gif)


##ダークとライトテーマを切り替える機能

```vue 
<template>
  <div>
    <v-switch
      v-model="theme"
      :prepend-icon="themeIcon"
    ></v-switch>
  </div>
</template>

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

export default Vue.extend({
  data() {
    return {
      theme: true
    }
  },
  computed: {
    themeIcon(): string {
      return this.theme ? 'mdi-weather-night' : 'mdi-weather-sunny'
    }
  },
  watch: {
    theme() {
      this.$vuetify.theme.dark = this.theme
    }
  }
})
</script>
```

`v-model="theme"`として、watchで監視します。
`this.$vuetify.theme.dark = true or false`でダークとライトテーマを切り替えています。

見栄えの為に`computed`でアイコンの変更も実装しています。

## テーマごとのカラー設定

```js:nuxt.config.js
import colors from 'vuetify/es5/util/colors'

export default {
  /*
   ** vuetify module configuration
   ** https://github.com/nuxt-community/vuetify-module
   */
  vuetify: {
    customVariables: ['~/assets/variables.scss'],
    theme: {
      dark: true,
      themes: {
        dark: {
          primary: colors.blue.darken2,
          accent: colors.grey.darken3,
          secondary: colors.amber.darken3,
          info: colors.teal.lighten1,
          warning: colors.amber.base,
          error: colors.deepOrange.accent4,
          success: colors.green.accent3
        },
        light: {
          primary: colors.red.darken2,
          accent: colors.blue.darken3,
        }
      }
    }
  }
}

```

テーマごとのカラーの設定はnuxt.config.jsで行うことができます。

## 最後に

Vuetifyを使えば簡単にテーマの切り替えが実装できるので便利です。
VScodeの2種類のユーザースニペットの違い(ユーザースニペットとグローバルユーザースニペット)

## 結論
VScodeのユーザースニペットには

- ユーザースニペット
- グローバルユーザースニペット

の2種類があり、それぞれ挙動が異なる。

## 詳細

どちらのsnippetも「CのコメントスタイルをサポートするJSON」形式で書かれており、**ユーザースニペット**をそのまま**グローバルユーザースニペット**に転記しても使えます。

VScodeの[英語ページ](https://code.visualstudio.com/docs/editor/userdefinedsnippets)では
ユーザースニペット→ `language snippet`
グローバルユーザースニッペト→ `global snippet`
と表記が分けられていました。

### 1. ユーザースニペット(language snippet)

特定の言語のスニペットで、例えば`Javascript.json`や`LaTeX.json`がこれにあたります。
注意点として **VScodeの言語モード(右下のとこに出てるやつ)が一致している時にしか表示されません。**

![コメント 2020-07-12 224130.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327331/993125e3-b854-ca2a-2a27-9085ea941202.png)


例えば、LaTeXのユーザースニペットを出したい場合、ここが`LaTeX`になっている必要があります。

### 2. グローバルユーザースニペット(global snippet)
複数以上の言語に対応しているsnippetはすべてグローバルユーザースニペット(global snippet)だそうです(上記[英語のVScodeのページ](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_language-snippet-scope)より)。
これは拡張子が`.code-snippets`のファイルになります。
`scope`プロパティを追記しない限り、言語モードに関わらず全ての言語のファイルで使用可能です。

以下の例ではPythonファイルを編集中でも`Ctrl+Space`でLaTeXのsnippetが出てきています。

![globalsnippetex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327331/b1377f7c-92ab-8d14-9e0d-46e26c0bd155.png)




`scope`プロパティを`"scope": "javascript,html",`みたいに書くと任意の言語のファイルでのみsnippetが有効になるようです。

## ちなみに
Stack Overflowなんかを見ていると、自分で設定したsnippetを削除するにはsnippetが入っているフォルダーを開いてファイルごと消すのが一般的なようです。他にいい方法があれば教えてください。
IntelliJ IDEA (Windows10) で com.intellij.execution.process.ProcessNotCreatedException に出くわした場合のトラブルシュート

# TL;DR

設定の Docker Compose の実行パス末尾に .exe が付けよう

# Docker Compose で実行しているアプリケーションをリモートデバッグする

IntelliJ で読み込んでいるプロジェクトは、Dockerfile, docker-compose ファイル開いた状態から直接コンテナデプロイしてあれこれでき大変便利です。公式チュートリアルにも記述あり、さくっとお試しできます。

> Docker Composeを使用してSpring Bootアプリケーションを実行およびデバッグする
https://pleiades.io/help/idea/run-and-debug-a-spring-boot-application-using-docker-compose.html

が、以下のようなエラー(*1)に出くわすとそもそもコンテナの起動に失敗します。
![20200712-01_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146846/a66af3c9-deaa-b32f-a91d-04c1a332a737.png)

```Console:Error
Failed to deploy 'Compose: docker-compose-debug.yml': com.intellij.execution.process.ProcessNotCreatedException: Cannot run program "C:\Program Files\Docker\Docker\resources\bin\docker-compose" CreateProcess error=193, %1 は有効な Win32 アプリケーションではありません。
```

# トラブルシュート

"有効な Win32 アプリケーションではありません。" と言われているけどファイルは配備されてるしIntelliJ通さないと動くし、ということで設定を見直します。
File > Settings > Build, Execution, Deployment > Docker > Tools と設定を辿り、実行パスに '.exe' が付いているか確認します。拡張子指定がないとコケます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146846/d0a4bb9d-457a-c7f9-30a7-ba77a326cced.png)

'.exe' が付いていれば、晴れて Dockerビルド・デプロイされます。

![20200712-02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146846/44835c21-0fa3-2c94-a9da-8f74fd7c1dd7.png)

## 環境

```
IntelliJ IDEA 2020.1.3 (Community Edition)
Build #IC-201.8538.31, built on July 7, 2020
Runtime version: 11.0.7+10-b765.64 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Windows 10 10.0
GC: ParNew, ConcurrentMarkSweep
Memory: **
Cores: **
Non-Bundled Plugins: org.jetbrains.kotlin, Docker
```

## 参考リンク

ツール
https://pleiades.io/help/idea/settings-docker-tools.html?keymap=primary_windows
→Win10で言われるがままに環境作るとハマる気がする。

Docker Compose ProcessNotCreatedException Windows 10
https://intellij-support.jetbrains.com/hc/en-us/community/posts/360008456260-Docker-Compose-ProcessNotCreatedException-Windows-10
Cant start docker conteiners from docker-compose file
https://youtrack.jetbrains.com/issue/IDEA-243048
→英語ではknownなのか、、と思ってみたら、すでにIssueが上がっていた。次バージョンでは直りそう。
（気にしなくてよくなって、この記事消せますように）
Djangoで期限切れセッションを削除する方法

# Djangoで期限切れセッションは削除しちゃおう:blush:
Djangoでセッションはdefaultでデータベースに保存されます。
ほっておくと、期限切れセッションが増えてきてしまうので、
削除する方法を紹介したいと思います。
## 試した環境
Django 3.0.5
Python 3.8.2
## 仕様の確認
仕様を確認すると、推奨するやり方が書いてあります。
[Clearing the session store](https://docs.djangoproject.com/en/3.0/topics/http/sessions/#clearing-the-session-store)
>Django does not provide automatic purging of expired sessions. Therefore, it’s your job to purge expired sessions on a regular basis. Django provides a clean-up management command for this purpose: clearsessions.

自動一掃はしないから、定期的に一掃するのはあなたの仕事ですよ。
でもコマンドは用意してるよって感じですね。

どうやら、clearsessions というコマンドあるみたいですね。

## 削除方法
manage.py があるディレクトリに行き、下記コマンドを打つだけです。

```shell
$ python manage.py clearsessions
```

これで、**期限切れのセッションのみ**をデータベースから削除してくれるみたいです。

## 確認
### DBのテーブル確認
セッションは**django_session**テーブルで確認できます。
現在**2**件のデータが入ってます。

```SQL
sqlite> select session_key, expire_date from django_session;
3dub24wutcq28y7lhgnfl2rasoy37646|2020-07-11 19:20:40
g7s29wnv45boguo5np33yroq61t4v9c2|2020-07-25 13:50:10
```
expire_date は 2020-07-11 と 2020-07-25 です。
### コマンドによる削除
現在の日付を確認して、セッションを削除します。

```shell
$ date
2020年 7月 12日 日曜日 23:00:36
$ python manage.py clearsessions
```

テーブルを確認してみましょう。

```SQL
sqlite> select session_key, expire_date from django_session;
g7s29wnv45boguo5np33yroq61t4v9c2|2020-07-25 13:50:10
```
**1**件のみになりました。
2020-7-12 23:00:36 時点で 2020-07-11 のセッションはexpireしてるので、削除されました。

## ご参考までに
実際にコマンドのソースコードを確認してみましょう。
[clearsessionsのソース](https://github.com/django/django/blob/master/django/contrib/sessions/backends/db.py)


```python
class SessionStore(SessionBase):
...
    @classmethod
    def clear_expired(cls):
        cls.get_model_class().objects.filter(expire_date__lt=timezone.now()).delete()
```

`expire_date < timezone.now()`
で現在時刻より前のデータを対象にしているのが、分かると思います。

##参考にしたサイト
https://stackoverflow.com/questions/7296159/django-session-database-table-cleanup
Ruby on Rails簡易実装メモ

Qiitaで記事を書く際にRailsで簡易実装をしたいときがある。
その際にコマンドを忘れてしまうのでメモ。随時必要なったら追記していく。

```terminal
$ rails new [プロジェクト名] -d [データベース名]
$ cd [プロジェクト名]
$ rails db:create
$ rails generate scaffold [モデル名] [カラム名:型] [カラム名:型] [カラム名:型] ・・・
```

例えば、

```terminal
$ rails new scaffold_app -d postgresql
$ cd scaffold_app/
$ rails db:create
$ rails generate scaffold user name:string nickname:string
```



####slim化&binding.pryでデバックしたいとき

１、Gemfileに以下の記載

```text:Gemfile
gem 'html2slim'
gem 'slim-rails'
gem 'pry-rails'
```

２、`bundle install`して、viewファイルをslim化`--delete`オプションをつけるとerbのファイルは削除される。

```terminal:console
$ bundle install
$ bundle exec erb2slim app/views/ --delete
```


#### すでにdbが存在している場合

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

参考：https://kirohi.com/rails_duplicate_error
Webアプリケーションについて


### Webアプリケーションについて

・Webブラウザから利用できる
（Google ChromeやSafariなどインターネットを通じて、いろいろな情報が習得できる）
・データを登録できる
サービスをWebアプリケーションと言う。


###例
検索サイト
SNS
ブログ
ECサイト
掲示板
オークション
など
[flutter]はじめてのflutter5

#

#今日やること

-Flutterで画像表示をできるようになる

#画像表示(リンク）

```
Image.network(
'URL'
)

```
もしくは

```
Image.network(
'URL'
)
```

#画像表示（アセット）

imgなどのディレクトリに保存し、
pubspec.yamlに

```
flutter:
  assets:
   - img/py.jpg
```

main.dartに

```
Image.asset（
'パス'
)
```
【メモ】ROSで複数トピックからメッセージをSubscribe

# はじめに
ROSでは複数のトピックをSubscribeする場合が多いので、そのときのやり方をメモ

以下の記事がとても参考になりました。
[ROSで複数のトピックから同期的にメッセージを受け取る](https://qiita.com/nabion/items/319d4ffdc3d87bfb0076)

#方法
複数のメッセージをSubscribeするには、```message_filters```を使う。
例えば、ROSのtutorialsのlistenerを拡張すると、

```python
#/usr/bin/env python

import message_filters
import rospy
from std_msgs.msg import Int32

# Define callback
def callback(msg1, msg2):
   print(msg1.data)
   print(msg2.data)

# Initialize Subscriber node
rospy.init_node('listener')

# Define Subscriber
sub1 = message_filters.Subscriber('listener1', Int32)
sub2 = message_filters.Subscriber('listener2', Int32)

queue_size = 10
fps = 100.
delay = 1 / fps * 0.5

mf = message_filters.ApproximateTimeSynchronizer([sub1, sub2], queue_size, delay)
mf.registerCallback(callback)

rospy.spin()
```

``message_filters.ApproximateTimeSynchronizer()``で複数のsubscriberを同期している。

尚、python2の場合は、``fps=100.``のようにfloat型にしなければ``delay=0``と計算されてしまうので注意！
Gradleで任意のフォルダのプロジェクトを追加する

# はじめに

React NativeのAndroidプロジェクトで変則的なフォルダ構成だったのでGradleでうまく扱う方法を紹介します。
サブフォルダや同じ階層のフォルダの場合は[Gradleでマルチプロジェクト](https://qiita.com/shiena/items/371fe817c8fb6be2bb1e)で実現できます。

# フォルダ構成

```
myapp/
  android/ ★rootプロジェクト
    build.gradle
    settings.gradle ★これを編集する
    app/ ★アプリプロジェクト
      build.gradle
library/
  android/ ★ライブラリプロジェクト
    build.gradle
```

# 設定

```gradle:settings.gradle
include ':app'
// ここから追加
include ':library'
project(':library').projectDir = file('../../library/android')
// ここまで追加
```

# 参考サイト

- [Require Gradle project from another directory](https://stackoverflow.com/questions/19299316/require-gradle-project-from-another-directory/41161090#41161090)
- [Gradleでマルチプロジェクト](https://qiita.com/shiena/items/371fe817c8fb6be2bb1e)
javascript スクロール機能をつけるとき


#JavaScriptでスクロール機能をつけたいときのコードです
htmlタグの一番下に以下のコードを記入します。

~~~
<script>
$(function () {
      $('a[href^=#]').click(function () {
        var adjust = -50;
        var speed = 400;
        var href = $(this).attr("href");
        var target = $(href == "#" || href == "" ? 'html' : href);
        var position = target.offset().top + adjust;
        $('body,html').animate({scrollTop: position}, speed, 'swing');
        return false;
      });
    });
</script>
~~~

※adjustという変数は調整の意味です。
【ターミナル】ターミナル強制終了後、rails sしたらA server is already runningとなった時の対処法【Rails】

<h3>「controll+z」でサーバーを切ったら、rails sが効かなくなった。どうしよう・・という問題。


<h5>【バージョン】</h5>
Rails 5.2.4.3
Ruby 2.5.1
macOS Catalina 10.15.4
<br>

<h5>【経緯】</h5>
ローカルで作業中、rails sで立ち上げたlocalhost:3000を「controllキー + c」でサーバを切り、再度「rails s」で起動させようとしたらうんともすんともいわず・・・ほかの切り方がないか調べたところ「controllキー + z」で強制終了できることが判明。

しかし、「controllキー + z」で強制終了後、
再度、rails sで立ち上げたところ、localhost:3000が立ち上がらず、下記のエラーが出た。


```ruby:ターミナル
A server is already running. Check /Users/名前/XXX/XXXXXX/tmp/pids/server.pid.

```

「サーバーはすでに起動しています」と言われた。
<br>

<h5>【解決方法】</h5>
なので、

```ruby:ターミナル
% lsof -i:3000
```
でどんなプロセスが動いているのかを確認してみる。

**lsofコマンド** 
…「LiSt Open Files」（開いているファイル群を列挙する）という言葉に由来するようです。その名の通り、「プロセスが開いているファイル」を表示するコマンドらしいです。


<br><br>

```ruby:ターミナル
COMMAND  PID            USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    6792 satokokinoshita   11u  IPv4 0x95b341c28591923f      0t0  TCP localhost:hbci (LISTEN)
ruby    6792 satokokinoshita   22u  IPv6 0x95b341c27813ce6f      0t0  TCP localhost:hbci (LISTEN)

```
<br>
実際の画面はこんな感じだった
<img width="1001" alt="quiita.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603198/108f1b17-7b76-991c-06fc-62cfad19a1b9.png">



ここで、COMMANDがrubyとなっているPIDの番号 （ここだと6792、下の画面だと3405) を、○に入れる。


```ruby:ターミナル
% kill -9 〇〇〇〇
```

<br>
これで、rails sで再度起動できるようになりました。

<i>※ちなみにkillコマンドについてはkill -9（強制終了）以外は試しておりません。

localhost:3000のサーバーを切った時に消えるはずのプロセスが、強制終了したことで一部残ってしまっていたのだと思います。<br>
「PID(プロセスアイディー)」は、プロセスを識別するための一意の数字になりますが、
PIDを指定してkillコマンドで切ることで、サーバーを切った状態に戻ったということになったのだと思います。





<h6>【参考にさせていただいたサイト】</h6>

[このポートで実行中のプロセスはどれ？ lsofコマンドの使い方](https://www.atmarkit.co.jp/ait/articles/1510/05/news014.html#:~:text=lsof%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E4%B8%BB%E3%81%AA%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AF,%E9%80%9A%E3%82%8A%E3%81%A7%E3%81%99%EF%BC%88%E8%A1%A81%EF%BC%89%E3%80%82&text=%E3%80%8C%2Dc%E3%80%8D%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB%E7%B6%9A%E3%81%91,%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E7%89%B9%E5%AE%9A%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)</h6>

[プロセスを止める最終手段killコマンドの種類・シグナルの使い方](https://suwaru.tokyo/%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%82%92%E6%AD%A2%E3%82%81%E3%82%8B%E6%9C%80%E7%B5%82%E6%89%8B%E6%AE%B5kill%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E7%A8%AE%E9%A1%9E%E3%83%BB%E3%82%B7/)

<br>
<h6>【当該エラーに直面した時の感想的な】</h6>
Railsの画面に表示されるエラーは慣れたけど、ターミナルのエラーってあまりないので変な汗がでました😅
ターミナルコマンドはどんどん慣れていきたいです。