OmniAICreator/Qiita-1.07M huggingface dataset:
Firebase Crashlytics SDKのアップデートでテストクラッシュが上手くいかなかった時の解決方法

クラッシュレポートのためのFirebase Crashlytics SDK を アップグレードしないと2020/11/15から使えなくなるので[Firebaseのドキュメント](https://firebase.google.com/docs/crashlytics/upgrade-sdk?platform=ios&authuser=1#swift_4)を参考にアップグレードの作業を進めました。
[Firebaseのドキュメント](https://firebase.google.com/docs/crashlytics/upgrade-sdk?platform=ios&authuser=1#swift_4)通りに作業を進めればすんなりと終わるはずだが自分はそうもいかなかったので記事にさせていただきます。
後ほど説明しますが、自分はコードの修正を行いテスト用で強制クラッシュさせる際にかなりてこずりました。
ios環境をアップデートしたのでXcodeを使っていきます。
## そもそもFirebase Crashlyticsとは
アプリのクラッシュ時にレポートを管理してくれるFirebaseの機能
## アップデートの手順
- podfile追加＆pod install
- コード修正
- 実機でテスト用強制クラッシュ

### テスト用強制クラッシュの手順([参考サイト](https://firebase.google.com/docs/crashlytics/test-implementation?hl=ja))
1. Xcode にて Build and then run
2. Xcode にて Stop running
3. 実機でもう一回アプリの立ち上げ
4. 自分が前もって設定してたfatalErrorを仕込んである画面に遷移
5. fatalErrorでクラッシュレポート発信
6. Firebaseのコンソールで確認
7. 実装されたfatalErrorを削除する

### これをやれば大丈夫！強制クラッシュの実装方法
アプリを立ち上げた時には呼び出すことができないようなViewController内のviewload関数内にfatalErrorを入れる

- つまり実機でアプリを立ち上げて自分の手でスマホを操作してのち、fatalErrorを起こせればOK
- アプリを立ち上げて即fatalErrorになるとレポートが送られない
- [参考サイト](https://firebase.google.com/docs/crashlytics/test-implementation?hl=ja)では、プロジェクト内でタップするとfatalErrorが起きるボタンを実装している

## なぜ僕がテスト用強制クラッシュで手こずったのか

ずばりXcode にて Stop runningののち、実機でもう一回アプリの立ち上げをしないとクラッシュレポートが送れないということを知らなかったから
何回も修正したコードを見直しました笑

## 一連の作業が終わって大変だなって思ったこと
Pods関連はcocoapodsを使ったことがある方は一瞬で終わるでしょう。
自分が大変だなって思ったのはコード修正です。
[Firebaseのドキュメント](https://firebase.google.com/docs/crashlytics/upgrade-sdk?platform=ios&authuser=1#swift_4)をみてもらえればわかりますが、修正項目が14箇所あり間違えればテスト用の強制クラッシュさせる時にエラーが出るため抜け漏れなく修正する必要があります。
僕は各項目それぞれ修正点と懸念点を細かくメモしながら修正しました。修正点を見つけるときはXcodeのプロジェクト内検索機能を使うと楽です。
Cisco Modeling Labs v2.0 (CML2) のライセンスクリア方法

# はじめに
`VIRL2`とも呼ばれるシスコ機器シミュレータの`Cisco Modeling Labs v2.0`（`CML2`）を使っているのですが、うっかり`CML2`をインストールしていたホストの仮想マシンを削除したら、再度`CML2`を再セットアップしたときに**コンプライアンス違反**となり使えなくなったため、その時に実施したライセンスクリア方法を紹介します。

# CML2とは
簡単に紹介すると、`Cisco`が正式に販売している**CIsco機器シミュレータ**となり、**年額$199**（パーソナル版）かかります。
複数台にインストールして使うことはできないため、今回OS再インストールを行ったことで**コンプライアンス違反**となったんですね・・・

# コンプライアンス違反の確認
今回のようにライセンスを解除せずに再インストールしたような場合、CML2の管理画面の中にある`Smart Software Licensing`画面では以下の様に`OUt of Compliance`と表示されます。

![compliance.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/bcb83f22-8794-e31b-9b90-27a115bef031.jpeg)

ステータスが`Out of Compliance`の場合、マシンを起動したりできなくなるので、ライセンスをクリアするまで使えなくなります。

# ライセンスクリア方法
`ライセンスクリア`するためには、`CML2`の管理画面ではなく、[CiscoのWebサイト](https://www.cisco.com/c/ja_jp/index.html)から行う必要があります。

ご自身の`Ciscoアカウント`でログインし、`Cisco Learning Network Store`の`My Account`ページから行います。

![deregister.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/e4faa7a9-10ec-31b2-6568-028347c0ed7d.jpeg)

`2.x License`を選択すると上図のように`Registration Token`が表示されます。

右下の`De-register`を選択して画面説明に沿っていけばライセンスがクリアされるので、後は通常通りに`CML2`管理画面の`Smart Software Licensing`画面からライセンスを登録すればステータスが`Authorized`となり使えるようになります。

![Authorized.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/6b8441ac-2cc4-421a-905e-9e85e2d2443b.jpeg)

# 別マシンへのライセンス移行方法
今回のような強制クリアではなく、正式な？移行方法も紹介しておきます。

`CML2`の管理画面から`Tools`→`Licensing`の`Actions`から`Deregister`することで、現在登録されているライセンスが解除されるため、あとは移行後の`CML2`で通常通りライセンス登録を行えば今回のようなエラーが発生することなく移行できます。

![capture_22102020_080533.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/94823e4a-6bdf-1b50-54e3-cd50552208f2.jpeg)

# おわりに
`CML2`はあまり情報が出回っていないので、同じように困っている方の助けになれば幸いです。
アンケートの「良かった」「ふつう」「悪かった」の割合（パーセンテージ）をSQLで算出する

## やりたいこと
アンケートテーブル（surveys）に含まれる、「良かった」「ふつう」「悪かった」の割合（パーセンテージ）を出したい。
どんなSQLを書けば良いか？

### データの例

surveysテーブルの中身（全13件）

| id | user_id | answer   |
|----|---------|----------|
| 1  | 251     | 良かった |
| 2  | 113     | 良かった |
| 3  | 46      | ふつう   |
| 4  | 414     | 良かった |
| 5  | 456     | 良かった |
| 6  | 18      | ふつう   |
| 7  | 173     | ふつう   |
| 8  | 441     | 良かった |
| 9  | 419     | 悪かった |
| 10 | 157     | ふつう   |
| 11 | 116     | 良かった |
| 12 | 204     | 良かった |
| 13 | 445     | 悪かった |

算出したい値

- 良かった = （7件なので）53.8%
- ふつう = （4件なので）30.8%
- 悪かった = （2件なので）15.4%

### 対象RDBMS

- PostgreSQL 9.6

## 解答例

こんなSQLで算出できる。

```sql
SELECT
  TO_CHAR(
    100.0 * SUM(CASE WHEN answer = '良かった' THEN 1 ELSE 0 END) / COUNT(*),
    '999.9%'
  ) AS "良かった",
  TO_CHAR(
    100.0 * SUM(CASE WHEN answer = 'ふつう'   THEN 1 ELSE 0 END) / COUNT(*),
    '999.9%'
  ) AS "ふつう",
  TO_CHAR(
    100.0 * SUM(CASE WHEN answer = '悪かった' THEN 1 ELSE 0 END) / COUNT(*),
    '999.9%'
  ) AS "悪かった"
FROM surveys
```

出力結果

|   | 良かった | ふつう  | 悪かった |
|---|----------|---------|----------|
| 1 |   53.8%  |   30.8% |   15.4%  |

### 簡単な解説

- `SUM(CASE WHEN answer = '良かった' THEN 1 ELSE 0 END)` で「良かった」が何件あったのかをカウントする。（ここでは7）
- `COUNT(*)`でテーブルの全件数をカウントする（ここでは13）
- 上の2つの数値で割り算して100を掛ければ、パーセンテージが算出できる
- ただし、整数同士の割り算は整数値に丸められてしまうので、7÷13×100=0となってしまう。それを避けるため、100ではなく100.0を最初に掛ける。これにより小数点以下の値も算出される。（100.0×7÷13=53.8461538）
- 最後に`TO_CHAR`関数で数値をフォーマットする（`TO_CHAR(53.8461538, '999.9%')` → `53.8%`）
- 同じ手順で「ふつう」と「悪かった」のパーセンテージを算出する

### 実際に実行してみる

以下のサイトにアクセスして"Run it"ボタンをクリックすると、SQLの実行結果を確認できる。

https://rextester.com/XINWIX39774
![Screen Shot 2020-10-23 at 10.01.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/8ba10e1a-84c3-8991-7812-7d5f405e03db.png)

### おまけ：Railsでの実装例

Ruby on Railsで実装するならこんな感じ。

```ruby
# SELECT句のSQLを書く
sql = <<~SQL
100.0 * SUM(CASE WHEN answer = '良かった' THEN 1 ELSE 0 END) / COUNT(*) AS good,
100.0 * SUM(CASE WHEN answer = 'ふつう'   THEN 1 ELSE 0 END) / COUNT(*) AS fair,
100.0 * SUM(CASE WHEN answer = '悪かった' THEN 1 ELSE 0 END) / COUNT(*) AS bad
SQL

# SQLを実行して値を取得する
survey = Survey.select(sql)[0]
survey.good #=> 53.8461538
survey.fair #=> 30.7692308
survey.bad  #=> 15.3846154
```

補足説明

- 列の別名を日本語にするとプログラムとの相性が悪くなるので、ここではgood/fair/badとした
- 値のフォーマットはViewの責務なので、ここでは算出された値を純粋に返すだけにした
- `Survey.select(sql).first`とすると、ORDER BY句が自動的に追加されてSQLエラーが発生するので、あえて`[0]`とした

## 別解

本記事のコメント欄より。

### AVG関数を使う

```sql
SELECT
  TO_CHAR(
    AVG(CASE WHEN answer = '良かった' THEN 100 ELSE 0 END),
    '999.9%'
  ) AS "良かった",
  TO_CHAR(
    AVG(CASE WHEN answer = 'ふつう'   THEN 100 ELSE 0 END),
    '999.9%'
  ) AS "ふつう",
  TO_CHAR(
    AVG(CASE WHEN answer = '悪かった' THEN 100 ELSE 0 END),
    '999.9%'
  ) AS "悪かった"
FROM surveys;
```

（実行結果は上の本文と同じ）

### 列方向ではなく、行方向に平均値を出す

```sql
SELECT
  answer,
  TO_CHAR(
    100.0 * COUNT(*) / (SELECT COUNT(*) FROM surveys),
    '999.9%'
  ) AS "rate"
FROM surveys
GROUP BY answer
ORDER BY rate DESC;
```

実行結果

| answer   | rate  |
|----------|-------|
| 良かった | 53.8% |
| ふつう   | 30.8% |
| 悪かった | 15.4% |
【CRUD】【Django】PythonフレームワークDjangoを使ってCRUDサイトを作成する～3～

# シリーズ一覧(全記事完成したら更新していきます)

## ビューを作成する

Djangoでは汎用ビューが用意されています。
CreateView,UpdateView,DeleteView,ListView,DetailViewなどが存在します。

今回はListViewを用いて、一覧ページを作成します。

```python:/crud/blog/view.py
from django.views.generic import ListView
from .models import Post


class PostListView(ListView):
    # モデル指定
    model = Post
    # html指定 templates配下のパスを記載する
    template_name = 'blog/home.html'
    # Postクラス内のレコード群の名前
    context_object_name = 'posts'
    # 順序性　日付の降順（最新が上）
    ordering = ['-date_posted']
```

view.pyで指定したhtmlファイルを作成します。
posts(Postクラス内のレコード群)をforで1レコード取り出し、タイトル・内容・著者・投稿日を表示します。

```python:/crud/blog/templates/bolg/home.html
{% for post in posts %}
{{ post.title }}<br>
{{ post.content }}<br>
{{ post.author }}<br>
{{ post.date_posted }}<br>
{% endfor %}
```

## URLConfを作成する

URLConfとはDjangoの中でURLパターンをビューにマッピングする役割を担います。
「このURLが指定されたらこのビューを返す」と記述します。

urls.pyは2ファイルあるので注意してください。
1つ目は、/crud/config/urls.pyです。プロジェクト全体を設定範囲とします。includeを用いることで各アプリのurls.pyを読み込みます。
2つ目は、/crud/blog/urls.pyです。blogアプリを設定範囲とします。

blogアプリのurls.pyを読み込む設定を記述します。

```python:/crud/config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('', include('blog.urls')),
    path('admin/', admin.site.urls),
]
```

「[http://127.0.0.1:8000/](http://127.0.0.1:8000/)はPostListViewを返す」と記載します。

```python:/crud/blog/urls.py
from django.urls import path
from .views import PostListView

urlpatterns = [
    path('', PostListView.as_view(), name='blog-home'),
]
```

## ビューを表示する

準備ができましたのでビューを表示しましょう。

```python
python manage.py runserver
```
「[http://127.0.0.1:8000/](http://127.0.0.1:8000/)」にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763383/892def88-837e-844f-399b-7964afb377d8.png)

上のように表示されましたか？

本日はここまでにします。
Rails6のjs.erb内でJQueryを使う方法

ちょっとはまったのでメモ

# 概要

Rails6のビューの`remote:true`なフォームを受けとったコントローラで、js.erb を呼び出した時、JQuery `$('#hoge')`が動作しなかった。
※webpacker配下では正しく動作済み。

発生したJSエラー: `Uncaught ReferenceError: $ is not defined`


# 解決方法

app/javascript/packs/application.js内に以下の一行を追記する

```js:app/javascript/packs/application.js
...
require("bootstrap")
require("admin-lte")

window.$ = jQuery; // ここ!
```

```js:hogehoge.js.erb
$('.modal_area').html('<%= j(render "modal") %>');
$('#modal').modal('show');
```

config/webpack/environment.js で同じような定義をしてたけど、js.erb ファイル内から使うにはこの記述が必要だった。
「行削除」の使い方 - DBUpdateTool

Excelアドイン
DBUpdateTool(https://www.lasis.com/products/dbupdatetool)

選択した行について、プライマリーキーのセルの値をWHERE条件とし、DBのデータをDELETEします。【複数行選択可】

1. 以下のデータベースの状態から説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/ee427a90-86cd-d681-3cad-04e9c9204d4c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/e899ddf1-1c3d-42ca-9faa-89e06823abf6.png)

2. 削除したい行の任意のセルを選択し、Excelの「アドイン」タブにある「DBUpdateTool」の「行削除」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/68b533f0-1e36-59af-7972-3ab23294071e.png)

3. データベースのデータが変更されるため、確認のダイアログが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/37ad6f8a-d7c0-a81a-c3c5-756acf1779a0.png)

4. 無事、処理が完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/2bf940b4-7006-32f7-58e4-7f9736603d23.png)

5. 「行削除」を行った行の背景色が変更されました。データベースから行が削除されたことを示しています。ですが、Excel上にはデータが残っています。そのため、削除したデータをすぐにデータベースに更新することができます。これは、複数のデータを使用してシステムの動作をテストする際に、とても便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/0940e07d-7339-5402-ca75-c449a469f95c.png)

6. 「Microsoft SQL Management Studio」で、データが本当に削除されたかを確認してみます。ご覧の通り、削除されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/7bb15d08-1407-2fad-24b1-b6336651bba5.png)
「行差分」の使い方 - DBUpdateTool

Excelアドイン
DBUpdateTool(https://www.lasis.com/products/dbupdatetool)

選択した行について、セルとDBのデータを比較し、差分がある場合は、セルの背景色を変更して差分を表現します。【複数行選択可】

1. 以下のデータベースの状態から説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/4c6d85f7-611c-1d46-18fb-06988a082bc8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/dc9ca329-083f-1322-37d9-c20b5f0092dc.png)

2. 「Microsoft SQL Management Studio」にて、「DeletedDate」に、「2020-10-21」を入力してコミットします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/7949ab51-a481-17fa-ebcb-1f702a399c4a.png)

3. データベースの内容が変更されましたが、Excel上では前に最新化したデータが残っています。ここで、「行差分」を行ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/1bd85f41-61a5-541c-8afd-3d7e30979a9b.png)

