OmniAICreator/Qiita-1.07M huggingface dataset:
M1 MacでDocker Preview版が起動しなくなった。

## 事象

ある日突然Docker Preview版が起動しなくなりました。
~~何もしてないのに...~~

## 解決方法

以下のIssueを参考にしました。

https://github.com/docker/for-mac/issues/5276

まず以下を試しました

Kubernetesを無効化（効果なしでした）

> k8s is known not to work, I had to edit ~/Library/Group\ Containers/group.com.docker/settings.json ("kubernetesEnabled": false, "kubernetesInitialInstallPerformed": false) to get the dashboard to respect that I wanted to back out that change
that said, the perpetual starting state problem happened to me long after I tried to enable k8s
edit: when docker was working, I was using k3d successfully

で、以下を試したところ起動しました（FireWallをOFFにする）

ちなみにファイアーウォールオプションから、Docker Previewを外部アクセス許可してもだめだったので、ファイアーウォール自体をオフにしないとダメっぽいです。

> Try to close the firewall on mac m1 and then restart the docker.

## 結論

~~原因はわかりませんが、~~Mac側のファイアウォールが起動を妨げていた模様。

**セキュリティ的に問題ありそうですが**、一応は動くようになったので解決です。
EntityFrameworkCoreでDDLファイルを出力する

#目的
ASP.NET Core(.NET Core)でコードファーストでデータベースを作成する。
この際、実際データベースに発行しているDDL(SQL)をファイルに出力する方法を記す。


#前提条件
Microsoft.EntityFrameworkCore.Tools を導入済である

#方法
1.テーブルセットファイルを作成する
`PM> Add-Migration Init
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
`
https://docs.microsoft.com/ja-jp/ef/core/cli/powershell#add-migration

2.SQLスクリプト(DDL)を作成する
`PM> Script-Migration 0
Build started...
Build succeeded.
`

https://docs.microsoft.com/ja-jp/ef/core/cli/powershell#script-migration

##注意
本来マイグレーションを意識したコマンドである。
プログラムにおけるエラー処理


# １．エラー処理は問題対処の放棄ではない（エラーの分類）

プログラムにおいてエラー処理は重要です。
ただ、設計の際には意外と、後回しにしたり、設計の時間が短かったりします。
エラーと一言で言っても、立場・視点によってその意味合いは異なってきます。
エラーを分類してみると以下のようになります。

## （１）ユーザーが引き起こすエラー

　入力エラーや、処理の運用上不必要な処理、受け入れられないことがこれに該当します。

## （２）プログラマが引き起こすエラー

　いわゆる「バグ」と呼ばれるもので、コーディング上のエラーに該当します。関数の実行され方がおかしいとか、考慮ミス、そして、テスト不足が原因です。

##（３）環境が引き起こすエラー

　実行時にしかわからないアプリケーションの外部のものが引き起こすエラーです。
たとえば、DBへの接続がきれてしまった、保存先がいっぱいになってしまって書き込めないなど、状態の変更によっておこり、アプリケーションの制御外の原因によって起こるものです。

# ２．「例外」は「想定外」。単なるエラーとは異なる
　
　エラーと同義のように使われる「例外」についてみてみます。
Javaをはじめとするオブジェクト指向言語では、「例外」という考えやクラスがあり、正常な処理を妨げることが起こると「例外」を発生させるという処理をします。
では、「エラー」と「例外」言葉上は違いますが、同じように扱ってもよいのでしょうか？

## （１）設計時に想定ができるもの、できないもの

　多くの場合、この境は曖昧です。そもそも、英語にしろ日本語にしろ、「例外」というのは、言い換えてみると「想定外」「ケースとして該当しないもの」と言えます。
それでは、よくソフトウェアの現場で見られる「例外」の利用ケースはどうでしょうか？
　
　想定されているケースについても、「例外」が使われていないでしょうか？
ユーザーがある処理上思わしくないことをしたからといっても、それが想定されるのであればそれは「例外」ではなく、しいていえば「異常系」です。そして、どちらかといえば、これは「エラー」といったほうがまだしっくりきます。
　
　往々にして、「例外」は処理をそこで止めてしまう機能をもっていますが、それは想定していない現象に使う以上は、対処ができずそこで処理をすべて止めてしまうのが当然なことです。
逆にいえば、想定されているケースであれば、処理は継続できるはずです。たとえ、そこでメッセージを表示させて終了させるにしてもです。

# ３．ユーザーへの情報伝達、再操作への支援こそエラー処理の目的
　
　エラーについて、「立場・視点」、そして、「例外」という観点で考察をしました。
Googleが開発している「Go」を用いたアプリ開発においては、異常系の判別については、例外（panic）は使わず、明示的にerror型の変数を返却して、判別して、処理を継続することが一般化しています。
　
　一見、めんどくさいように見えますが、本来、エラーがどう発生して、発生に対してアプリケーションがどうユーザーに伝え、どう対応してもらうのかを考えたとき、Goの発想は必要なことのように思います。
　
　そして、ユーザー由来のエラーについては、本来、多くのケースにおいて、「例外」ではなく、「異常系：エラー」として、想定して適切なメッセージ表示や、オペレーションの適正な方法を提示するべきだと思います。
一言で「エラー」といっても、その起因を考え、原則、処理を止めずに責任をもって、ユーザーの情報を届けて、可能な限り、アプリケーションの処理を止めないこと、それが「エラー処理」において重要なことだと思います。
　
　エラー処理が曖昧なソフトは有名なものでも多く見られます。一体どうすればいいのだという憤りを覚えたことは多くのユーザーが持っていると思います。
その根底には作り手の、エラーに対する向き合い方の不十分さがでているのだと思います。

# ４．想定内、想定外、いずれのエラーにも誠実に対応する

　エラーは想定外ではなく、きちっと想定して、可能な限り再操作の方法を提示できてこそ、本当のエラー処理で、問題の先送りがエラー処理ではないと思います。
エラーへの配慮の行き届きまでできているシステムはきっと、正常系においてもきちっとした処理ができているはずだと私は偏見かもしれませんが、そう確信しています。
【SwiftUI】NavigationViewの遷移のネストでbackボタンが複数生成されていくのにハマったのでメモ

#はじめに
SwiftUIを触り始めてまだ１日目
`Navigation`での画面遷移を行う際に愚直にコードを書いていたが、解決記事がさっと見つからなかったのでメモ

#開発環境
* Swift(version 5.3.1)
* Xcode(version 12.2)