4. 処理が完了し、メッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/c0c612ee-9ae4-8734-b5f3-d8285c852fc2.png)

5. 「G2」のセルの背景色が変化しました。データベースのデータとExcelのデータに差異がある場合、このようにセルの背景色が変化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/72df842b-d483-9f89-87f3-bc9c62bb8449.png)

6. よく見ると、「G2」のセルに、コメントが設定されています。「G2」のセルにマウスのカーソルを当てると、コメントの内容が表示されます。Excelのセル上は「(null)」と記載されていますが、実際のデータベースのデータは、「2020-10-21 00:00:00.000」であることを示しています。これがExcelとデータベースに「差分がある」という状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/d752fdc2-06d1-d8ce-647b-1157a463bbc1.png)
リンク先が正しく反映されない理由【解決事例あり】 

みなさん、こんにちは。

未経験からWebエンジニア転職を目指して独学中の体育教師しろと申します。

今回は、ネット上に公開された、サイトのリンク先が正しく反映されない理由について記事にしました。
実際に、リンク先が反映されなかった私の事例を元に説明していきます。

私のサイトは最初このような状態でした。


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">【問題2】<br><br>ページ遷移後、トップページに戻ったら<br>「そのページは存在しません」と表示される。 <a href="https://t.co/twM47CHpqN">pic.twitter.com/twM47CHpqN</a></p>&mdash; しろ＠体育教師のエンジニア転職 (@next_shiro) <a href="https://twitter.com/next_shiro/status/1319380220214865921?ref_src=twsrc%5Etfw">October 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

”トップページに戻る”ボタンを押してもページが見つからない状態。

コードはこちら。

![スクリーンショット 2020-10-23 6.23.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/812168/9c573be7-f498-dedd-92d4-61cbd0d6322a.png)

問題点は見つかりましたか？

問題点はこちら。

![スクリーンショット 2020-10-23 6.24.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/812168/740f6c7e-31bf-03cd-2ac0-553866b7fa51.png)



![スクリーンショット 2020-10-23 6.45.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/812168/11867f1a-5486-9b19-1b41-2f6b4cf8847a.png)
とリンクを設定していました。


答えをいうと、このコードを




![スクリーンショット 2020-10-23 6.45.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/812168/cec75a57-56ca-f4b1-1435-4c900db9609f.png)


にすると解決しました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">問題解決しました！<br><br>詳しい解決方法はQiitaで解説します！ <a href="https://t.co/236RtChewT">pic.twitter.com/236RtChewT</a></p>&mdash; しろ＠体育教師のエンジニア転職 (@next_shiro) <a href="https://twitter.com/next_shiro/status/1319392150883164161?ref_src=twsrc%5Etfw">October 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
今回は何が問題かというと、リンク先の住所が指定されていないから、コンピューターが見つけられなかったのです。

”index.html”だけだと　「江名子町にあります」だけだと「江名子町ってどこ！見つけられないよ！」となります。
これを”https://daikishirakawa.github.io/index.html”としてあげると　「群馬県/高山市/江名子町にあります」と指定しているので、「江名子町は群馬県の高山市にあるのね！」とコンピューターが見つけることができます。


つまり、

①”https://daikishirakawa.github.io”というサイトの中の、
②”index.html”というファイルとリンクさせてください

とコンピューターにファイルの住所を一緒に教えてあげることで、リンク先にコンピューターがたどり着くことができます。
「行更新」の使い方 - DBUpdateTool

Excelアドイン
DBUpdateTool(https://www.lasis.com/products/dbupdatetool)

選択した行について、プライマリーキーのセルの値を「WHERE」条件とし、セルのデータをDBに「INSERT」もしくは「UPDATE」します。 既存データが無い場合は「INSERT」、既存データがある場合は「UPDATE」を行います。【複数行選択可】

1. データベースのテーブルに新たな行を追加したい場合、そのテーブル名でExcelシートを作成し、ヘッダー作成を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/803b580e-5fcf-07a4-6597-3e7039b649da.png)
わかりやすいように、先ほどの画像を拡大表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/33a895d0-a487-9e4b-0b6a-7a390a627486.png)

2. DBUpdateToolで、ヘッダー作成後、追加したいデータをExcelシートに入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/b66bf72d-1625-da01-2812-ba0a79ad7a4a.png)

3. 追加したい行の任意のセルを選択し、Excelの「アドイン」タブにある「DBUpdateTool」の「行更新」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/4bbf7d4f-9e55-eb2d-d6e8-fd414ac30435.png)

4. データベースのデータが変更されるため、確認のダイアログが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/b6fbd885-27b7-71cb-4f58-478695b0b05b.png)

5. 無事、処理が完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/c67f709e-9411-5a4d-0b29-8c1b94afbd42.png)

6. データベースのデータが更新されました。この場合、同じ主キーのデータが存在しないため、SQLのINSERT処理が実行されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/5c0b2eb8-1c5e-288b-a4de-2e82ecbd9ded.png)

7. ご覧の通り、Microsoft SQL Server Management Studioで確認してみると、確かにデータが登録されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/455e62f4-781e-51ae-7665-46e2ff56399c.png)
ハンバーガーメニューのリンク先をクリックでメニューを閉じる方法

ハンバーガーメニューを実装した際に、リンク先をクリックしてもメニューが閉じずに　「×」でしかメニューが閉じず困りました。
調べてなんとか実装できたので備忘録として書いていきます。

##実装したときのコード

```index.html
          <nav>
            <h1 class="gn-header__logo">AAA社</h1>
            <ul class="gn-header__list">
              <li class="gn-header__item"><a href="#feature" class="gn-header__item-link"></a>A</li>
              <li class="gn-header__item"><a href="#price" class="gn-header__item-link">B</a></li>
              <li class="gn-header__item"><a href="#work" class="gn-header__item-link">C</a></li>
              <li class="gn-header__item"><a href="#flow" class="gn-header__item-link">D</a></li>
              <li class="gn-header__item"><a href="#contact" class="gn-header__item-link">E</a></li>
            </ul>
          </nav>
```

```index.html
        <!-- burger-menu -->
        <div class="burger-btn" id="js-burger-btn">
          <span class="bar bar_top"></span>
          <span class="bar bar_mid"></span>
          <span class="bar bar_bottom"></span>
        </div><!-- burger-menu -->
```



```script.js
jQuery(function($){$('.gn-header__item a').on('click', function(){
	if (window.innerWidth <= 768) {
		$('#js-burger-btn').click();
	}
});});
```

JSでなにが行われているのかをみていきます。
`gn-header__item a`をクリックしたとき、もしも`innerWidth`が768px以下であれば,
`js-burder-btn`をクリックしてイベント処理を実行させています。

###まとめ
こちらのコードで１００点なのかどうかはわかりませんが、とりあえず実機でも問題なく動作していますので良いかなって思います。
もう少しjQueryやJSを学習してプログラミング力をつけねば。
「ヘッダー作成」の使い方 - DBUpdateTool

Excelアドイン
DBUpdateTool(https://www.lasis.com/products/dbupdatetool)

「シート」名もしくは「A1」セルに記入してあるテーブル名を元にヘッダーを作成します。

1. この操作を完了するには、あらかじめデータベース接続設定とデータベースに指定のテーブルが存在する必要があります。以下、SQL Serverを例に、手順を記述します。まず、SQL Serverを操作するために、SQL Management Studioを立ち上げます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/fdf945c4-bbdf-1925-3cb2-879f253e2f3d.png)

2. メニューの「ファイル」から、「オブジェクト エクスプローラーを接続」をクリックし、SQL Serverに接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/d540f4c7-242d-8e4c-c311-478a98fe20b4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/8a7eb666-46d1-6dae-2e14-a3ce0429704c.png)

3. 「オブジェクト エクスプローラー」のツリーを「データベース」 > 「システムデータベース」 > 「master」スキーマ > 「テーブル」の順に開き、「Account」の名前で、新しいテーブルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/947df69a-d626-2432-662d-2f177da941a3.png)

4. 続けて、「AccountEMail」の名前で、新しいテーブルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/a2950c04-19b2-b853-fd52-6b2b3d1059cd.png)

5. 以下の通り、「Account」、「AccountEMail」のそれぞれのテーブルのデータを表示すると、データが空であることが確認できます。
Account
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/4835aad7-42c4-73bd-854e-9a309d2f505c.png)
AccountEMail
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/b52f671f-7762-66f1-0758-ad88d3a7e496.png)

6. DBUpdateTool用に作成したExcelファイルを開き、「@Config」シートに、データベース接続情報を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/cd955eb0-4d76-0fa3-12b8-23c6fab4c2d9.png)

7. 続いて、新しいシートを作成し、シート名を「Account」に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/1ac10a7b-b92d-e505-abe5-4a268dbb1eb1.png)

8. Excelのリボンメニューにある、「アドイン」タブを選択します。その中にある「DBUpdateTool2020」メニューの「ヘッダー操作」 > 「ヘッダー作成」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/04208c6d-dd7d-a279-f73e-42aec1c75cbe.png)
わかりやすいように、先ほどの画像を拡大表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/047379c5-7a0d-dbf4-c354-86a996218284.png)

9. ご覧の通り、「Account」テーブルのヘッダーが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/8d324ccf-6ad5-72f9-ed40-f931b62f6621.png)

10. 同様に、「AccountEMail」シートを作成し、「ヘッダー作成」を行うと、「AccouneEMail」テーブルのヘッダーが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/ade9c3e8-e763-e1cd-4de4-386bbbfb901c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/f4505bd2-baa3-0b76-96e1-b7b20812bd01.png)
「新規作成」の使い方 - DBUpdateTool