#解決したいこと
`Navigation`のbackボタンが前画面のViewに更新されるのではなく、下に追加されてしまっている…
![Swift01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543882/8ff6bf0d-6a70-c637-c507-3dc1f4194d6d.gif)
いやいや、困るよ(汗

#解決する前
* FirstView.swift
* SecondView.swift
* EndView.swift

以上の3画面で構成している

```Swift:FirstView.swift
struct FirstView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: SecondView()) {
                Text("Go Second View")
            }
        }
        .navigationTitle("First View")
    }
}
```

```Swift:SecondView.swift
struct SecondView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: EndView()) {
                Text("Go End View")
            }
        }
        .navigationBarTitle("Second View", displayMode: .inline)
    }
}
```
```Swift:EndView.swift
struct EndView: View {
    var body: some View {
        Text("Hello, World!")
    }
}
```
シンプルに実装したが何が原因なのか…

#解決方法
なんか`Navigation`が2個生成されてる雰囲気だよね
`FirstView.swift`で`NavigationView{}`を記述しているから`SecondView.swift`ではもしかしていらない感じ？？
`NavigationLink`だけ残して動くのかな…

```Swift:SecondView.swift
struct SecondView: View {
    var body: some View {
        //NavigationView {}削除！
        NavigationLink(destination: EndView()) {
            Text("Go End View")
        }
        .navigationBarTitle("Second View", displayMode: .inline)
    }
}
```


これで実行↓
![Swift02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543882/9448c0f7-3914-6ea1-e3d9-59479e6df9ee.gif)
うんうん、この挙動を求めていたの
無事に解決した〜！

#最後に
多分、これであってるよね？
愚直に書いてるとこういうところにハマるね
まだまだ初心者だけど頑張ろう

Qiita初投稿…こんな感じの書き方でいいのかなw
RubyとHTMLにおけるクラス名の書き方の違い



# クラス名の付け方の違い
1.HTMLでのクラス名の付け方は、このようにclass="#"として名付けることができます。

     <a href="##", class="#">
      〇〇  
     </a>

2.Rubyでのクラス名の付け方は、class:"#"として名付けることができます。

          <link_to "##",class:"#">
  
#最後に
私の学習順序ではHTMLが先だったのでclassの記述の仕方についてはclass="#"でしかないと思っていましたが、rubyの記述で同じ記述をした場合rubyにおけるクラスとインスタンスの方のclassが与えられてしまっていたので、ここは覚えておかなければいけないポイントなのではないかと思い、記事を書かせていただきました。このほかにも上記のようなlink_toの書き方であったり、form_withなどはHTMLと書き方が違うのでまた必要だと思ったことは書かせていただきます！！
Pythonでテキストファイルの行数を取得する方法

#Pythonでテキストファイルの行数を取得
    import subprocess
    cmd = "wc -l [テキストファイル名]"
    c = subprocess.check_output(cmd.split()).decode().split()[0]
    print(c) 
    #行数990002のファイルにかかった時間
    0.05637836456298828 (sec)  
他に以下でも取得できる

    print(len(open('[テキストファイル名]').readlines()))  
    #行数990002のファイルにかかった時間
    0.2346503734588623 (sec)

    print(sum(1 for line in open('[テキストファイル名]')))  
    #行数990002のファイルにかかった時間
    0.1792283058166504 (sec)

　それぞれかかる時間を比較すると、一番上の方法が最も速いが、何度も取得する必要がなければ大差は無い。
mapメソッドの実践的な使い方

#課題
皆さんは、ポートフォリオ等でオリジナルアプリを作成する際に下記のようなことで困ったことはありませんか？

- マイページで口コミを投稿した店舗(商品)を一覧で表示したいが、店舗(商品)を取得する方法がわからない。

イメージとしては以下のような感じです。※paramsではユーザーidのみ取得可能


```ruby:histories_controller.rb
  def index
    user = User.find(params[:user_id])
    @reviews = Review.where(user_id: user.id)
  end
```

DB図
![DB図_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759659/2906f6c2-8292-ac61-927a-8bb1e4d5d2a2.png)

ここから、ビューファイルに店舗一覧を表示したいと思うと以下のように無理やりになってしまいます。
※一部抜粋

```erb:views/histories/index.html.erb
    <% @reviews.each do |review| %>
      店舗名：<%= review.shop.name%>
      店舗投稿された口コミ数：<%= review.shop.reviews.count%>
      口コミの全内容：<% review.shop.reviews.each do |review|%>
        口コミのタイトル<%= review.title%>
        口コミ投稿者<%= "by　#{review.user.name}"%>
                  <% end %>
    <% end %>
```
これ見づらいだけでなく、同じ店舗に口コミを2回している場合、一覧でも店舗が2回登場してしまいます。
どうにかして、特定のユーザーのマイページでそのユーザーが口コミを投稿した店舗を取得したい、、
しかし、reviews変数が配列で要素を所持しているから扱いづらい、、

# 結論
その時にmapメソッドが非常に役に立ちます！
結論から言うと下記の書き方で口コミした店舗データのみを取得できます。

```ruby:histories_controller.rb
  def index
    user = User.find(params[:user_id])
    reviews = Review.where(user_id: user.id)
    @shops = Shop.where(id: reviews.map{|review| review.shop_id})
  end
```
mapメソッドは公式リファレンスによると以下の説明が書いています。

>各要素を順番にブロックに渡して評価し、その結果で要素を置き換えます。

つまり、reviews変数がもつ配列内のすべての要素に対して、whereメソッドで検索したことになります。
reviews内の各要素を順番にreview変数にいれた後にshop_idを参照しているということです。

これで、口コミしたことがある店舗データをshops変数内に取得しました。
しかもwhereメソッドにはdistinctの処理が自動的に入っているので、店舗データの重複はしないようになっています。

その結果ビューファイルも以下のようにスッキリ記載することができます。

```erb:views/histories/index.html.erb
    <% @shops.each do |shop| %>
      店舗名：<%= shop.name%>
      店舗投稿された口コミ数：<%= shop.reviews.count%>
      口コミの全内容：<% shop.reviews.each do |review|%>
        口コミのタイトル<%= review.title%>
        口コミ投稿者<%= "by　#{review.user.name}"%>
                  <% end %>
    <% end %>
```

こんな感じでスッキリしました！
Arrayクラスを扱うときはmapメソッド、めちゃくちゃおすすめなので、ぜひ使ってみてください。
LINE Messaging APIでメンション情報が取得できるようになったよ！

LINEBotでメンション情報が取れるようになった！

# 最近アップデートきた
### [Messaging APIアップデート（2021年1月）](https://developers.line.biz/ja/news/2021/01/20/messaging-api-update-january-2021/)
> **テキストメッセージタイプの新プロパティ**
以前は、グループチャットやトークルーム内のメンションの情報は取得できませんでした。今回、メッセージWebhookイベントオブジェクトのテキストメッセージタイプに追加された新プロパティを利用することで、メンションの情報を取得できるようになりました。
>
>新たに追加されたプロパティは以下のとおりです。
>
> `mention`：メンションの情報を含むオブジェクト。
> `mention.mentionees[]`：1個以上のメンション。
> `mention.mentionees[].index`：テキストの先頭を0とした、textプロパティ内のメンションの開始位置。
> `mention.mentionees[].length`：メンションの長さ。@exampleであれば、8が長さになります。
> `mention.mentionees[].userId`：メンションされたユーザーのユーザーID。
詳しくは、『Messaging APIリファレンス』の「[テキスト](https://developers.line.biz/ja/reference/messaging-api/#wh-text)」メッセージタイプを参照してください。

# 試してみる
nodejsで見てみる。
公式SDKのEcho-Botのサンプルを使う。
https://github.com/line/line-bot-sdk-nodejs/tree/next/examples/echo-bot

とりま、`event.message` 見てみよう。

```diff:line-bot-sdk-nodejs/examples/echo-bot/index.js
function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    // ignore non-text-message event
    return Promise.resolve(null);
  }
+  console.log(event.message);

  // create a echoing text message
  const echo = { type: 'text', text: event.message.text };

  // use reply API
  return client.replyMessage(event.replyToken, echo);
}
```

```shell
macuser@macbook:~/line-bot-sdk-nodejs/examples/echo-bot (next *)$ node index.js 
listening on 3000
{
  type: 'text',
  id: '13424246938488',
  text: '@みかんBot @R @りんごBot @カワウソちゃん ',
  mention: { mentionees: [ [Object], [Object], [Object], [Object] ] }
}
```
おお、**mentionees!**
もっと見てみよう。

```diff:line-bot-sdk-nodejs/examples/echo-bot/index.js
function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    // ignore non-text-message event
    return Promise.resolve(null);
  }
+  console.log(event.message.mention.mentionees);

  // create a echoing text message
  const echo = { type: 'text', text: event.message.text };

  // use reply API
  return client.replyMessage(event.replyToken, echo);
}
```
```shell
macuser@macbook:~/line-bot-sdk-nodejs/examples/echo-bot (next *)$ node index.js 
listening on 3000
[
  { index: 0, length: 7, userId: 'Ud99df1c3b2066eca8348547af0c8be9f' },
  { index: 8, length: 2, userId: 'U89c0a22ed4a897463bd950519e0f72ba' },
  { index: 11, length: 7, userId: 'U054f7d1ddf16b75f1a8df5c39d043c9b' },
  { index: 19, length: 8, userId: 'U272633bd8ac62da518bac7b7469cc420' }
]
```
おおお、よい！

# ちょっと注意

**情報の取得に同意してないユーザー**のuserIdは取得できない。

```shell
macuser@macbook:~/line-bot-sdk-nodejs/examples/echo-bot (next *)$ node index.js 
listening on 3000
[
  { index: 0, length: 7, userId: 'Ud99df1c3b2066eca8348547af0c8be9f' },
  { index: 8, length: 2, userId: 'U89c0a22ed4a897463bd950519e0f72ba' },
  { index: 11, length: 7, userId: 'U054f7d1ddf16b75f1a8df5c39d043c9b' },
  { index: 19, length: 16 }
]
```
詳細はこちら
https://developers.line.biz/ja/docs/messaging-api/user-consent/

# 最後に
メンションの情報を取得できるだけで大分幅が広がりそうですね〜

残念ながら**botからグループ、ルームメンバーへのメンション**は出来ません。。。
無償のSpark実行環境であるDatabricks Community Editionの申し込み方法


## 概要
無償でSpark実行環境として利用できるDatabricks Community Editionの環境構築方法を共有します。
合わせて、無償で提供されているDatabricksの学習コンテンツの申し込みもおすすめします。

- [Databricks Academyで、20万円相当のSelf Paced Trainingを無償で申し込む方法 - Qiita](https://qiita.com/ryoma-nagata/items/0221c07b64a112f1f949)

### Databricks Community Editionとは
Sparkによるビッグデータ処理やPythonやRによるデータ分析を実施可能なデータ統合データプラットフォーム（レイクハウス）のサービスであるDatabricksの無償環境です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/c5d2f198-43ef-eebb-4e0a-444f1d633016.png)
引用元：[Databricks - 統合データ分析](https://databricks.com/jp/)

## Databricks環境構築
### [Try Databricks](https://databricks.com/try-databricks)から申し込みを実施します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b13a9b83-02d9-d018-eae8-3bb0e5b7f366.png)
引用元：[Try Databricks](https://databricks.com/try-databricks)

### 下記にて、"COMMUNITY EDITION"を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/048bd2e7-6f62-6291-5126-0219cf03f2f5.png)
引用元：[Try Databricks](https://databricks.com/try-databricks)

### 届いたメールのリンクを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/a8efb4bf-e142-3408-39c2-8fb165c9099a.png)

### パスワードを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/0eedb7d5-8d25-e875-cb9f-46f99c46f3f5.png)

### Databricksに接続できることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/053d1c96-90c8-d2b4-a0b5-4b8ccf69e751.png)

### "Clusters"を選択後、"+Create Cluster"を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/c279f525-48dc-b50b-2879-917afb88202a.png)

### "Cluster Name"に適切な名前を入力し、"Create Cluster"を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/c1cc6d84-7a79-35f6-f139-4a02b9a62963.png)

### 数分後に、クラスターが作成されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ddc30e4e-943b-02a5-174a-b8644a05dd04.png)

### "Workspace"を選択後右クリックし、"Create" -> "Notebook"を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/5a820b78-1197-2f2e-a31d-987220b6bb70.png)

### "Name"に適切な名前を入力し、"Default Language"にて"Python"を選択して、"Create"を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/947f37dc-65a2-2b95-ddfe-5518156be0fb.png)

### 左上にある"Detached"を選択後、作成済みのクラスターを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/16beada5-7fab-7bb3-f68e-f5476db5b901.png)

### "print("Hello World")"と入力後、右にある"▶︎"を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/9f278488-dd35-6168-7628-d1245c1466cf.png)

### "Hello Worldと表示されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b5792c4d-a948-2e1b-2a9d-219dd56ceed4.png)
extundeleteで削除したファイルを復元する

## はじめに
Ubuntuでファイルを削除してしまった！Windowsであれば、ごみ箱から復元したらいいだけなのだが、Linuxではこのような仕組みにはなっていません。しかも、mvするつもりが、rmをしてしまったという経験はありませんでしょうか？そこで、ファイルを思わず削除してしまっても、復元する手順は予め知っておいた方がいいでしょう。という事で記事を書きました。復元するには、いくつかの方法があるようですが、今回は、extundeleteというツールを使って復元しました。デフォルトではプレインストールされていないコマンドなので、コマンドがない環境の方は、個別にインストールして下さい。

参考URL
https://ameblo.jp/itboy/entry-11249111402.html


## 環境
Vagrant + Ubuntu 16.04.5 LTS

## やったこと

パーティションの情報を表示して、**Mounted on** が **/** になっているディレクトリのファイルシステムを調べます。自分の環境では、Vagrantで動かしているため、 **/dev/mapper/vagrant--vg-root** になっています。因みにファイルシステムは**ext4**です。

```
$df -hT
```

/home/vagrantにある、aa.txtを削除した後、復元してみます。

```
$rm aa.txt
```

**extundeleteコマンド**を実行する。

```
$sudo extundelete --restore-file /home/vagrant/aa.txt /dev/mapper/vagrant--vg-root
```

すると、カレントディレクトリに、**RECOVERED_FILES**という名のディレクトリが作成されます。

```
$ls -l
```

このディレクトリの中を見ると、削除したaa.txtが復元されています。

```
$ls -l RECOVERED_FILES/home/vagrant/
```

復元されたファイルをカレントディレクトリに持ってきます。

```
$cp RECOVERED_FILES/home/vagrant/aa.txt ./
```

復元されたディレクトリは削除しておきます。

```
$sudo rm -r RECOVERED_FILES/
```

状態が戻った事を確認してOK。

```
$ls -l
```
単体テストエラー　〜ActiveRecord::StatementInvalid:        Mysql2::Error::ConnectionError: Lost connection to MySQL server during query〜

自分の備忘録として残しておきます

<h1>エラー内容</h1>
ActiveRecord::StatementInvalid:
       Mysql2::Error::ConnectionError: Lost connection to MySQL server during query

![スクリーンショット 2021-01-22 12.27.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614674/4cbe7797-610d-211c-d843-343e8da50f59.png)


スクショを見る限り一つ目のテストは成功してるのに二つ目以降のテストは失敗している、、、なぜ？
可能性としてはテストに負荷がかかりすぎてread_timeout以内に処理が終わらなかった。

```ruby:spec/models/ファイル名_spec.rb

RSpec.describe UserAddress, type: :model do
  before do
    @user = FactoryBot.create(:user)
    @item = FactoryBot.create(:item)
    @user_address = FactoryBot.build(:user_address, user_id: @user.id, item_id: @item.id)
    sleep 0.1    #この1行を追加
  end


#以下略
```

```ruby
sleep 0.1 
```
上記の記述はインスタンスを生成する処理に0.1秒待機させてread_timeoutのエラーを回避するための記述です。

![スクリーンショット 2021-01-22 12.59.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614674/b09b3509-1014-5d5f-7717-1f88deb45c08.png)


<h1>できたぁ！（悟空）</h1>



参考記事
https://abicky.net/2017/09/17/014241/

https://qiita.com/shun915a/items/e18f538be6221f929876
MCMCが上手くいく時といかない時

#はじめに
千葉大学/Nospareの[米倉](https://sites.google.com/site/shoutoyonekura/)です．今回はベイズ統計学でよく使われる，マルコフ連鎖モンテカルロ法（MCMC）が上手行く時・いかない時はどんな状況なのかを確認したいと思います．簡単化のために，ランダム・ウォーク・メトロポリス法を特に扱います．

#ランダム・ウォーク・メトロポリス法(RWM)
話に入る前に，最も簡単なMCMCの一つであるランダム・ウォーク・メトロポリス法(RWM)について確認します．

今，$\pi()$をターゲットとなる密度関数だとします．現在のポジション$x$を所与として，次のポジションの候補となる$y$を，$q(y\mid x)=q(x\mid y)$を満たす条件付き密度関数からサンプリングします．典型例は$q(y\mid x)=x+\epsilon$で，ここで$\epsilon$は$x$とは独立で同一な正規分布に従う確率変数です．

次にメトロポリス・ヘイスティング比$\alpha(y,x)=\frac{\pi(y)q(y\mid x)}{\pi(x)q(x\mid y)}=\frac{\pi(y)}{\pi(x)}$を計算します．

最後に$u$を区間$(0,1)$の一様分布からサンプリングし，$u$が$\alpha(y,x)$より大きかったら候補となった$y$を棄却して，$y=x$とします．逆に小さかったら採択して，$y=y$とします．

上の３個のステップを任意の$M$回繰り返すのが，RWMです．

#RWMが上手くいく条件
MCMCが上手くいく条件を「エルゴード性」といいます．MCMCの文脈におけるエルゴード性とは，平たく言うと，どんな初期分布からMCMCを始めても，ある程度の速さで発生させた乱数が事後分布に収束することをいいます．なので，MCMCのアルゴリズムがエルゴード的か否かが，数学的にそのMCMCが上手くいくかいかないかを保証するものとなります．

RWMの場合，RWMがエルゴード性を持つための「十分条件」はターゲットとなる分布の形に依存します．簡単化のためにターゲット$\pi()$は１次元の密度関数としましょう．この時，ある$x_{0}>0$と$a>0$と任意の$y\geq x\geq x_{0}$について，$$\frac{\pi(y)}{\pi(x)}\leq \exp(-a(y-x))$$と，同様に任意の$y\leq x\leq -x_{0}$に対して$$\frac{\pi(y)}{\pi(x)}\leq \exp(-a(x-y))$$が成立すると，RWMはエルゴード的（正しくは幾何エルゴード的）になることが知られています．

これはRWMがエルゴード性を持つためには，ターゲットとなる密度関数$\pi(x)$の裾は指数関数的に小さくなっていくことを要求していて，例えば<font color="Red">コーシー分布の様に裾が厚い分布に対しては，RWMはエルゴード的にならない</font>ことを意味しています．詳しくは [K. L. Mengersen and R. L. Tweedie (1996)](https://projecteuclid.org/euclid.aos/1033066201)を例えば参照してみてください．


#数値実験
数学的なことをみてきたので，最後に数値実験を通して理論が意味することを確認したいと思います．まずターゲットとして，$\pi(x)\propto \exp(-x^{2}/2)$と言う，標準正規分布に比例する密度を考えます．下の結果は異なる初期値$x_{0}=50,0$からRWMを用いてサンプリングを行った結果です．プロポーサル密度には標準正規分布を用いました．図から分かる通り，どんなに外れた点(分布の裾)から初めても$0$付近にきちんと収束することが分かります．このことは発生させたサンプルのヒストグラムと標準正規分布の密度関数を重ね合わせても，きちんと動いていることが分かります．![Screenshot (171).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1040197/ca1b0697-1fd7-f883-03c0-f9911dea567e.png)

次にターゲットを$\pi(x)\propto \frac{1}{1+\mid x \mid^{1.1}}$と言う，コーシー分布っぽい裾の厚い分布に比例するものを考えて，先ほどと同じようにRWMを用いてサンプリングを行います．そうすると，先ほどとは対照的に発生させた乱数はランダムウォークの様なふるまいをみせて，全く収束しないことが分かります．ヒストグラムと密度関数を重ねても，全く動いていなことが分かります．
![Screenshot (170).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1040197/0b0db879-71f8-d1ae-d084-03a7deed84ba.png)

#おわりに
ベイズ推定を行う際にMCMCを用いてサンプリングを行うことが非常に多いと思いますが，上手くいく・いかないはターゲットの形状と用いるMCMCの種類に依存します．やみくもに用いるのではなく，データをプロットして形状を把握したり，適切なMCMCサンプラーを用いるための（高度な）知識が必要不可欠です．株式会社Nospareでは統計学の様々な分野を専門とする研究者が所属しております．統計アドバイザリーやビジネスデータの分析につきましては[株式会社Nospare](https://bit.ly/38WtGZH) までお問い合わせください．
<a href="https://bit.ly/38WtGZH">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1023506/d5c625c0-d6f4-680b-d702-3c40f11d6c39.jpeg" alt="株式会社Nospare" width=400>
</a>
【Model I/O】MDLMeshオブジェクトから頂点データを取得する方法

Model I/Oフレームワークの、MDLMeshオブジェクトから頂点の情報を取得するのが面倒だったので、メモ。

参考：
Read vertex positions with Model I/O
https://gist.github.com/algal/8e31ce035af0aafebc3736661ae9e3cd

mdlMeshにMDLMeshオブジェクトの値が入っているとして、これをXcodeのデバッガ(LLDB）上で取得したい場合。

頂点の数を取得する。

```swift:デバッガ
po mdlMesh.vertexCount
// 出力結果：54
```

バッファのデータのstrideを確認する。

```swift:デバッガ
po mdlMesh.vertexDescriptor.layouts.filter {($0 as! MDLVertexBufferLayout).stride != 0}
// 出力結果：
// ▿ 1 element
//   - 0 : <MDLVertexBufferLayout: 0x2824e4490 stride=32>
```

strideは32であることがわかった。

次のコードで、fromByteOffsetにオフセットを与えると頂点の情報が確認できる
n番目の要素を得たいときは、n * strideで取得できる。例えば2番目の要素を取得したいときは2*32を与える・

```swift:デバッガ
po mdlMesh.vertexBuffers.first!.map().bytes.load(fromByteOffset: 1*32, as: Float3.self)
// 出力結果：
// ▿ SIMD3<Float>(0.5, 0.5, 0.5)
//   ▿ _storage : SIMD4Storage
//     - _value : (Opaque Value)
```

2番目の頂点の座標は、x = 0.5, y = 0.5, z = 0.5であることがわかった。

### 最後に

NoteではiOS開発、とくにCoreML、ARKit、Metalなどについて定期的に発信しています。
https://note.com/tokyoyoshida

Twitterでも発信しています。
https://twitter.com/jugemjugemjugem
heroku　Method Not Allowed



<h1>Rails-Tutorial</h1>

rails-tutorialのherokuにデプロイするところで躓きました。

<b>開発環境</b>
AWS cloud9

----
<b>実行したこと</b>

```
ec2-user:~/environment/hello_app (master) $ heroku keys:add
? Which SSH key would you like to upload? /home/ec2-user/.ssh/id_rsa.pub
Uploading /home/ec2-user/.ssh/id_rsa.pub SSH key... done
ec2-user:~/environment/hello_app (master) $ heroku create                         
Creating app... done, ⬢ shrouded-beach-44231
https://shrouded-beach-44231.herokuapp.com/ | https://git.heroku.com/shrouded-beach-44231.git
ec2-user:~/environment/hello_app (master) $ git push heroku master
error: src refspec master does not match any.
error: failed to push some refs to 'https://git.heroku.com/frozen-citadel-28797.git'
```
rails-tutorialの手順通りに進めたつもりだったが
途中でSSH鍵間違えたり、heroku createを2回やったりでうまくいかなかった。

----

<b>解決方法</b>

・まず、herokuにログインして度重なるheroku createで作ってしまった不要なアプリを削除。
.新しく ```$ heroku create``` 
・git remote -vでURLを確認したらぐちゃぐちゃだったので```$ git remote set-url heroku <URL>```で住所変更。 
・次に、git addもcommitもpushもしていないといけないことを知り、コマンド実行
1 ```$ git init```
2 ```$ git add -A```      例:送りたい荷物を決める
3```$ git commit -m "first commit"```  例:送りたい荷物の梱包
4```$ git push -u origin master``` 例:荷物の発送

という感じでやってみました。

その後herokuをpush

```$ git push heroku master```

最後に ``$ heroku open ``でデプロイできているか確認。


----
補足

heroku createの前に

```$ heroku login --interactive```
```$ heroku keys:add```
以上をする必要もあるみたいです。
単体テストのエラー　〜ActiveRecord::RecordInvalid:        Validation failed: Email has already been taken〜

単体テストして変なエラーが出たので備忘録として残しておきます

<h1>結論</h1>
<h3>「そのメールは既に登録されているよ」って怒られてます。</h3>
この時僕はFakerでメールを作らずに手入力で入れていてのでテスト内でuserが何度も作成されるにあたって手動で入れてしまうとメールが重複してしまった、と言うことになります

以下コード

```ruby:fuctories/user.rb

FactoryBot.define do
  factory :user do
      nickname                 {"tarou"}
      email                    {"sanple.sample@com"}
#emailを以下に変更⬇︎
      email                    {Faker::Internet.free_email}
#emailを上記に変更⬆︎
      password                 {"a1234567"}
      password_confirmation    {"a1234567"}
      last_name                {"山田"}
      last_name_kana           {"ヤマダ"}
      first_name               {"太郎"}
      first_name_kana          {"タロウ"}
      birthday                 {"2000-01-01"}
  end
end
```
【Julia入門】JuliaでRDatasets.jlしてMLLabelUtils.jlを活用しつつXGBoost.jlする

#概要
irisをxgboostする意義はありません。

#環境
julia version 1.5.3
  "RDatasets"      => v"0.7.3"
  "MLLabelUtils"   => v"0.5.5"
  "XGBoost"        => v"1.1.1"

```julia
>import Pkg.add.(["RDatasets", "MLLabelUtils", "XGBoost"])
```
（Plutoでやりました）

#データセット準備

```julia
using RDatasets
iris = dataset("datasets", "iris")

train_Y = convertlabel(LabelEnc.Indices{Int},iris.Species) #Speciesをlabel encoding

train_X = select!(iris, Not(:Species)) #Speciesを抜く
train_X = convert(Matrix,train_X) #arrayに

```

#XGBoost

```julia
bst = xgboost(train_X, num_round = 2, label = train_Y, eta = 1, max_depth = 2)
pred = predict(bst, train_X)
```
完

#Julia基礎
##変数型確認
```julia
> typeof(array)
Array{Float64,1}
```
##arrayの長さ
```julia
> size(array)[1]
150
```
##unique
```julia
> unique(array)
Int64[1,2,3]
```
##count
```julia
> countmap(array)
Dict(2⇒50,3⇒50,1⇒50)
```
##arrayの中から特定の値を数える
```julia
> length(array[array .> 2.5])
50
```
##array各要素にround
```julia
> array1 = [round.(x) for x in array]
```
##dataframeからcolumnをarrayで抜く
```julia
> df.column_name
```
##train_test_split
```julia
> using MLDataUtils
> train, test = splitobs(X, at = 0.7)
```
EC-CUBE4 をDocker Composeでローカルに立てるメモ

EC CubeとかDockerとか触ったことない人が、少し苦戦しながらローカルに立てて、
一通り動く状態にする迄のメモ。
# 環境
Windows 10 Home

# 手順
### Dockerのインストール
まず、Dockerhubというサイトにサインアップ
https://hub.docker.com/

このサイトでは、docker imageをダウンロードしたり、
アップロードしたりできる様だ。

からの、Docker for Windowsのダウンロード⇒インストール
https://www.docker.com/products/docker-desktop

インストーラーでも何も設定変えずに進めたら、
途中、Windows components for WSL 2のインストール作業があり、
手作業でダウンロード⇒インストールしたところがあった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/017f6061-da57-183d-c187-3b4a34f20494.png)

まあ、上記ダイヤログ読んでやれば大した作業ではない。
インストーラの設定時に、[Install required Windows components for WSL 2] の行のチェック外すべきだったのかもしれないけど、
別にその後の作業に大きな支障は無かった。

インストール完了すると、
DockerのTutorial？みないなのが自動的に始まった。
やってもやらなくてもよさそうだったけど、初めて使ったので一応やっといてよかったと思う。

ま、これで一旦Dockerはオッケー。
（ #ちなみにこの状態で既にDocker Composeも入ってた。）

### Docker ComposeでEC-CUBEのコンテナを立てる
概ねは公式ページの[開発者向けインストール方法 4. Docker Composeを使用してインストールする](https://doc4.ec-cube.net/quickstart_install#4docker-compose%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)に沿って行けばいける。

まずは、githubからEC-CUBE4のソースをclone。
リポジトリ⇒　https://github.com/EC-CUBE/ec-cube

今回はPostgreSQLを使用したかったので、ルートフォルダ直下にあるenvファイルを下記の様に書き換える

```
DATABASE_URL=postgres://dbuser:secret@postgres/eccubedb
```

また、メール送信もしたいので同ファイルを下記の様に書き換える

```
MAILER_URL=smtp://mailcatcher:1025
```

したら、ルートフォルダにて、下記コマンドでコンテナ起動からインストールスクリプトの実行

```
# コンテナの起動 (初回のみビルド処理あり)
docker-compose up -d

# 初回はインストールスクリプトを実行( **`www-data` ユーザで実行する点に注意！** )
docker-compose exec -u www-data ec-cube bin/console eccube:install
```

インストールスクリプトを実行すると、
DBやMailのURIを聞いてくるので、そこは先ほどenvに先ほど設定した内容を見て
書き込んでいくと、DB作成したりして初期化してくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/68774545-de5e-d6cd-5413-bd4beb86d875.png)


これでサイトは動く状態になっている。

### サイトを動かしてみる
https://localhost:4430/
にアクセスするとトップページが表示される↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/f621ce08-db4d-fb9d-bb30-76e2f0739b5f.png)

https://localhost:4430/admin/login
にアクセスすると管理画面へのログインページが表示されるので
デフォルト設定のIPASS（ID: admin、password: password）を入力すれば認証が通り管理画面が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/3a551a4d-8d58-5d88-bc6a-e798f1b23840.png)

で、ユーザーの新規登録が出来るかもやってみた。
一回管理者からログアウトして、
トップページ右上にある新規登録画面からユーザー情報を登録して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/1866de6d-3236-dbdd-89d0-d22e58a24541.png)

その後の確認画面も進めていくと仮登録が出来て下記の画面が出て、メールが飛ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/04f50abe-d80e-0cfd-a5f2-99725bf94021.png)

で、この確認メールが先ほどのDocker Composeで立てたMailMather（http://127.0.0.1:1080/）に届く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/9bf72887-9039-e5d8-0040-1791764f3189.png)

メール本文内のリンク押下してやれば、登録完了画面が出る↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504562/ce5fc5df-d643-ad51-3c6b-b286ac2e199f.png)



一旦、こんな感じで。
以上、どどん。
Jesus the God particle

Christ the God particle.
If you have read some of my ways of explaining concepts in physics in simple terms you have heard me use a square and a circle to explain supersymmetry.
![Jesus is our creator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/950107/37d3417c-2388-9808-463c-37ef4bff85af.png)
  
Why do I explain supersymmetry as the change of a circle to a square. It seems like this is a contradiction.  

Supersymmetry is turning one shape into another shape. As you can see we can fit a square inside a circle but there is always “stuff” leftover. The stuff left over is mass. 
“Supersymmetry is a scientific theory that says that when elementary particles (such as photons, electrons, and quarks) were formed at the beginning of the universe, matching kinds of theoretical "superparticles" were also created”
What this means is we need a beginning particle that turns into another particle. Photons to electrons to quarks. What's the problem? All these particles have different properties, photons have (+) charge and electrons (-), they have different masses. 
There is a mystery if you like to use terms of excitement: Please see the following link. https://www.youtube.com/watch?v=BYRz_9wvJzA
The increase of mass as a total and as its components. 
It is possible to gain or lose mass on the binding process so it might be possible to at least gain or lose mass. Why this happens? So say it is a different energy state others like me say who knows. 
The higgs is another mysterious event. There is a difference between the Higgs boson, the higgs field and the Higgs. See link https://www.youtube.com/watch?v=joTKd5j3mzk.
"Scientists believe that almost all of your body's mass comes from the kinetic energy of the quarks and the binding energy of the gluons." The bible declares 
“Genesis 1:4 And God saw that the light was good. And God separated the light from the darkness.”
Creation points to a creator. Please ask God for forgiveness and read the bible.             


Works Cited
“Photon.” Wikipedia, Wikimedia Foundation, 5 Jan. 2021, en.wikipedia.org/wiki/Photon.
Silverberg, Larry M. “Fragments of Energy-Not Waves or Particles-May Be the Fundamental Building Blocks of the Universe.” Phys.org, Phys.org, 10 Dec. 2020, phys.org/news/2020-12-fragments-energynot-particlesmay-fundamental-blocks.html.
Silverberg, Larry M. “Fragments of Energy-Not Waves or Particles-May Be the Fundamental Building Blocks of the Universe.” Phys.org, Phys.org, 10 Dec. 2020, phys.org/news/2020-12-fragments-energynot-particlesmay-fundamental-blocks.html.
“Supersymmetry.” Wikipedia, Wikimedia Foundation, 17 May 2018, simple.wikipedia.org/wiki/Supersymmetry.
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
Dockerいれてみた　

# サーバの用意

まずはさくらにログインして最小構成でUbuntu選んで適当にサーバ作る

## ユーザの作成
作成完了したら、デフォルトのユーザでログイン後、
`adduser USER`
を実行してユーザを作成する。


# dockerインストール
参考）公式
https://docs.docker.com/engine/install/ubuntu/

```bash

apt-get update

sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo apt-key fingerprint 0EBFCD88

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

sudo apt-get install docker-ce docker-ce-cli containerd.io
```

ここまでやればdocker使えるようになる


ちなみにdockerコマンドをsudoしないで使いたいなら
dockerグループにユーザ追加すればOK
cakephp4 - find('list') キー/値のペア出力で値を配列にする


\<select> エレメントを生成するfind('list')を使う際に、出力する値を配列にしたい場合。

###### キー/値のペア出力

```php:SampleController.php
$query = $articles->find('list', [
    'keyField' => 'slug',
    'valueField' => 'title'
]);
$data = $query->toArray();
```

参考:https://book.cakephp.org/3/ja/orm/retrieving-data-and-resultsets.html

###### キー/値(配列)のペア出力

```php:SampleController.php
$query = $articles->find('list', [
     'keyField' => 'slug',
     'valueField' => function ($entity){
                       return [
                          'id' => $entity->id,
                          'title' => $entity->title,
                        ];}
]);
$data = $query->toArray();
```
ssh公開鍵認証を使ってサーバにアクセスできるようにする


# ローカルで実行
ローカルマシンでおもむろに

```
ssh-keygen -t rsa -b 4096
```

を実行すると、下記のようになる

```
Enter file in which to save the key (/Users/USER/.ssh/id_rsa): 
```

証明書ファイルを保存したい場所、名前（既に存在すると上書きされる）を入力

```
/Users/USER/.ssh/sshpem/id_HOGEHOGE
```

Enterすれば、入力したところにファイルができる

```
id_HOGEHOGE
id_HOGEHOGE.pub
```

pubのほうをコピー

# サーバで実行
これ実行して（初回のみ）

```
mkdir ~/.ssh && chmod 700 ~/.ssh && touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
```

```
vi ~/.ssh/authorized_keys
```

してコピーしたやつ貼っつけておわり
ローカルで

```
ssh -i ~/.ssh/sshpem/id_HOGEHOGE USER@SAKURA_IP
```

すればつながる

つながることを確認したら、サーバで

```
sudo vi /etc/ssh/sshd_config

+PasswordAuthentication no
```

追加して

```
service sshd restart
```

するとパスワード認証OFFになる（証明書ファイル無いとログインできない）
CentOS Stream 8で日本語化した

conoHaVPSで環境構築をはじめたのですが、
ブラウザで文字化けするし、Failed to set locale, defaulting to C.UTF-8ってエラーが出るしで、よくわからんので、日本語化しました。

<h2>環境</h2>

CentOS Stream 8
(ちなみに、CentOS7.9を入れるところ、間違ってCentOS Stream 8を入れてしまったのがそもそもの間違い。。。)

<h2>日本語化までの流れ</h2>

~~~Bash:ロケールの確認
$ localectl

 System Locale: LANG=en_US.UTF-8
      VC Keymap: jp
      X11 Layout: jp
~~~
en_USをja_JPに変えたいので、ロケールの変更。

~~~Bash:ロケールの変更
$ localectl set-locale LANG=ja_JP.UTF-8
failed to set locale!
~~~

設定できない。

ロケールのチェック。

~~~Bash:インストールされてるロケールを確認
$ locale -a

C
C.utf8
POSIX
en_AG
en_AU
en_AU.utf8
en_BW
en_BW.utf8
en_CA
en_CA.utf8
en_DK
en_DK.utf8
en_GB
en_GB.iso885915
en_GB.utf8
en_HK
en_HK.utf8
en_IE
en_IE.utf8
en_IE@euro
en_IL
en_IN
en_NG
en_NZ
en_NZ.utf8
en_PH
en_PH.utf8
en_SC.utf8
en_SG
en_SG.utf8
en_US
en_US.iso885915
en_US.utf8
en_ZA
en_ZA.utf8
en_ZM
en_ZW
en_ZW.utf8
~~~

jaに関するものが一つもない。
ということで、日本語パッケージインストール。

~~~Bash
$yum install glibc-langpack-ja
~~~

再度、インストールされているロケールを確認。

~~~Bash
$ localectl list-locales | grep -i ja
ja_JP.UTF-8
ja_JP.eucjp
ja_JP.utf8
~~~
入りました！
もう一度、ロケールの設定。

~~~Bash
$ localectl set-locale LANG=ja_JP.UTF-8
~~~

~~~Bash:確認
$ localectl
   System Locale: LANG=ja_JP.UTF-8
      VC Keymap: jp
      X11 Layout: jp
#成功！
~~~
CentOS 7系で動かしているZabbix 4.0をZabbix 5.0へアップデートする

# このページに書かれていること

CentOS 7標準のRPMパッケージのミドルウェアApache + PHP 5.4で、Zabbix社公式リポジトリからインストールしたZabbix Server 4.0系 + Webフロントエンドを構築している環境にて、Zabbix Server 5.0系にアップデートする手順について簡単にまとめました。
（CentOS 7へZabbix 5.0系の新規インストール手順は見つかったのですが、4.0系→5.0系の手順があまり見当たりませんでしたので）

## 注意点

作業途中でZabbix Serverを停止させます。その間のZabbix Serverに送られてくる監視データは破棄されるという前提を頭に置いてから実施してください。

Zabbixはメジャーアップデートを行うと、DBのスキーマが更新されます。そのため5.0へのアップデートした後に不具合があり、4.0に戻そうとしたときにパッケージだけを戻しても正常に機能しないことが起こり得ます。
そのため、DBのバックアップ・リストアを含め十分に試験を行ってから本番環境で実施することをお勧めします。

Zabbix Proxyも併用している環境の場合、Zabbix ServerとProxyはメジャーバージョンを揃えないといけません。
本ページでは記載しておりませんがZabbix Proxyのアップデートについても一連の作業手順として予定してください。

このページの情報を鵜呑みにせず、公式ドキュメントを参考の上、ご自身が作業内容を理解した上で実施してください。
[Zabbix社アップデート手順公式ドキュメント](https://www.zabbix.com/documentation/5.0/manual/installation/upgrade/packages/rhel_centos)

## 作業前の環境

- CentOS 7.0系
- Apache 2.4系 （CentOS 7系標準RPMパッケージ）
- PHP 5.4系 （CentOS 7系標準RPMパッケージでmod_phpとして稼働）
- MariaDB 5.5系 （CentOS 7系標準RPMパッケージ）
- Zabbix Server 4.0系 + Webフロントエンド （Zabbix社公式リポジトリよりyumでインストール）

## 作業後の環境

Zabbix (/usr/share/zabbix/以下) のPHPは、sclリポジトリ管理のphp-fpmのPHP 7.2で稼働することになります。
そのためApacheが稼働していても、php-fpmが稼働していないとZabbixのWebフロントエンドが表示されません（mod_phpの環境になれている方は注意が必要です）。
他のディレクトリについては作業前の環境（mod_phpのPHP 5.4）のままになります。

# 移行手順

### バックアップ

/usr/share/以下のバックアップについては、当該ディレクトリ以下のファイルを手で書き換えていない限りは必要ない気もしますが、Zabbix社のドキュメントにありますので念のため実施します。


```
# mkdir /opt/zabbix-backup/
# systemctl stop zabbix-server
# cp /etc/zabbix/zabbix_server.conf /opt/zabbix-backup/
# cp /etc/httpd/conf.d/zabbix.conf  /opt/zabbix-backup/
# cp -R /usr/share/zabbix/ /opt/zabbix-backup/
# cp -R /usr/share/doc/zabbix-* /opt/zabbix-backup/
# mysqldump -u ${USERNAME} -p -h ${HOSTNAME} ${DBNAME} > /opt/zabbix-backup/zabbix-db-backup.sql
```

### アップデート

```
# yum update https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
# yum install centos-release-scl epel-release
# yum-config-manager --enable zabbix-frontend epel
# yum clean all
# yum upgrade zabbix-server-mysql
# systemctl start zabbix-server
# yum remove zabbix-web-* 
# yum install zabbix-web-mysql-scl zabbix-web-japanese zabbix-apache-conf-scl
# systemctl start rh-php72-php-fpm
# systemctl enable rh-php72-php-fpm
# systemctl restart httpd
# yum -y upgrade zabbix\*

# vi /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf

以下を追加
php_value[date.timezone] = Asia/Tokyo
```

# 備考

初めてのQiitaへの投稿になります。お見苦しい点等ございましたら、コメントにてご指摘いただければ幸いです。
また私の手元の環境ではうまくいっておりますが、うまくいかない点などございましたら、こちらもコメントにてお教えいただければ幸いです。
（私が分かる範囲であればコメント、記事の修正等させていただきます）
OCIでの制御ファイルの名前変更とコピー

# 制御ファイルの追加コピーの作成、名前変更および再配置
OCI DBaaS-VM環境にて19c環境で初めて制御ファイルの設定変更をしたので、その備忘録。
環境はSPFILE運用で、ASMを使用。

まずは[マニュアル](https://docs.oracle.com/cd/E96517_01/admin/managing-control-files.html#GUID-9C41ADFB-5A26-4FFB-8582-41A33B2F5C53)の記載を読み、これまでと大きな違いがないことを確認。

```
10.3.2 制御ファイルの追加コピーの作成、名前変更および再配置
多重化のために制御ファイルのコピーを追加作成するには、既存の制御ファイルを新しい位置にコピーし、
そのファイル名を制御ファイルのリストに追加します。

同様に、制御ファイルの名前を変更するには、既存の制御ファイルを新しい名前や位置にコピーし、
制御ファイル・リストのファイル名を変更します。
どちらの場合も、作業中に制御ファイルが変更されないように、
制御ファイルをコピーする前にデータベースを停止してください。

現行の制御ファイルの多重化コピーを追加、または制御ファイル名を変更するには:
　1.データベースを停止します。
　2.オペレーティング・システムのコマンドを使用して、
　  既存の制御ファイルを新しい位置にコピーします。
　3.データベース初期化パラメータ・ファイルのCONTROL_FILESパラメータを編集して、
　  新しい制御ファイル名を追加するか、または既存の制御ファイル名を変更します。
　4.データベースを再起動します。
```
実際の対応手順は以下

## 対応手順

### １．SQL*Plusに接続後、移動前の配置確認
```
SQL> show parameter control_files
```

### ２．SPFILEのcontrol_filesパラメータを変更
```
SQL> alter system set control_files
  2> ='+RECO/TESTDB01_NRT1BS/CONTROLFILE/control01.ctl'
  3> ,'+DATA/TESTDB01_NRT1BS/CONTROLFILE/control02.ctl' 
  4> scope=spfile;
```

### ３．DBのシャットダウン
```
SQL> shutdown immediate
SQL> exit
```

### ４．ASM側で操作をするため、gridユーザーにスイッチしてASMCMDで制御ファイルをコピー
```
-- +DATA配下CONTOROLFILEディレクトリについては、
-- デフォルトでは存在しないので、手動で作成する。
ASMCMD> cd DATA
ASMCMD> cd TESTDB01_NRT1BS
ASMCMD> mkdir CONTOROLFILE
ASMCMD> ls

-- 1つ目の制御ファイルのコピー
ASMCMD> ls -lt +RECO/TESTDB01_NRT1BS/CONTROLFILE
ASMCMD> cp +RECO/TESTDB01_NRT1BS/CONTROLFILE/<制御ファイル名> +RECO/TESTDB01_NRT1BS/CONTROLFILE/control01.ctl
ASMCMD> ls -lt +RECO/TESTDB01_NRT1BS/CONTROLFILE

-- 2つ目の制御ファイルのコピー
ASMCMD> ls -lt +DATA/TESTDB01_NRT1BS/CONTROLFILE
ASMCMD> cp +RECO/TESTDB01_NRT1BS/CONTROLFILE/<制御ファイル名> +DATA/TESTDB01_NRT1BS/CONTROLFILE/control02.ctl
ASMCMD> ls -lt +DATA/TESTDB01_NRT1BS/CONTROLFILE
ASMCMD> exit
```

## ５．oracleユーザーへスイッチしてDBを起動し、変更後の確認
```
-- SQL*Plusへの接続と起動
$ sqlplus /as sysdba
SQL> startup
SQL> show pdbs
SQL> show parameter control_files
```
使用したライブラリ等　※自分用

###talend API
chromeのcurl(対抗API)の実施するツール

basic認証で聞かれる場合は、add authrizationに登録すれば都度聞かれずにすむ

###postman
jsonの整形するツール

###datadog
logの出力

###testcafe
画面を叩くソースツール

###snipingtool
windows標準のエビデンスツール

###tweak mock API calls(chromeのツール)
スタブやAPIをchromeにて期待値を返却するようにする
これは、皆が共有してスタブを使用している際に、自分だけ
返却値を修正する必要があるときに有効である。
BlackHoleを使って動画・音声を配信してみよう

[BlackHole](https://github.com/ExistentialAudio/BlackHole)を使い、Mac上で再生している動画の映像・音声をZoomやTeamsなどの会議ツールで配信するための手順です。

配信中に自分の音声も載せたい！という方は別な記事を参考にしてください。

## 実現したいこと
* QuickTimeなどで再生した動画の映像・音声を、TeamsやZoomでも配信できるようにしたい。
* ただ、再生中何も聞こえないと退屈。
* なので自分のMacからも音声を聴こえるようにしたい。

動画の映像と音声を配信したければ、BlackHoleを使うと簡単にできます。

## BlackHoleとは？
BlackHoleは仮想オーディオドライバです。
インストールすると、あるアプリケーションで再生した音声を別なアプリケーションの入力として扱えるようになります。

> BlackHole is a modern MacOS virtual audio driver that allows applications to pass audio to other applications with zero additional latency. 
> [ExistentialAudio/BlackHole](https://github.com/ExistentialAudio/BlackHole) から引用


## 完成イメージ
下の手順を完了すると、QuickTimeなどの映像・音声をZoomやTeamsなどに配信できる形になります。
![スクリーンショット 2021-01-22 11.09.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30970/71bac18d-4213-e3d4-ca5a-48d442717ba9.png)

## インストールとセットアップ

### BlackHoleのインストール
[BlackHole](https://github.com/ExistentialAudio/BlackHole)の手順に従ってインストールします。

### 複数出力装置のセットアップ
動作の再生中にスピーカーから音声が聞こえるようにするため、複数出力装置を設定します。
今回はMacの内蔵スピーカーから出力できるよう設定します。

`Audio Midi設定.app`を起動し、「複数出力装置」を追加します。

![multi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30970/95c5c79b-f8f4-e154-71f0-5ee33d93ea0b.png)

追加後、以下の通り設定します。

1. 一覧中の`BlackHole`の「使用」にチェック
2. 「マスター装置」に「内蔵出力」を選択

![midi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30970/981e3346-437b-e350-664b-ecde05c613bc.png)

外部スピーカーを使いたい場合は適宜設定を変えてみてください。

## 配信してみよう
### システムの音声を複数出力装置に変更
音声の出力ソースを上で作った複数出力装置に変更します。
`System Prefrence.app`の「サウンド」などで変えてみましょう

![preference.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30970/e6a92dd5-c767-ff1b-4956-4dffb48a15ac.png)

### 配信側のツールで音声の入力ソースを変更
ZoomやTeamsで、音声の入力ソースを`BlackHole`に変更します。

ここまで終わらせて動画を再生すると、通話先の人に動画を配信できます。
OpenJDKコンテナにDockerを追加

```Dockerfile
FROM openjdk:8-jdk

RUN apt-get update -qq && apt-get install -qqy \
    apt-transport-https \
    ca-certificates \
    curl \
    lxc \
    iptables
    
RUN curl -sSL https://get.docker.com/ | sh

CMD service docker start && /bin/bash
```
LaravelでDBに保存した画像を表示する方法

#はじめに
前回Laravelで画像のパスをDBに保存する方法をご紹介したので、今回は画像を表示する方法関してご紹介していきたいと思います。

保存する方法に関しては以下の記事をご参考ください。
[Laravelで画像をアップロードし、パスをDBに保存する方法](https://qiita.com/yuzuyuzu0830/items/2bc982516a513a95cb06)

こちらでは、画像のパスがすでにDBに保存されている前提で進めており、ファイル名等は全て前回作成したものを利用していきます。

-各バージョン
-laravel 6.x
-PHP 7.4.9
-mySQL 5.7.30

#コントローラーを記述する
今回はindexアクションを使っていきたいと思います。

DBファザード使用するため、useで宣言し、そのあとに書いていきます。

```PHP:BookController
use Illuminate\Support\Facades\DB;

public function index()
{
  $books = DB::table('books')->orderBy('created_at', 'desc')->get();

  return view('index', compact('books'));
}
```

まず、前回作成したbooksテーブルのデータを取得し、`orderBy()`で`created_at`、つまり作成した日時を`desc`順に並べるように指定しています。`desc`とはdescendの略で、下に降りるという意味になるので、指定することによって作成した日時が新しいものが先頭に来るようになります。
そして取得したものを`$books`という変数に格納しています。

続いて格納したものを`return`でビューに渡すようにします。
`index.blade.php`というビューをこのあと作成するので、`index`を指定し、`compact()`メソッドで変数をビューに渡すことができるようになっています。`compact()`を使用するときは$マークはつけずに記述して問題ありません。

また、今回はデータが少ないため全てのデータを取得していますが、もしデータが多く一覧画面では一部のデータのみ表示させたい場合は、以下のように書くこともできます。

```PHP:BookController
use Illuminate\Support\Facades\DB;

public function index()
{
  $books = DB::table('books')
  ->select('id','title', 'author', 'created_at') //ここを追加
  ->orderBy('created_at', 'desc')
  ->get();

  return view('index', compact('books'));
}
```
`select()`でデータを選択することができるので、表示したいカラム名を指定することができます。
この場合は別途、全てのデータを表示する画面を作成するといいでしょう。

#ビューを作成する
新しくデータを表示するindex.blade.phpを作成し、一覧を表示させるコードを書いていきます。
なお、今回はデータが少ないので全てのデータが表示されるようにしていきます。

```php:index.blade.php
@foreach('books' as 'book')
  <table>
    <tr>
      <th>タイトル</th><td>{{ $book->title }}</td>
    </tr>
    <tr>
      <th>作者</th><td>{{ $book->author }}</td>
    </tr>
    <tr>
      <th>投稿日</th><td>{{ $book->created_at }}</td>
    </tr>
    <tr>
      <th>画像</th><td><img src="{{ asset('uploads/books/' . $book->image) }}" alt="book-image"></td>
    </tr>
  </table>
＠endforeach
```

BookControllerでbooksテーブルのデータを`$books`に格納しているので、データを`foreach`で回して表示するようにしています。
画像に関しては、DBには画像のパスしか保存されていないため、画像の保存先を指定する必要があります。画像は前回Publicフォルダ内のuploads/booksに保存したので、今回はそのように指定しています。
また、見えやすくするように`table`を使用しましたが、便宜に合わせて`ul`や`p`タグで表示することも可能です。

#ルーティングを指定する
index.blade.phpに接続したら、BookController内のindexアクションが起動するようにします。

```php:web.php
Route::get('index', 'BookController@index')->name('index');
```
以上で完成です！

#さいごに
今回はDBに保存している画像のパスを表示させる方法に関して解説しました。

もっとこういうやり方あるよーという場合は、やさしくコメントで教えていただけるとありがたいです！
ここまで読んでくださりありがとうございました！

##参考
[Laravel Image CRUD : How to fetch the image in Laravel](https://youtu.be/C6bvvVimwAc)
DynamoDB Localで同一のハッシュキーが出来てしまった場合の対処法

DynamoDB Localを利用していると極稀に同一のハッシュキーのレコードが2重に作成されテーブルへのアクセスが不能な状態に陥ってしまう時があります。

重複エラー状態になった時の対処法はテーブルの再作成またはDynamoDB Local内のDBを直接操作して該当レコードを削除するで対処できます。

### テーブルの再作成

データが全部消えても問題ない場合はテーブルを一度削除して再作成するのが手っ取り早い解決法になるかと思います。

テーブルの削除

```shell
$ aws dynamodb delete-table --table-name TARGET_TABLE
```

テーブルの作成

```shell
$ aws dynamodb create-table --table-name TARGET_TABLE ...その他オプション省略
```

### DynamoDB Local内のDBを直接操作する

DynamoDB LocalのバックエンドはただのSQLiteのため、shellログインして直接SQLiteのレコードを操作して修正します。

```shell
$ docker exec local-dynamodb /bin/bash
または
$ docker-compose exec local-dynamodb /bin/bash
```

shellログインしたhomeディレクトリにSQLiteのdbは存在します。

```shell
$ ls -l
-rw-r--r-- 1 dynamodblocal dynamodblocal 19919872 Jan 22 01:06 AKIAXXXXXXXXXXXXXXX1_ap-northeast-1.db
-rw-r--r-- 1 dynamodblocal dynamodblocal  2527232 Jan 22 01:06 AKIAXXXXXXXXXXXXXXX2_ap-northeast-1.db
-rw-r--r-- 1 root          root           3787546 May 29  2020 DynamoDBLocal.jar
drwxr-xr-x 2 root          root              4096 Aug 20 03:32 DynamoDBLocal_lib
-rw-r--r-- 1 root          root              8644 May 29  2020 LICENSE.txt
-rw-r--r-- 1 root          root              1856 May 29  2020 README.txt
...略
```

DynamoDB Localでテーブル作成時に設定したAWS AccessKeyとregionを繋げたdbが作成されているのでエラーが発生しているdbを選びsqliteコマンドで接続します。

今回は仮にAWS AccessKeyがAKIAXXXXXXXXXXXXXXX1でregionがap-northeast-1だとします。

```shell
$ sqlite AKIAXXXXXXXXXXXXXXX1_ap-northeast-1.db
```

tableのschema情報を見てみる

```sqlite
sqlite> .schema TARGET_TABLE
CREATE TABLE "TARGET_TABLE"(
  hashKey TEXT,
  ObjectJSON,
  itemSize INT,
  hashValue
);
CREATE INDEX "TARGET_TABLE*HVI" ON "TARGET_TABLE" (hashValue);
```

どのテーブルもhashKey, ObjectJSON, itemSize, hashValueの構成で出来ています。

実際に1件取得してみると以下のように格納されています(本当は | 区切りですが便宜上改行で区切りに編集しています)

```sqlite
sqlite> SELECT * FROM TARGET_TABLE LIMIT 1;
hash-key-value
{"value": {"N": 0},"updated_at":{"N":"1603954694880509"}}
74
jF
```

重複レコードを両方消したい場合は単純にhashKeyでselectしたレコードを削除します。

```sqlite
sqlite> DELETE FROM TARGET_TABLE WHERE hashKey = 'HASH-KEY'
```

重複レコードどちらでもいいのでとにかく1件だけ削除したい場合は以下のクエリーを実行します。

```sqlite
sqlite> DELETE FROM TARGET_TABLE WHERE hashKey IN (SELECT hashKey FROM TARGET_TABLE WHERE = 'HASH-KEY' LIMIT1)
```

何かしら差分が発生しており特定のレコードだけ削除したい場合はObjectJSONカラムに対してLIKE検索をして削除するといいかと思います。

```sqlite
sqlite> DELETE FROM TARGET_TABLE WHERE hashKey = 'HASH-KEY' AND ObjectJSON LIKE '%残って欲しくないレコードの値%';
```

以上、同様の問題で困っている方の参考になれば。
【Spring】TemplateInputExceptionが発生したとき

Springにおける開発時にTemplateInputExceptionが発生したときの対処方法


・htmlで定義しているオブジェクトに対して、Controllerクラス側でaddAttributeできているか。
・Controllerクラス側で定義しているオブジェクトを、html側で定義できているか。
【SwiftUI】SwiftUI Appで`window.rootViewController`を用いた初期画面の表示

# はじめに
アプリの初期画面を`window.rootViewController`を用いて表示することは採用したアーキテクチャにもよると思いますが、よくあることかと思います。
ただし、プロジェクト作成時に`Life Cycle`で`SwiftUI App`を選択した場合に少し実装が必要だったため記しておきます。

# 実装
`SwiftUI App`でプロジェクトを作成すると、以下のようなファイルが生成されます。
このままだと`ContentView`が初期表示画面になってしまいます。
例えば`Coordinator`や`Rooter`パターン等を利用したい場合は`AppDelegate`や`SceneDelegate`を経由したくなります。

```swift:SampleApp.swift
import SwiftUI

@main
struct SampleApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```

まず、`AppDelegate`と`SceneDelegate`をそれぞれ自分で作成します。
自作した`SceneDelegate`が呼び出されるような実装を`AppDelegate`にしていきます。

```swift:SceneDelegate.swift
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = SampleViewController()
            window.makeKeyAndVisible()
            self.window = window
        }
    }

}
```

```swift:AppDelegate.swift
import UIKit

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        let config = UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
        config.delegateClass = SceneDelegate.self
        return config
    }

}
```

これであとは、`AppDelegate`が呼び出されるようにするだけです。
`@UIApplicationDelegateAdaptor`を利用します。

```swift:SampleApp.swift
import SwiftUI

@main
struct SampleApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
        }
    }
}
```

これで、`SceneDelegate`で指定している`SampleViewController`が表示されるようになります。

# おわりに
そもそも`SwiftUI App`を選択しなければ良い話ですが、参考になる方がいればいいなと思います。
単純に起動時に処理がしたいだけであれば`ScenePhase`というものもあるようです。
https://developer.apple.com/documentation/swiftui/scenephase