Excelアドイン
DBUpdateTool(https://www.lasis.com/products/dbupdatetool)

DBUpdateToolの操作用に、Excelファイルを新規作成します。

1. Excelのリボンメニューにある、「アドイン」タブを選択します。その中にある「DBUpdateTool2020」メニューの「新規作成」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/124a6486-b6e7-f2b4-f3de-909907c03558.png)
わかりやすいように、先ほどの画像を拡大表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/45438c14-7d6e-f45f-47f3-7accb462c204.png)

2. ファイル選択ダイアログが表示されますので、任意の場所を指定して、Excelファイルを保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/fb26492a-d978-58ba-7a44-6fe8b2459900.png)

3. 以下の画面が表示されるまで、しばらく待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/c2a31f5a-0c0a-344a-2328-678d93d67a1e.png)

4. Excelファイルの作成と同時に、自動的に４つのシートが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/48345383-0edb-e6fb-368a-0b70cb1df769.png)

5. 作成された「Introduction」シートをご覧ください。こちらのシートには、ツールを使うために必要な手順が書かれています。慣れてくればこちらを見なくても、スムーズに開始できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/2c395b31-bfed-83e5-2c7f-8510fe325ca0.png)

6. 作成された「Config」シートをご覧ください。こちらのシートには、データベース接続に必要な情報を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/55cfebd3-57d1-d0e7-e4fe-eacf71dda294.png)

7. 作成された「Option」シートをご覧ください。こちらのシートには、ツールをさらに便利に使うためのオプション設定を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/3ca2ebec-246f-b345-3c7c-55237106db0a.png)

8. 作成された「Description」シートをご覧ください。こちらのシートには、ツールの各ボタンの機能説明が書かれています。様々な便利に使える機能が搭載されていますので、システム開発作業の効率化にご活用ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/ea9153a5-fb21-453a-935b-d8b4b91387aa.png)
インストールの方法 - DBUpdateTool

Excelアドイン
DBUpdateTool(https://www.lasis.com/products/dbupdatetool)

DBUpdateToolのインストールの方法をご紹介します。
インストーラーに従いクリックするだけで、簡単にインストールが完了できます。
ExcelマクロではなくExcelアドインなので、PCにインストールすれば、Excelファイル内にプログラムを含める必要がありません。

1. ダウンロードしたzipファイルを解凍し、その中の「setup.exe」を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/ba2c3345-4cc4-ce70-b168-f99479ca6846.png)

2. 「インストール」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/68f6293e-5c6b-72d9-7c37-c25bd06f0573.png)

3. インストールが終わるまで、しばらく待機します。比較的、すぐに終わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/3abd2dad-e7bb-c1f1-cc8a-8638783dd313.png)

4. インストールが終わりました。「閉じる」ボタンを押して、インストールを完了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/a3e7b43d-cebe-89b2-03b4-07b0e2287eee.png)

5. インストールされたアプリを確認すると、「Lasis DBUpdateTool 2020」が表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/a7db756e-862e-155e-42d6-96316059e6eb.png)
Xcodeプロジェクトのコンフィグレーションの追加削除

時々、Xcode のプロジェクトで build configuration を追加や削除したくなる時があります。これまでも、何度かやってきたのですが、今回またやり方がわからなくてググってしまったので、ここにメモする事とします。

この画面はアーカイブする時のコンフィグレーションを選びます。事情があってここにコンフィグレーションのコピーを追加したいとします。が、この画面からコンフィギュレーションを追加削除はできません。

![Screen Shot 2020-10-22 at 3.54.51 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65634/46a526fc-a321-d050-c1ff-e99949dc6fcd.png)

メニューからはできそうな雰囲気があるのですが、どの条件でここか選べるようになるのかわかりませんでした。

![Screen Shot 2020-10-22 at 4.08.28 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65634/392d74a9-b7d6-cd2f-da64-7a3634a6ceb1.png)

結局ググってしまいました。結局プロジェクトを選び、`Info`を選びさらに`PROJECT`から自分のプロジェクトを選ぶと、`Configuration`に現在のコンフィグレーションの一覧が現れます。「+」または「-」でコンフィギュレーションの追加削除を行います。

![Screen Shot 2020-10-22 at 4.00.02 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65634/16d899b1-0687-0973-1aca-acafb580ae45.png)

また、半年後とかにわからなくなる可能性がありますので、ここにメモを残したので、UIに変更がない限り安心です。

```
Xcode Version 12.1 (12A7403)
```
NginxでAWS ELBのHealth Checkログを出力させない方法

NginxでAWS ELBのHealth Checkをアクセスログとして出力させない方法を紹介します

# 環境

![Nginx](https://img.shields.io/badge/nginx-1.19-green.svg) ![LB](https://img.shields.io/badge/LB-AWS%20ELB-orange.svg)

# 方法

## コンフィグ

```nginx
map $http_user_agent $loggable {
    ~ELB-HealthChecker  0;
    default             1;
}

access_log  /var/log/nginx/access.log main if=$loggable;
```

## 解説

mapとaccess_logに分けて少し解説していきます

### map

`map $first $second {...}`とすると、`$first`を`{...}`に沿って評価して返り値を`$second`にマッピングします
今回の場合は`$http_user_agent`、つまりHTTPヘッダーに含まれるUser Agentが`ELB-HealthChecker`に部分一致するか評価して一致するなら0、一致しなければ1を`$loggable`にマッピングします

ELB-HealthCheckerの前についている`~`は正規表現を使うための記号です
`~`はcase-sensitiveで、`~*`はcase-insensitiveです

[備考]
2020/10時点では正式なUser Agentは`ELB-HealthChecker/2.0`でした
/以降はバージョンなので今後変更の可能性があるので、ELB-HealthCheckerが含まれているかだけチェックしましょう

### access_log

access_logには`if`というパラメータがあります
条件が0か空文字と評価されたらログ出力しなくなります
今回は$loggableのデフォルトが1で、ELB-HealthCheckerがUser Agentに含まれていたら0になるので、Health Checkのアクセスログが出力されなくなります。

# Reference

- http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
- http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log
C#_コレクション


どの言語でもあるように、C#でも複数のデータを扱う為の方法が存在します。これを **"コレクション"** と呼びます。
今回はコレクションについて述べていきます。

## コレクション

コレクションにはいくつか種類があります。
どれも複数のデータを扱えるという点で同じではありますが、細かく使い方が違います。

|コレクション|特徴|
|:---:|:---:|
|配列(Array)|固定長。インデックスで要素にアクセスできる|
|リスト(List)|可変長。インデックスで要素にアクセスできる|
|ディクショナリ(Dictionary)|可変長。キーと値を紐づけてアクセスできる|
|スタック(Stack)|可変長。先入れ後出し(FILO)式|
|キュー(Queue)|可変長。先入れ先出し(FIFO)式|

これらについて一つずつ見ていきましょう

## 配列(Array)

最も基本的なコレクションです。
簡単に扱うことができますが、固定長なので必要なデータの要素数が最初から分かっている場合に使うことができます。

```C#:Program.cs
int[] arr = new int[3];
arr[0] = 3;
arr[1] = 5;
arr[2] = 7;
```

C#ではコレクションのインデックス（要素番号）は0から始まるので、要素数3の配列を作成した場合、アクセスできるインデックスは0~2の3つになります。
また、要素外のインデックスにアクセスした場合、実行時エラーが発生します。

配列は次のように最初から要素を指定して初期化することも可能です。

```C#:Program.cs
int[] arr = new int[] { 3, 5, 7 };
```

## リスト(List)

配列とは違い、リストは要素数が可変なのでAddメソッドを使うことで要素を追加していくことが可能です。

```C#:Program.cs
List<int> list = new List<int>();
list.Add(3);
list.Add(5);
```

ただし、リストにおいても要素外のインデックスへのアクセスは実行時エラーになります。
※言語によっては初期値で自動追加される場合もありますが、C#のリストはプログラマの想定外の挙動を抑制するためエラーとされています。

また、それを回避するためにある要素がリストに含まれているかどうかを判定するContainsメソッドも持っています。

```C#:Program.cs
List<int> list = new List<int>();
list.Add(3);
Console.WriteLine(list.Contains(3));
Console.WriteLine(list[0]);
Console.WriteLine(list.Contains(5));
```

```TXT:出力
> True
> 3
> False
```

## ディクショナリ(Dictionary)

キーと値を紐づけた情報を複数持つことができます。他の言語ではハッシュマップなどとも呼ばれます。


ディクショナリは配列やリストの様な"何番目"という考え方ではなく追加された"キー"を基準に値にアクセスしていきます。
キーと値のペアはリストと同じくAddメソッドによる追加、ContainsKeyメソッドによるキーの確認ができます。

```C#:Program.cs
// Dictionary<キー型, 値型>
Dictionary<int, string> dic = new Dictionary<int, string>();
dic.Add(2, "Tokyo");
dic.Add(5, "Osaka");

Console.WriteLine(dic[5]);
Console.WriteLine(dic.ContainsKey(2));
Console.WriteLine(dic.ContainsKey(3));
```

```TXT:出力
> Osaka
> True
> False
```

追加されていない要素へアクセスしたり、既に追加されている要素と同じキーを再度追加しようとするとエラーが発生します。
追加されているかどうかの管理を厳密に行うことにより、キーの一意性を保つことができます。

## スタック(Stack)とキュー(Queue)

スタックとキューに関しては対比しながら同時に紹介します。

```C#:Program.cs
Stack<int> stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
stack.Push(3);
Console.WriteLine(stack.Pop());
Console.WriteLine(stack.Pop());
Console.WriteLine(stack.Pop());
```

```TXT:出力
> 3
> 2
> 1
```

```C#:Program.cs
Queue<int> queue = new Queue<int>();
queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
Console.WriteLine(queue.Dequeue());
Console.WriteLine(queue.Dequeue());
Console.WriteLine(queue.Dequeue());
```

```TXT:出力
> 1
> 2
> 3
```

上記の通り、スタックやキューは今までのコレクションとは違い、アクセスするときに番号やキーを指定しません。
Push/Enqueueメソッドで要素を追加し、Pop/Dequeueメソッドによって要素を取り出します。

注意しなければならないのはPop/Dequeueメソッドによって取り出した要素はスタックやキュー本体からも消えているということです。

また、スタックとキューで何が最も違うかと言えばその取り出す順番にあります。
スタックは一般にFILO(First In Last Out)方式であり、「最初に入れた要素が最後に出てくる」ことになります。
Popメソッドによって取り出されるのは、要素の中で一番最後にPushされたものです。

反対にキューは一般にFIFO(First In First Out)方式であり、「最初に入れた要素が最初に出てくる」ことになります。
Dequeueメソッドによって取り出されるのは、要素の中で一番最初にEnqueueされたものです。

IEnumerableという概念を知ってからだとコレクションについてのさらに詳しい内容を知ることができますが、このページではここまで。
Windows 10/WSL2 で X Server ソフト X410 を使ってみる

WSL2 で X Window を使うために [X410](https://www.microsoft.com/ja-jp/p/x410/9nlp712zmn9q?activetab=pivot:overviewtab) を導入してみました。導入は簡単 Microsoft Store で購入するだけですw

定価は5,850円なのですが私が購入時は80％引きの1,150円でした。もっとも88%引きで売っていたこともあるらしく値上がりしたっちゃ値上がりしてるのですが。。

なぜ X410 を導入しようと思ったかというとずばり xsel が VcXsrv だと上手く動かなかったから。どうも一定のサイズ以上のデータを渡すとクリップボードが動かなくなるようです。例えば以下の例だと tail -10 を付けてあげれば動くけど 3M 丸ごと渡してしまうと動かない。一旦大きいデータを渡してしまうと Windows 側でもコピペができなくなってしまいました。

```
$ ls -lh ./hoge
-rw-r--r-- 1 karube karube 3.0M Oct 22 12:24 ./hoge
$ tail -10 ./hoge | xsel -bi  # <--- 動く
$ cat ./hoge | xsel -bi  # <--- 動かない
$ tail -10 ./hoge | xsel -bi  # <--- 動かない
```

VCXSrv のログには以下のようなメッセージが出ていました。

```
winClipboardFlushXEvents - OpenClipboard () failed: 00000005
```

この問題は X410 の無料試用版を試したら無事に解決。その勢いで購入してしまいました。しばらくハマってた問題なので1,150円なら安い。これで心置きなく WSL2 が使えそうです。(Xming という選択肢ももしかしてあるかもですが。)

と言うことで VcXsrv などになにか問題のある場合は X410 も良い選択肢となるかもしれません。
監視サーバZabbixでLinux(CentOS7)の死活監視(Ping)をやってみた

#はじめに
Zabbix4.4で死活監視の設定・動作確認をする手順について説明する。
ここではZabbixでの細かい設定については省略している。

#環境
- ホストOS：Windows10
- ゲストOS：CentOS7 × 2台
 - 監視用サーバ　：ホスト名 zabbix（IPアドレス:192.168.33.10）
 - 監視対象サーバ：ホスト名 webserver（IPアドレス:192.168.33.20）
- 仮想マシン構築方法：VirtualBox, Vagrant

#手順（概要）

1. Zabbixで監視対象のホストを追加する
2. Zabbixで監視対象のホストにテンプレートを適用する
3. Zabbixで障害発生時の通知先メールアドレスを設定する
4. 動作確認（Zabbix管理画面、メール通知）

#手順（詳細）

##1. Zabbixで監視対象のホストを追加する

Zabbixのホストとは監視する対象を示す。
Zabbixでは、ホストは少なくとも1つのホストグループに属す必要があるためグループを作成しホストを所属させる。

Zabbixの[設定]→[ホスト]から、監視対象サーバ webserver(192.168.33.20) を追加する。

##2. Zabbixで監視対象のホストにテンプレートを適用する

「テンプレート」とは、監視に必要な条件やルールなどをまとめて定義したものである。
Zabbixには標準でいくつものテンプレートが用意されている。もちろん個々にカスタマイズしたテンプレートを作成することも可能。

今回は、標準で用意されている死活監視に最適なテンプレート「Template Module ICMP Ping」をwebserverに適用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799092/0cfa9444-ec3a-9d14-5eef-241b4d879f2b.png)

##3. Zabbixで障害発生時の通知先メールアドレスを設定する

[管理]→[メディアタイプ]から通知したいメールアドレスを設定する。
今回はGmailを設定した。
※Gmailを設定する場合は、Gmail側で「信頼性の低いアプリ」からのアクセスを有効にしないとメール通知がされない。セキュリティ上、動作確認が済んだら元に戻すことを推奨する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799092/835dfd63-55ac-e98a-3ad3-d8177a89e339.png)

[設定]→[アクション]で、メール通知する場合の実行条件を設定する。
今回は、「トリガーの深刻度」が「重度の障害」以上の場合にメール通知がされるように設定した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799092/d5acedcd-69ed-bc3e-da64-1e6a398a060e.png)

##4. 動作確認（Zabbix管理画面、メール通知）

Zabbix側の設定が完了したら、わざとwebserverをシャットダウンして障害発生の状況を作る。
つまり、監視サーバzabbixから監視対象サーバwebserverへの疎通ができない（ping応答がない）状態である。

###Zabbixで障害が発生していることを確認

[監視データ]→[障害]を確認してみる。
ステータスが「障害」になっており、メール通知のアクションが正常に動作していることが確認できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799092/966d3a5d-6f78-2a85-7eef-c80144235fc4.png)


###Gmailに障害発生メールが通知されることを確認

Gmailを確認してみると、ちゃんと障害発生メールが届いていることを確認できた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799092/20c832fe-9cb4-544d-06c8-312c37f8928c.png)
#まとめ
以下のことを自分でやってみると、ITインフラの構築・運用のイメージがつかめて勉強になる。
仮想マシンの構築　→　監視サーバの構築・監視設定　→　障害発生の動作確認

以上
Qiita 記事の書き方

#はじめに
今回自分がQiitaを始めるにあたって、記事の書き方がよく分からなかったので、練習がてらここに記事の書き方について書いてみることにしました。ちなみに、この記法はMarkdown方式という書き方のようです。



#見出しの付け方
ここのすぐ上にある「見出しの付け方」という見出しは、


```
#見出しの付け方
```

という風に書いています。
なお、#は半角にする必要があります。

また、#を増やすごとに見出しの大きさを小さくできます。
##これは#が2つ
###これは#が3つ
####これは#が4つ

このような具合です。



#箇条書き
###・の箇条書き

* 箇条書きテストの1
* 箇条書きテストの2
* 箇条書きテストの3

この箇条書きは、行頭に「*」を付け、半角空白の後、文字列を記述しています。

```
* 箇条書きのテストの1
* 箇条書きのテストの2
* 箇条書きのテストの3
```

こんな感じです。
なお、箇条書きの後には改行を入れないと、箇条書きの終わりとして判断されないようです。

###数字を用いた箇条書き

1. 数字バージョンの1
2. 数字バージョンの2
3. 数字バージョンの3

この箇条書きは、先程の「*」の代わりに、半角数字と「.」を使っています。

```
1. 数字バージョンの1
2. 数字バージョンの2
3. 数字バージョンの3
```

こんな感じで記述しています。



#コードの記載方法
###一番簡単な書き方

```
#include <iostream>
using namespace std;

int main()
{
  cout<<"Hello Qiita!"<<endl;
  return 0;
}
```

これは、ソースコードの前後を「```」（バッククオート3つ）で区切って書いています。
シングルクォーテーション「'''」ではないので注意が必要です。
![20201023014531.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815574/47abb287-0c28-8e31-9f82-3b165bc8a430.jpeg)
こんな感じです。
バッククオートの外側は改行をそれぞれ入れておいた方が良さそうです。
改行しなかった場合、#includeのところが見出しとして判断されてしまっていました。
また、勿論自動インデント等は無いので、直接記述する際は自分でインデント等を行う必要があります。

###コードに見やすく色付けする記述方法

```cpp
#include <iostream>
using namespace std;

int main()
{
  cout<<"Hello Qiita!"<<endl;
  return 0;
}
```

これは、先程と同じようにコードを記述し、先頭の「```」の後に「cpp」と記述しています。
![20201023015504.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815574/8db7b840-e129-3f6d-73ba-da09379812b9.jpeg)
こんな感じです。
ここではC++のコードを用いたためcppと書きましたが、pythonやjavaなど別の言語もそれぞれ対応しているようです。

###更にコードにファイル名を付ける

```cpp:hello.cpp
#include <iostream>
using namespace std;

int main()
{
  cout<<"Hello Qiita!"<<endl;
  return 0;
}
```

これは、先程先頭のバッククオートの後に書いたcppという文字の後に、「:hello.cpp」というようにコロンとファイル名を付け加えるだけです。
![20201023020008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815574/4522d374-b03a-8651-f559-65063b9dcd42.jpeg)



#リンクの作り方
[私のページ](https://qiita.com/wdwd5454)
↑のようにリンクができます。
書き方は、

```
[私のページ](https://qiita.com/wdwd5454)
```

こんな感じです。
[ ]の中に、リンクとして表示したい文字列を書き、( )の中にURLを記述します。



#おわりに
とりあえず自分が使えたらいいなと思った機能はこれくらいだったので、これくらいにしておこうと思います。
今後新たに必要だと思ったことがあれば追記しようと思います（できるのか知りませんが流石にできるはずです）。



##参考
[Qiita Markdown 書き方 まとめ](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)
【Nuxt.js】子コンポーネントにhtmlコードを渡すslotの使い方・自分用

##slot・・・親コンポーネントから子コンポーネントにhtmlのソースコードをそっくりそのまま渡す。



##基本的ルール
・親コンポーネントにおいてslotで表示したい部分は、子コンポーネントの名前のタグで囲ってあげる。
・子コンポーネントにだけslotタグをかく。


##コード例
###子コンポーネントでslotが1つだけの場合
```親コンポーネント.vue

<template>
<div>
<子コンポーネントの名前>
<h1>タイトル</h1>
</子コンポーネントの名前>
</div>
</template>

```


```子コンポーネント.vue
<template>
<div>
<slot></slot>  //もしくは<slot /> のみでも良い
</div>
</template>

<script>
export default {
}
</script>
```

###子コンポーネントでslotが複数ある場合

```親コンポーネント.vue

<template>
<div>
<子コンポーネントの名前>
<h1>タイトル</h1>
<h2>見出し2</h2>
</子コンポーネントの名前>
</div>
</template>

```


```子コンポーネント.vue
<template>
<div>
  <slot/>     //タイトル
</div>
<div>
  <slot/>     //見出し2
</div>
</template>

<script>
export default {
}
</script>
```

###子コンポーネントでslotに名前をつける場合
・名前をつける場合は親コンポーネントにおいて```<template>```タグで囲う必要があることに注意。

```親コンポーネント.vue
<Title>  //子コンポーネントで囲うクラス名として指定する必要がある。
  <template v-slot:h1-title>
　  タイトルです // slot name="h1-title"を置き換える
  </template>
  <template v-slot:h2-title>
　  見出し2です // slot name="h2-title"を置き換える
  </template>
</Title>
```


```子コンポーネント.vue
<div class="Title"> //クラス名を親コンポーネントで囲っているタグの名前にする、今回だとtitle
  <h1>
    <slot name="h1-title" /> // 置き換えたい部分のslot nameを決める
  </h1>
  <h2>
    <slot name="h2-title" /> // 置き換えたい部分のslot nameを決める
  </h2>
</div>
```

参考
https://note.com/aliz/n/n8a0f81fc6583

間違ってたらコメントをください。
spring × docker

##背景

現在springとdockerの勉強をしている。

どうせやるならdockerを使ってspringの開発環境の構築をしたい。

[公式tutorial](https://spring.pleiades.io/guides/gs/spring-boot-docker/#initial)や他の記事を色々調べてみたがいまいち規則性がわからず困っている。

原因はそもそも自分のdockerに対する知識不足の面もある

勉強しつつ自分の判断軸を作りたい。

##Dockerを学習する目的

- 開発環境構築を楽にしたい
- 新しくジョインする方の環境セットアップを楽にしたい
- 開発環境に問題が起きると修復だけでかなり時間がかかることがある、その時間を減らしたい

##参考記事



[Dockerで開発環境構築を10倍楽にしたはなし](https://techblog.kayac.com/developing-with-docker-compose)


[Running Spring Tool Suite and other GUI applications from Docker containers
](https://javaoraclesoa.blogspot.com/2018/08/running-spring-tool-suite-and-other-gui.html)

[Running Spring Tool Suite and other GUI applications from a Docker container
](https://blogs.oracle.com/developers/running-spring-tool-suite-and-other-gui-applications-from-a-docker-container)


###MySQL環境を構築する場合

[Java11+Spring Boot+Dockerで作るWebアプリケーション](https://blog.mmmcorp.co.jp/blog/2019/01/19/java11_springboot_docker/)


[docker-compose でMySQL環境簡単構築
](https://qiita.com/A-Kira/items/f401aea261693c395966)


###APIを作る場合
[Docker上でSpring Bootを動かしてみる
](https://qiita.com/tkani/items/ed56229330f00a333d5e)

[SpringBoot+DockerでAPIを作る方法を０から書いてみる
](https://qiita.com/reiji_matsumura/items/106024b61685cd361234)
初学者ポートフォリオに抱いた私の違和感を解消するために調べてみた


## 記事の背景
初学者ポートフォリオを見て抱いた、私（フロント未経験）の抱いた違和感が、
妥当なものかを確かめるために、「ポートフォリオ」を調べてみました。

###①使用場面から考える「ポートフォリオ」
　クリエイターが実績を提示する作品集という意味で使用される

###②単語の意味から考える「ポートフォリオ」
　書類（作品）を運ぶためのケース

##★ここたん的認識
昔はデザイナーさんが、作品（フライヤーやポスター等）を紙媒体としてファイリングし、
作品集をクライアントに提示していた認識なので、クリア。
昨今では、作品集を電子化して、ポートフォリオサイトを作成し、
クライアントに提示しているらしい。

### その上でここたんがみかけた、初学者「ポートフォリオ」へ抱いた違和感
#### １．自己紹介だけ
---------- >（え？自作HPのことをポートフォリオっていうの？）
#### ２．スキルセット
---------- >（へぇ、、、、、）
#### ３．模写 or 仮想サイト
---------- >（練習記録見せられてる？）

で？と言う気持ちになる:frowning2:


ここたん的認識は上記①②をクリアしていたので
ここたんの抱いた違和感が妥当という結論に至りました。

以上。
※ ここたんの違和感の原因を思考したものであり、マーケティング要素は一切ない記事です。
※「だからどうすりゃええんだ」はまた次回考察します。
備忘録No.2「ArrayListとHashSetで検索履歴を作る」[Java]

#はじめに
paizaのスキルチェック入門編で苦戦したので記録。

#やりたい事
1.任意の文字数の文字列を複数入力し、リストに持たせる。
2.その際、入力した文字列がすでにリストに存在していたら、以前の文字列を削除し、新しく追加する。
3.一番新しく入力されたものから順に上から出力する。

#コード1
```java

        Scanner sc = new Scanner(System.in);
        List<String> words = new ArrayList<>();
        while(sc.hasNext()) {
            String s = sc.nextLine();
            if(words.contains(s)) {//すでにリストにあるか調べ、存在していたら削除する
                words.remove(s);
            }
            words.add(0, s);//入力された文字列をリストの先頭に加える
        }

        for(String word : words) {
            System.out.println(word);
        }
```
#コード１の問題点
・ArrayListは、remove()やadd()で値を増減させると、格納されている全ての値をずらさなければいけない為、処理に時間がかかる。
・ArrayListのcontains()も、リスト内の全ての値を検索する為、格納されている値が多いほど、処理時間が長くなる。

#解決策
・文字列の検索にHashSetを使う。→ 要素をハッシュ値に変換して検索に使うことができ、素早く値を発見できる。

#コード2
入力された文字列は全てリストに追加し、HashSetを使って、重複しているものは表示しないようにする。（実際に削除するのではなく、無かったことにする)

```java

        Scanner sc = new Scanner(System.in);

        List<String> words = new ArrayList<>();
        while(sc.hasNext()) {
            String s = sc.nextLine();
            words.add(s);
        }

        Collections.reverse(words);//新しく入力されたものから出力する為にリストを反転

        Set<String> usedWords = new HashSet<>();//リスト内の文字列の重複の判定に使うHashSet

        for(String word : words) {
            if(!usedWords.contains(word)){//すでにusedWordに追加されているか(重複しているか)を判定し、していなかったら表示
                System.out.println(word);
            }
            usedWords.add(word);
        }
```
NameError: uninitialized constantを解決する【ActionMailer】

#概要
製作中のアプリケーションにAction Mailerを導入して実装しようとしたら序盤で沼にハマったので備忘録として記録します。

[参考にした記事](https://www.sejuku.net/blog/48739)

上記の記事の4 メールを送信してみようでエラーが発生

    NameError: uninitialized constant InquiryMailer

最初はクラス名やファイル名の単純なエラーかと思ったが一向に解決しない。

### 結論

以下の記事にたどり着き、どうやらspringが悪さをしているらしい。
試しに止めてみたら上手くいきました。

    spring stop

[参考にした記事](https://github.com/rails/rails/issues/38174)
[springについて](https://pleiades.io/help/ruby/spring.html)
シェルスクリプト練習

##シェルスクリプトとは？

unixの操作をしているときにコマンドをまとめて実行したい場合がある
そんなときに使えるのがシェルスクリプトである。

##開発環境
cloud9
ProductName:	Mac OS X
ProductVersion:	10.15.7


初めは簡単なシェルスクリプトから練習

今回はシェルである bash を使う
bash がどこにあるか調べる場合は which bash で調べることができる
/bin/bash をコピーしてはる
`#!`は「シェバン」もしくは「シバン」という

```sh
ec2-user:~/environment $ mkdir shell_lessons
ec2-user:~/environment $ cd shell_lessons/
ec2-user:~/environment/shell_lessons $ touch hello
ec2-user:~/environment/shell_lessons $ which bash
/bin/bash
ec2-user:~/environment/shell_lessons $ ls -l
total 4
-rw-rw-r-- 1 ec2-user ec2-user 25 Oct 22 16:14 hello
ec2-user:~/environment/shell_lessons $ chmod +z hello
chmod: invalid mode: ‘+z’
Try 'chmod --help' for more information.
ec2-user:~/environment/shell_lessons $ chmod +x hello
ec2-user:~/environment/shell_lessons $ ls -l
total 4
-rwxrwxr-x 1 ec2-user ec2-user 25 Oct 22 16:14 hello
ec2-user:~/environment/shell_lessons $ ./hello 
hello
```

##変数を使う場合

```sh

#!/bin/bash

#エラー
name = "cloud9"

#正解
name="cloud9"

echo "$name"
```

初めて知ったこと
シェルスクリプトの場合　「=」に半角スペースがあるとエラーが発生するようだ
スプレッドシートでQUERY関数を使って指定した文字を含まないクエリを記述する。

```
NOT Col1 contains '文字列'
```

not(Col1 contains '文字列')
ではないので、注意

例ではCol1ですが、
普段はAとかBとかで平気です。

QUERY(TRANSPOSE(A1:Z),"QUERY")

などの、私みたいによくわからないことをする機会がある方はColで指定してください。
Windows10 Node.jsのバージョン管理

##背景
windows10でnode.jsをインストール、バージョン管理の方法についてまとめる。


開発環境
windows10 64bit

##結論

この記事がとても参考になった。m(_ _)m
[nvm-windowsでNode.jsバージョン管理
](https://qiita.com/akuden/items/a88630de9624039c4135)


##方法
nvmのwindows版であるnvm-windowsをインストール
[coreybutler/nvm-windows
](https://github.com/coreybutler/nvm-windows/releases)


- nvm-setup.zipをダウンロード
- c直下に配置
- コマンドプロントを開く

```
> nvm --version
Running version 1.1.7
```

```
> nvm list available
```

今回は10.22をインストール

```
> nvm install 10.22
```

インストール後、使用バージョンを指定

```
> nvm use 10.22
> node -v
v10.22.0
```

```
> npm version
6.14.6
```

##まとめ


- node.jsの公式サイトからダンロードするよりもこちらの方がバージョン管理が楽
[ORACLE][SQL]複数レコードの値を1レコードにまとめるXMLAGG関数の例

#XMLAGG関数
・複数レコードの値を1レコードにまとめる、LISTAGG関数とXMLAGG関数があります。
・LISTAGG関数を用いる際に4000バイト文字を超える恐れがある場合は、XMLAGG関数を使用。
・ポイントは、下記SQLの「ORDER BY COL23」です。　綺麗に連結できます。

```sql
SELECT COL1,
RTRIM(XMLAGG(XMLELEMENT(e,COL23,'|').EXTRACT('//text()') ORDER BY COL23 ).GetClobVal(),'|') AS COL23
FROM
(
SELECT 
DISTINCT
TBL1.COL1
, TO_CHAR(TBL2.COL3, '99999') ||  '（' || TBL2.COL3 || '）' AS COL23
FROM
TBL1
 LEFT JOIN TBL2 ON TBL1.COL1 = TBL2.COL1
)
GROUP BY COL1
```
Vue.js のサンプルアプリケーションを立ち上げるときの手順メモ

## 欲しいもの
- Vue
- TypeScript
- vue-property-decorator
- eslint
- prettier
- tailwindcss

tailwindcss 以外は Vue CLI でプロジェクトを作成するとデフォルトで入る。

## 手順
Vue CLI でプロジェクト作成

```shell
$ vue create vue-sample
```

vue-ts-sample ([Vue 2] babel, typescript, eslint) を選択

```shell
? Please pick a preset: (Use arrow keys)
❯ vue-ts-sample ([Vue 2] babel, typescript, eslint)
  vue-simple-sample ([Vue 2] babel, eslint)
  Default ([Vue 2] babel, eslint)
  Default (Vue 3 Preview) ([Vue 3] babel, eslint)
  Manually select features
```

tailwindcss を追加する（スタイルをあてるのが楽だから）

```shell
$ yarn add tailwindcss
```

tailwindcss を有効にするために src/postcss.config.js と src/assets/index.css を追加

```src/postcss.config.js
const autoprefixer = require("autoprefixer");
const tailwindcss = require("tailwindcss");

module.exports = {
  plugins: [tailwindcss, autoprefixer]
};
```

```src/assets/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

src/assets/index.css を main.ts で import

```main.ts
import Vue from "vue";
import App from "./App.vue";
import "./assets/index.css";

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");
```

package.json の eslint の extends を下記のような感じにする。Vue のスタイルガイドになるべく沿うようにする。

```json
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/recommended",
      "eslint:recommended",
      "@vue/prettier",
      "@vue/typescript/recommended",
      "@vue/prettier/@typescript-eslint"
    ],
    "parserOptions": {
      "ecmaVersion": 2020
    },
    "rules": {}
  }
```

あとはデフォルトの無駄な HelloWorld などを削除して終わり。

## ハマったところ
### VSCode 上で ESLint が効かない
##### 原因
ESLint Server が立ち上がっていなかった

##### 解決方法
VSCode の画面右下の「ESLint」をクリックして有効化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474068/505b828a-b904-75c2-ed0a-6f635d87bf9f.png)

### prettier の自動フォーマットが効かない
##### 原因
package.json の設定漏れ

##### 解決方法

```diff
 "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/recommended",
      "eslint:recommended",
      "@vue/typescript/recommended",
+     "@vue/prettier",
      "@vue/prettier/@typescript-eslint"
    ],
    "parserOptions": {
      "ecmaVersion": 2020
    },
    "rules": {}
  },
```

@vue/prettier/@typescript-eslint だけで prettier が有効になると勘違いしていました。

## 参考
- https://qiita.com/hisako135/items/49c05633de4dadfcd627
WEB開発の基礎知識(フロントエンド)　

#はじめに
WEB開発を行ううえでの、超初心者エンジニアが最初に覚えると良い基礎知識をまとめました。
フロントエンド開発をこれから勉強したい！という方向けの内容となっております。

実際の開発知識を身につける前に、
○この技術の誕生に至る背景はどのようなものか？
○普段当たり前に使用しているモノはどういう仕組みで動いているのか？
を頭に入れておく事はきっと役に立つはずです。

「ふーん、なるほどね」くらいで、そこら辺のフリーペーパーとでも思って見ていただければと思います。
※ 私自身も勉強中の身でして、初心者に一本毛が生えた位のレベルですので、間違い等お気づきになられましたら
 お手数ですがご指摘頂けると幸いです。随時追記、修正していきますので悪しからず。

#WEBの基礎知識
###よく耳にする用語集
- **WWW（World Wide Web）**
インターネット上の様々なコンテンツをインタラクティブ（相互的）に
閲覧するための技術の総称です。
単にインターネットという表現そのものを意味する場合もあるそうです。
いろいろなURLの中に入っているwwwも、こちらが由来です
`（例）https://www.google.com/`
ちなみに一番最初のWEBサイトが公開されたのは1991年と言われています。
意外と最近だったんですね。

- **W3C（World Wide Web Consortium）**
WWWの様々な技術を標準化、推進する団体です。
つまり、「WEBでこういうことがしたかったら、こういう方法で開発するのがオススメです！」
というルールみたいなものを定義している人達。
WWWの開発者でもある、ティム・バーナーズ=リーさんが1994年に設立しました。

- **ハイパーテキスト**
ハイパーリンクと呼ばれる、他のWEBページに遷移することができる機能が用いられた
ドキュメントのこと。後述しますがこれを書くための特有の言語があります。

- **クライアント**
営業などのお仕事ではお客様みたいなニュアンスですが、WEBの世界では
私達が直接使うPC環境、WEBブラウザのことです。
そのためクライアントと言う言葉は時々、フロントと置き換えられます。
クライアント側で、WEBを閲覧するためのインターフェースを提供するのがブラウザになります。
>インターフェース
>コンピュータで、異なる機器・装置のあいだを接続して、交信や制御を可能にする装置やソフトウェア。

- **サーバー**
通信をするなにか。と思いがちですが、本当は、色々なデータを保存していて
クライアントからの要求に応えて何らかの応答を返す媒体です。
因みにこの要求をリクエスト、応答をレスポンスと呼びます。
サーバーからのレスポンスにはHTMLやCSSのファイルが含まれており、
それを受け取ったWEBブラウザがファイルを解析し、WEBページとして表示する仕組みになっています。

- **HTML(Hyper Text Markup Language)**
ハイパーテキスト（WEBページ）をマークアップ（記述）するための言語です。
私達が普段見ているWEBページも、ほとんどこのHTMLで記述されています。
（厳密にはHTMLの他にも色々な技術が合わさって作成されています。）
また、マークアップは訳すと「マークをつける」ということになりますが
WEBページ内の様々なコンテンツに対して印を付け、ブラウザが認識し易くする。
といった感じになります。

- **CSS（Cascading Style Sheets）**
WEBページにスタイルをあてる（装飾する）ための言語です。
検索してヒットするWEBページのほとんどは、HTMLにプラスしてこのCSSも
使われている場合がほぼ100%と言って良いでしょう。
因みにHTMLとCSSを使ってWEBページを作成する人を
「マークアップエンジニア」と呼んだりします。

- **Javascript**
おもにWEBで活用される、フロントエンド（見た目部分）に関与している**プログラミング言語**です。
先述したHTMLやCSSはプログラミング言語ではないようです。
HTMLとCSSだけでは毎回同じサイトしか表示できませんが、
Javascriptを用いると次のようなことができたりします。
・日付や時刻によって、サイトのヘッダー内容の表示を変える
・ボタンAが押されたら○○をする。というようなプログラムをWEBページに与えられる
・ブログの投稿のお気に入り数によって、ランキング一覧を毎回更新して表示する
Javascriptを使うと、サイトを「動的」にすることができます。
HTMLやCSSのみのページは「静的」です。
フロントエンドの技術進歩は凄まじく、今はJavascriptで出来ることが沢山あります。

###そもそもプログラミング言語とは
コンピュータ内で人間の頭脳にあたるパーツである、CPU（中央処理装置）が読める複雑な、
機械語というものを人間が理解しやすい様に開発された言語。

因みにこのプログラミング言語を機械語に変換（コンパイル）する必要があるが、２パターンの方式が存在する。

・**コンパイラ方式**  (windowsやmacアプリの開発言語に多い)
　あらかじめコンパイルをしておいてからプログラムを実行
　→プログラムを高速に処理できるが、プログラム修正のたびにコンパイルの作業が必要

・**インタプリタ方式** (WEBの開発言語に多い)
　プログラムの実行と同時にコンパイルを実行
　→コンパイラ形式より実行速度は落ちるが、修正や変更のたびにコンパイルを行わずにすむ



#フロントエンドって何？
ユーザの目に見える箇所全般のことを指します。
つまりフロントエンド開発とは、**見た目の改善、見た目を作成する仕組みの改善を行い、
利用者に安心かつ最適なユーザーインターフェース（UI）を提供すること。**だと思っています。

対立する用語はサーバーサイドといい、こちらはユーザが直接見ない部分である
サーバーに寄った部分のことを指します。
（ざっくりし過ぎですが、イメージ的にはデータベースとか、インフラとか、APIとか
ちょっとお固い感じ。）

因みに...フロントエンドのお仕事で最近よく聞く
- WEB制作
- フロントエンドエンジニア
これらは何が違うのかというと。
**WEB制作**...
HTML/CSS/JQuery(Javascriptのライブラリです)/
WordPress(CMSといってウェブサイトを簡単につくれるシステムです)
→これらを用いて静的なページをつくる。
**フロントエンドエンジニア**
HTML/CSS/Javascript/JSフレームワーク/..他大量の技術
→を用いて、サーバーサイドのエンジニアと連携して
WEB制作よりもしっかりした動的なサイトやアプリケーションをつくる。

といった感じです。


#開発環境について
開発環境とは、その名の通りWEBの技術を開発する上での作業場所という意味になります。
サーバーで実行されるサーバーサイドの技術は、もちろんそのサーバーを準備する必要が
あり、設定や手順が厄介なものがありますが、フロントエンドの実行する場所はブラウザです。
ブラウザと文字が書けるエディタがあればプラクティスが可能です。
PHP：ビルトイン関数array_unique()を自作してみた

#やりたいこと
ジャズライブの口コミをタグ付きで投稿できるサイトを、チームで開発しています。
タグが送信された時に、配列の中に２つ以上同じ文字列があったら、前者だけを残して他を削除し、配列内の値が全てユニークである状態を作るプログラムを作りたくルンルン楽しく試行錯誤していたら、`array_unique()`というPHPの便利なビルトイン関数があることを知り、便利と思いつつちょっと萎えました。なら無駄に自作してみっか！と思い作ってみました。

**[YouTube万屋エンジニアチャンネル](https://www.youtube.com/channel/UCHxqQ8bUg5F2GW79D_DvSjQ/videos)**のコミュニティーで大いに助けていただきました。大感謝！

#やってみた
試行錯誤しましたが、下記でarray_unique()と同じ結果が得られます。

```php
<?php

$tags = ['jazz', 'onuma', 'fusion', 'jazz', 'fusion', 'fusion', 'tokyo'];

$unique_tags = array(); //(1)unique_tagsを配列にする

foreach ($tags as $key=>$val) { //(2)後述
  $unique_tags[$val] = true;
}
$unique_tags = array_keys($unique_tags); //(3)配列のkeyを返す

print_r($unique_tags);

//出力↓
Array
(
    [0] => jazz
    [1] => onuma
    [2] => fusion
    [3] => tokyo
)

```
(1)は結構誰でもわかると思います。
(2)は初心者の私にはトリッキーでしたが、
　　a. まずforeachで配列`$tags`をキーを`$key`、値を`$val`と名前を付けて一つずつ処理すると()内で宣言。
　　b. (1)で配列化した`$unique_tags`のキーに`$tags`の値の方を渡し、連想配列化し、その値には[定数true](https://www.php.net/manual/ja/language.types.boolean.php)を代入。連想配列とは、キーを数字ではなく文字列にして管理する配列。
　　c. キーの重複は不可能なので、自然とbの時点で、重複するtagsの値は弾かれる。
　　d. この時点で$unique_tagsは下記のようになっています。

```php
Array
(
    [jazz] => 1
    [onuma] => 1
    [fusion] => 1
    [tokyo] => 1
)
```
(3)array_keysで配列のキーを配列で返します。

#最後に
ご指摘や他のやり方を知ってるという方いましたら、ぜひコメントにてよろしくお願い申し上げます、