OmniAICreator/Qiita-1.07M huggingface dataset:
Hololens開発環境構築_2020年5月

# この記事について
やんごとなき理由によってMRをやることになったので環境構築をしてみた
2019年版のQiita記事を見つけたが既に環境が変わってるっぽく応用が初心者の自分ではできなかったので一からやってみた

# 使うもの
1. Unity Hub
https://unity3d.com/jp/get-unity/download

2. MRTK Foundation
https://github.com/microsoft/MixedRealityToolkit-Unity/releases/tag/v2.3.0

3. Windows 10
4. やるき

# Unityのセットアップ
まず上記のURLからUnityHubをダウンロード
※UnityHubってなんじゃいって思いますがUnityはバージョン違いで既存Projectが動かなくなったりするのでそういう問題が起きないようにバージョンのコントロールなどをしてくれる存在

ダウンロードしたら開いてインストールカラムを選択
<img width="737" alt="Unity_Hub.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162318/a88de628-14a8-2f35-915e-b1b2ff2b9027.png">

インストールを押すとインストールするUnityを選択できるので利用したいverを選択し、次へ次にモジュールを選択する。まぁ必要なの勝手に選択されてるので何もせず次を選べばインストールが始まる

これでUnityはいったんおｋ

# Windows10のセットアップ
次にWindows10側を開発モードにする
設定 > 更新とセキュリティ > 開発者向け　を選択
<img width="660" alt="develop.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162318/1711f431-d06a-0249-66bc-c68fed514eea.png">

ラジオボタンの開発者モードにチェックを入れる

これでUnity側のBuild SettingsのUniversal Windows Platform(UWP)の項目の内容が表示される

# Visual Studio Installerの修正
UnityをInstallした際に一緒に恐らくVisual Studio(Installer)もインストールされているはず
UWPの場合Unity -> VS -> Appみたいな流れでビルドしていくみたい
もしかしたらWindows10のセットアップまでで行ける人もいるかもしれないがwindow10SDKがない場合がある
またUnityとVSのバージョンが合わないなどでBuildができなかったりすることもある
なのでこの項目にも触れておく
VS Installerを開くとすでにインストール済みの場合このような表示になっているはず
<img width="962" alt="vscode.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162318/28e0b343-c949-8c84-bb77-fbfc519e1256.png">
変更をクリック
UWPの開発に必要なものにチェックをいれてインストールする
## ワークロード
C++によるデスクトップ開発
ユニバーサルWindowsプラットフォーム開発
Unityによるゲーム開発（ゲーム作らなきゃいらないかも？）

## 個別のコンポーネント
USBデバイスの接続
Windows10 SDK(versionは環境による）
この2点は追加で必要、あとはデフォルトで大丈夫

チェックすると画面右下に変更のボタンがあるのでクリックするとダウンロードとインストールが始まる

# Unity側MRTK利用設定
使うものの項目に記載したMRTKのダウンロードページに移動
最新のMRTKのバージョンでアセットを取得する
最低限Foundationをダウンロードすればいいです

ダウンロードしたらダブルクリックなりUnityへのドラッグアンドドロップやUnityで
Assets > Import Package > Custom Package
でインポートしてください
拡張子が独特なのでダブルクリックでスムーズに開かない気もします（開くプログラムを設定すればいい）

インポートすれば画面上部のツールバーにMixed Reality TookKitが追加されているはず
またインポート後にプロジェクトのセットアップのためにプロンプトが表示されることがあります。
推奨事項のようですのでApplyを選択しましょう

# Buildの設定
File > Build Settingsを開くとどの環境でのアプリを作るかを設定できます。
Univeresal Windows Platformを選択してください
ウィンドウ右下にswitch platformのボタンがあるのでクリックしてください
処理が完了するとBuild And Runのボタンが活性化するはずです

# プロジェクトの作成
ツールバーのMixed Reality TookKitのボタンをクリック
Add to Scene and Configureを選択するとHierarchyにSceneが追加されます。
あとはPlayを押せばBuildが実行されシンプルなアプリが動作します。
スペースを押すと手のシミュレーションが実行でき、左クリックでつまむ、右クリックしたままドラッグで視点の変更ができます。


# まとめ
上記の作業手順は自分が詰まったところ中心でまとめています
より詳しいやり方は
こちらをご覧ください
https://microsoft.github.io/MixedRealityToolkit-Unity/version/releases/2.3.0/Documentation/GettingStartedWithTheMRTK.html#switch-your-unity-project-to-the-target-platform
Property 'blur' does not exist on type 'EventTarget'.

onKeyDownでblurをしようと思ったらtypescriptでエラーが発生

エラーがでたコード

```tsx
target.blur();
```

targetがHTMLElementであることを指定してあげる必要があった。

```tsx

  const handleKeyDown = (evt: React.KeyboardEvent<HTMLInputElement>) => {
    const { keyCode, target } = evt;
    if (keyCode === 13) {
      (target as HTMLElement).blur();
    }
  };
```
GitHub ActionsでDockerコンテナのアクションを作成する

## 参考

- [Docker コンテナのアクションを作成する](https://help.github.com/ja/actions/building-actions/creating-a-docker-container-action#testing-out-your-action-in-a-workflow)
- [GitHub Actionsのメタデータ構文](https://help.github.com/ja/actions/building-actions/metadata-syntax-for-github-actions)

## 作業環境

* Ubuntu 18.04
    * git

## 内容
GitHub ActionsでDockerコンテナのアクションを作成する。
※ただの"やってみた"です。

* GitHubでリポジトリを作成する
* Dockerfileを作成する
* GitHub Actionsのメタデータファイルを作成する
* アクションコード（`entrypoint.sh`）を作成する
* GitHubへのコミットとタグをプッシュする
* ワークフローを作成する
* 実行結果を確認する

### GitHubでリポジトリを作成する
パブリックリポジトリを作成する。
リポジトリ名を、`hello-world-docker-action` とする。

### Dockerfileを作成する

* ファイル名：Dockerfile

```Dockerfile
FROM alpine:3.10
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
```

### GitHub Actionsのメタデータファイルを作成する

* ファイル名：action.yml

```yaml
name: 'Hello World.'
description: 'Greet someone and record the time'
inputs:
    who-to-greet:
        description: 'Who to greet'
        required: true
        default: 'World'
outputs:
    time:
        description: 'The time we greeted you'
runs:
    using: 'docker'
    image: 'Dockerfile'
    args:
        - ${{ inputs.who-to-greet }}
```

### アクションコード（entrypoint.sh）を作成する

* ファイル名：entrypoint.sh

```bash
#!/bin/sh -l

echo "Hello $1"
time=$(date)
echo "::set-output name=time::$time"
```

* 実行権限付与

```bash
chmod +x entrypoint.sh
```

### GitHubへのコミットとタグをプッシュする

```bash
git add action.yml entrypoint.sh Dockerfile README.md
git commit -m "My first action is ready"
git tag -a -m "My first action release" v1
git push --follow-tags
```

### ワークフローを作成する

* ファイル名：.github/workflows/main.yml

```yaml
on: [push]

jobs:
  hello_world_job:
    runs-on: ubuntu-latest
    name: A job to say hello
    steps:
    - name: Hello world action step
      id: hello
      uses: actions/hello-world-docker-action@v1
      with:
        who-to-greet: 'Mona the Octocat'
    # Use the output from the `hello` step
    - name: Get the output time
      run: echo "The time was ${{ steps.hello.outputs.time }}"
```

`uses: actions/hello-world-docker-action@v1` を、先ほどまで作成したリポジトリに置き換える。

### 実行結果を確認する

GitHubリポジトリの `Actions` タブをクリックして、最新のワークフロー実行結果を選択するとこのような結果をみることができる。

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


### 所感
公式ページの日本語訳があやうい。コマンドが日本語訳されてしまっていたり、ところどころ英語のままだったりしている。
誰でも簡単に量子計算自動化（google colabでpsi4）

[Google Colab](https://colab.research.google.com/)を活用して誰でも簡単に量子計算自動化できるようになる記事です。
Google Colabの使い方は[このサイト](https://future-chem.com/rdkit-google-colab/)がおすすめです。
psi4についての説明は[このサイト](https://future-chem.com/psi4-intro/)がおすすめです。


#psi4のインストールとimport
時間がない人やとりあえず動けばいいという人は，以下のコードを貼り付ければColab上にconda環境の構築からpsi4のimportまでができるようになります．

```rb:psi4.ipynb
# コンダの実装
!wget -c https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
!chmod +x Miniconda3-latest-Linux-x86_64.sh
!bash ./Miniconda3-latest-Linux-x86_64.sh -b -f -p /usr/local
# psi4のインストール
!conda install -q -y -c psi4 python=3.6 psi4
import sys
sys.path.append('/usr/local/lib/python3.6/site-packages/')
```
コード各部の説明については以下を参照してください．

##conda環境の構築
「[RDKitでケモインフォマティクスに入門](https://future-chem.com/rdkit-intro/)」という記事でも説明したように，現時点ではpsi4をpipでインストールすることはできませんので，Colab上にconda環境を準備する必要があります．

そこで以下のように

1.minicondaのインストールスクリプトのダウンロード
2.スクリプトの実行権限の付与
3.インストールスクリプトを実行して/use/local下に環境構築

```
# コンダの実装
!wget -c https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
!chmod +x Miniconda3-latest-Linux-x86_64.sh
!bash ./Miniconda3-latest-Linux-x86_64.sh -b -f -p /usr/local
```

##psi4のインストール
python3.7のpsi4をインストールしようとすると、pip環境と競合してしまうようなので、python3.6のバージョンをインストールします。

```
# psi4のインストール
!conda install -q -y -c psi4 python=3.6 psi4
```

##psi4のimport
ここまででpsi4はインストールできていますが，このままではimportできません．pythonがimportするライブラリ・モジュールを探す場所を「モジュール検索パス」といいますが，psi4の入っているディレクトリはこの中に入っていません．モジュール検索パスの確認はsys.pathで確認できます．

###モジュール検索パスの確認
```
import sys
import pprint
pprint.pprint(sys.path)
#['',
# '/env/python',
# '/usr/lib/python36.zip',
# '/usr/lib/python3.6',
# '/usr/lib/python3.6/lib-dynload',
# '/usr/local/lib/python3.6/dist-#packages',
# '/usr/lib/python3/dist-packages',
# '/usr/local/lib/python3.6/dist-packages/IPython/extensions',
# '/root/.ipython']
```

###psi4のインストールパッケージの場所確認
上にてモジュール検索パスの確認をしました．次にpsi4の場所を確認しましょう。場所は--psiapi-pathで確認できます．


```
# psi4のインストールパッケージの場所確認
!psi4 --psiapi-path
#['/usr/local/lib/python3.6/site-packages']
```
###モジュール検索パスにpsi4の場所追加
上にてpsi4の場所を確認しできました。この場所をモジュール検索パスに追加（append）しましょう．

```
sys.path.append('/usr/local/lib/python3.6/site-packages/')
```
#終わりに
今回は「誰でも簡単に量子計算自動化（google colabでpsi4）」という記事を書きました．初心者にとってpythonの環境構築は挫折ポイントの1つですので，Google Colabを使うことで気軽に分析が始められる点は大きな利点だと思います．
[私のブログ](https://effichem.blogspot.com/)ではもっと詳細な情報や、化学系のグラフ作成方法など幅広く紹介しているので是非参考にしてみてください。
[次回](https://qiita.com/takashi-programming/items/5bb275e09834e22e7824)はGoogle ColobにRDKitとpsi4の両方を導入する方法について解説する予定です。

##参考
https://future-chem.com/rdkit-google-colab/ Google ColabでRDKit：ケモインフォマティクス用のpython環境を手軽に構築

https://effichem.blogspot.com/ 私のブログ
COVID-19チャレンジ（フェーズ3）その4

#概要

signateのCOVID-19チャレンジ（フェーズ3）やってみた。
d3.jsでフェーズ1のデータ読んでみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5fc5dd40-b7d6-b41e-85fb-7920138622f1.png)

#サンプルコード


```

var url = "https://docs.google.com/spreadsheets/d/10MFfRQTblbOpuvOs_yjIYgntpMGBg592dL8veXoPpp4/export?gid=809590826&format=csv";
var out0 = document.getElementById('out0');
var out1 = document.getElementById('out1');
d3.csv(url, function(data) {
  var keys = data.columns;
  var table = d3.select("body").append("table").attr("border", "1")
  table.append("thead").append("tr").selectAll("th").data(keys).enter().append("th").text(function(d) {
    return d;
  });
  for (var i = 1; i < data.length; i++)
  {
    var rows = [];  
    keys.map(function(c) {
      rows.push(data[i][c])
    });
    table.append("tbody").append("tr").selectAll("td").data(rows).enter().append("td").text(function(d) {
      return d;
    });
    out0.value += rows[1] + ", ";
    out1.value += rows[2] + ", ";
  }  
});

```

#成果物

https://embed.plnkr.co/plunk/nMIunOHb4Qio5MGg

以上。
空のディレクトリを削除するには

`find` コマンドを使って、ディレクトリを再帰的にたどって空のディレクトリをすべて削除する方法です。

要件に応じて次の2つのどちらかでできます。

1つ目の方法（空のディレクトリのみを削除）

```console
$ find TARGET -type d -empty | xargs rm -r
```

2つ目の方法（削除対象のディレクトリしか含まれていなかったディレクトリも削除）

```console
$ find TARGET -type d -empty -delete
```

または

```console
$ find TARGET -depth -type d -empty -exec rm -v -r {} \;
```

# 説明

以下のようなファイル構成だとします。

```console
$ mkdir -p a/b1
$ mkdir -p a/b1/c1
$ mkdir -p a/b1/c2
$ mkdir -p a/b2/c3
$ touch    a/b2/c3/d.txt
```

`a/b1` は空ではありませんがからディレクトリのみであり中にファイルが1つもありません。
`a/b1/c1`, `a/b1/c2` は空のディレクトリです。
`a/b2/c3/d.txt` は空のファイルです。

```console
$ find a
a
a/b1
a/b1/c1
a/b1/c2
a/b2
a/b2/c3
a/b2/c3/d.txt
```

`find` に `-empty` という条件を付けると空のディレクトリまたは空のファイルを見つけられます。

```console
$ find a -empty
a/b1/c1
a/b1/c2
a/b2/c3/d.txt
```

`-type d` を条件に追加するとで空のディレクトリのみを見つけられます。

```console
$ find a -type d -empty
a/b1/c1
a/b1/c2
```

これに `xargs rm -r` をパイプでつなげることでこの2つのディレクトリを削除できます。

```console
$ find TARGET -type d -empty | xargs rm -r
```

残ったファイル構成は以下のようになります。

```console
$ find a
a
a/b1
a/b2
a/b2/c3
a/b2/c3/d.txt
```

`a/b1` はいまや空ディレクトリですが、削除前は中にディレクトリがあったので削除されません。

`-exec rm -r {} \;` を `find` のアクションとして付けても削除できますが、 `find` が空のディレクトリを削除してから、そのディレクトリの中身を再帰的にたどろうとするため、余計なエラーメッセージは出てしまいます。

```console
$ find a -type d -empty -exec rm -r {} \;
find: ‘a/b1/c1’: No such file or directory
find: ‘a/b1/c2’: No such file or directory
```

`a/b1/c1`, `a/b1/c2` は削除され、 `a/b1` は削除されないのは `xargs` の場合と同じです。

`-depth` というオプションを付け、 `-exec rm` を使うとディレクトリの中を再帰的にたどってからそのディレクトリ自身を処理するため、 `a/b1` のような削除対象ディレクトリのみのディレクトリも削除してくれます。エラーメッセージも出ません。

```console
$ find a -depth -type d -empty -exec rm -r {} \;
```

結果はこのようになります。

```console
$ find a
a
a/b2
a/b2/c3
a/b2/c3/d.txt
```

ここで、 `xargs` や `-exec rm` の代わりにを `-delete` というアクションにすると `-depth` が暗黙のうちに指定されたことになり、同じ結果になります。

```console
$ find a -type d -empty -delete
```

```console
$ find a
a
a/b2
a/b2/c3
a/b2/c3/d.txt
```

※ `-delete` というアクションはPOSIXの標準には含まれないらしいです。環境によってはできないのかも。

`-delete` だとなにが削除されたかわからなくて気持ち悪い、という場合は `-exec rm -v` のほうがいいかもしれません。

```console
$ find a -depth -type d -empty -exec rm -v -r {} \;
```

以上。
Ruby on Rails チュートリアル 第３章①

○この記事の要点
「第3章　ほぼ静的なページの作成」の途中まで実施内容メモ
思ったことなどのメモ

○第3章でやること
・HTMLファイルだけの静的なWebページの作成
・自動化テストの雰囲気掴み
・静的なページを少し動的にする

○内容
■セットアップ
（１）sample_appの作成
（２）Gemファイルの修正
（３）bundleのインストール。相変わらず bundle update の実行が必要
※test環境では、SQLiteを利用するGemの設定になっているらしい。
（SQLiteの方がインストール等が楽。本場のPostgreSQLと動きが変わらない。ことから）
（４）README.md のメンテ。他の人へのアプリ説明
（５）Bitbucket上にリポジトリを作成してpush
（６）Herokuサーバへのデプロイ
ここまでは新しい内容はない

■静的ページの作成
（１）StaticPagesコントローラの作成
　rails generate controller StaticPages home help　でコントローラファイルが作成される。
　※ここまで実施しただけでは、Webページの閲覧はまだできない。後述するが、routes.rbに各ページのルーティング設定が必要。
　○重要
　・home, helpはアクション
　・作成されたstatic_pages_controller.rbのhome,help定義は空だが、ApplicationControllerを継承しているので、特有の振る舞いをする
　　/static_pages/homeというURLにアクセスすると、RailsはStaticPagesコントローラを参照し、homeアクションに記述されているコードを実行し、アクションに対応するビューを出力する。
　・コントローラ名をキャメルケースで渡すと、コントローラーファイル名が_でつなぎ合わせたものになる
　（StaticPagesで渡すと、static_pages_controller.rb　ができる
　・config/routes.rb（コントローラ）の役割
　　get  'static_pages/home'　⇒ /static_pages/homeというURLに対するリクエストを、StaticPagesコントローラのhomeアクションと結びつけている
　○メモ
　・GET：最も頻繁に使われるHTTPリクエストで、主にWeb上のデータを読み取る (get) ときに使う
　・POST：GETの次によく使用されるリクエストで、ページ上のフォームに入力した値を、ブラウザから送信する時に使う

■テスト
（１）test/controllers/static_pages_controller_test.rbに追加

```ruby:static_pages_controller_test.rb
test "should get about" do
  get static_pages_about_url
  assert_response :success
end
```

（２）rails test実行でエラー

```ruby:エラー
$ rails test
3 tests, 2 assertions, 0 failures, 1 errors, 0 skips
NameError: undefined local variable or method `static_pages_about_url'
```
⇒config/routes.rbにaboutのルートを設定してエラーへ対応

（３）rails test実行でエラー

```ruby:エラー
AbstractController::ActionNotFound:
The action 'about' could not be found for StaticPagesController
```
⇒app/controllers/static_pages_controller.rbにaboutの定義を設定してエラーへ対応

（４）rails test実行でエラー

```ruby:エラー
ActionController::UnknownFormat: StaticPagesController#about
is missing a template for this request format and variant.
```
⇒app/views/static_pages/about.html.erbを作成してエラーへ対応

（５）rails test実行で正常終了
ここまで実施すればWebページの閲覧が可能。

　○重要
　・rails generate controllerした時点で、テストファイルが作成されている
　　　test/controllers/static_pages_controller_test.rb
　・作成されているテストコードの実行コマンド。
　　rails test
　○メモ
　・テスト駆動開発 (TDD)。3つのメリット
　　１．テストが揃っていれば、機能停止に陥るような回帰バグ (Regression Bug: 以前のバグが再発したり機能の追加/変更に副作用が生じたりすること) を防止できる。
　　２．テストが揃っていれば、コードを安全にリファクタリング (機能を変更せずにコードを改善すること) ができる。
　　３．テストコードは、アプリケーションコードから見ればクライアントとして動作するので、アプリケーションの設計やシステムの他の部分とのインターフェイスを決めるときにも役に立つ。
　　この章では、コントローラテスト、モデルテスト、統合テストを行う
　・あえて失敗するテストを書く
    テスト駆動開発⇒「失敗するテストを最初に書く」「次にアプリケーションのコードを書いて成功させる (パスさせる）」「必要ならリファクタリングする」の順に進む

■感想
・テストコード書くの楽しい。UnitTestの存在は知っていたけど、自身で作成するのが初めてでした。
・動作仕様が定まっていないとテストコードが書けないだろうな。と思った。
・この初めてのテスト体験と、自分でアプリ作成するのをかけ合わせて実施するのは非常に良い教材だな。アプリに何が足りないか。など理解しながら実施できる。
・多分この後実施するんだろうけど、ファイルに変更がある都度自動でテストコードが走るようになれば、異変にもすぐ気づけるだろうから良い。
フッターを一番下に固定する方法

コンテンツの内容が少なくフッターが画面の途中にきてしまいフッターの下にスペースが開いてしまった時の解決方法。

**HTML**

```sample.html
<body>
  <div id="wrapper">
    <main>
 
      コンテンツの内容
 
    </main>
 
    <footer>
 
      フッターの内容
 
    </footer>
  </div>
</body>
```

**CSS**

```sample.css
body,
#wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
 
footer {
  margin-top: auto;
}
```

これでフッターがつねに一番下に配置されるようになりました。
CakePHPで論理削除

#論理削除のメリットデメリット

* ユーザーからその存在を隠蔽したいが、データとしては残しておきたい （例えば、業務事情により当該データを使用禁止にしたいが、一時的なのですぐに元に戻せるようにしたい場合）
* 誤って削除した場合に備え、すぐにデータを復元できるようにしておきたい

[参考](https://qiita.com/wanko5296/items/f1af9c7bf020e867c2dd)



#記事の論理削除
CakeDCを用いて論理削除を実装した。
**論理削除**
DBでdeletedカラムをデフォルトで0に設定して、
delete関数が走った時に、deletedカラムに１が立つように実装すれば良い。

SELECT文では検索した場合はdeleted=0が勝手に条件で入り、論理削除されたデータは表示されなくなる。


* CakeDCは以下を参考にした。
[このページのセクション１、２を参考にした](http://www.tailtension.com/cakephp/398/)
* CakeDCを使った論理削除関数の実装は、以下サイトを参考にした。
[delete関数の参考](https://qiita.com/mirror0770/items/791da5808b08fe77be96)
* [一番説明がしっかりされてる英語だけど](https://qiita.com/f_uto/items/9ab67e2bfd7f3de17345)

論理削除関数

```php
  public function exists($id = null) {
        if ($this->Behaviors->loaded('SoftDelete')) {
            return $this->existsAndNotDeleted($id);
        } else {
            return parent::exists($id);
        }
    }
    
    public function delete($id = null, $cascade = true) {
        $result = parent::delete($id, $cascade);
        if ($result === false && $this->Behaviors->enabled('SoftDelete')) {
           return (bool)$this->field('deleted', array('deleted' => 1));
        }
        return $result;
    }
```

上記のように実装したが、実はdelete()はsoftdeleteで上書きされていて、消去ではなくupdateという形になっているらしい。
また、deletedというカラム名があればそこに１を立ててくれるようになっている。
なくても動くものはコメントアウトした。

```php

    public function exists($id = null) {
        if ($this->Behaviors->loaded('SoftDelete')) {//ちゃんとプラグインがあるとき
            return $this->existsAndNotDeleted($id); ////普通の存在チェックだとレコードあるかないかで判断してしまうので、論理削除バージョンの存在チェックが必要
		} 
		// else {//こいつはなくても論理削除は動く
        //     return parent::exists($id); //おそらく、ここでのparentはAppModel（デフォルトのexitsを読んでる）
        // }
    }
    
    // public function delete($id = null, $cascade = true) { //cascadeがtrueだと関連するテーブルのレコードも消去される
    //     $result = parent::delete($id, $cascade); //消去されちゃうと心配かもしれないが上書きされているっぽい
    //     if ($result === false && $this->Behaviors->enabled('SoftDelete')) {
    //        return (bool)$this->field('deleted', array('deleted' => 1)); //なぞ、falseじゃなくてtrueがかえるらしい
    //     }
    //     return $result;
    // }
```

これで、SoftDeleteBehaviorで定義されている
デフォルトのカラム名を変更できる。
```
public $actsAs = ['Utils.SoftDelete'=>['削除フラグ名'=>'削除日時名']];
//実例
public $actsAs = ['SoftDelete'=>['deleted2'=>'deleted_date2']];
```

**Behavior**
モデル間で共通して利用したい機能などをまとめることができる。（controllerでいうコンポーネント的な？）
これを利用すると継承をする必要がなくなる。
ファイルは`app/Model/Behavior`におく。

**Modelのクラスメソッド**
appModelの継承先のModelにおそらく、findとかdeleteメソッドが定義されている（クラスメソッド）。PostModelでdeleteをかくことで上書きできる。はず。

**スコープ定義演算子 (::)**
[parent,self,static](https://maeharin.hatenablog.com/entry/20130202/php_late_static_bindings)

**Curlコマンドが便利そう**
気軽にhttpリクエス、ファイルダウンロードとかできる。

get
`curl localhost:8080/api/json`

標準出力せず、getで取得したデータをファイルに書き込める。
今回githubにあるファイル単体をダウンロードするのに使った。
`curl localhost:8080/api/json -o `



#豆知識
* jsってint型ない。かわりにnumber型がある（整数または浮動小数点数）
社会人エンジニアがatcoderで茶色を目指す#1

## 前回
[社会人エンジニアがプログラミングコンテストに参加してみたい#2](https://qiita.com/Ruby2020/items/e091adb46fc30749b004)

ABCに一回参加したのでタイトルを変更して記載していきます。

#Atcoder Begginers Selectionへ挑戦
前回はコンテストに参加して、ABCの３問回答に終わりました。
まだ１回しか参加していません。
[Atcoder Begginers Selection](https://atcoder.jp/contests/abs)へ参加してABCの難易度にて自身に問題がないか確認しましょう。

##Atcoder Begginers Selection
A〜Bの８問題に関しては何も問題はないと思います。
C問題の以下３問について考えていきます。

##ABC085C	Otoshidama
問題文はatCoderにて読んでください。

まず考えるのは、
- Y<２＊１０の７乗なのでint型を使用
- ループによる全検索
- N=10000の枚数＋5000の枚数＋1000の枚数
- Y=10000×10000の枚数＋5000×5000の枚数＋1000×1000の枚数
ここからコーディングをします。


```
    int N, Y;
    cin >> N >> Y;
    
    for(int i=0; i<=N; i++){
        for(int j=0; j<=(N-i); j++){
            for(int k=0; k<=(N-i-j); k++){
                if(Y==i*10000 + j*5000 + k*1000 && N==i+j+k){
                    cout << i << " " << j << " " << k << endl;
                    goto END;
                }
            }
        }
    }

    cout << -1 << " " << -1 << " " << -1 << endl;
    END:
```

上記は最初の回答です。C++のパワーならいける！
本回答は、

```
    int N, Y;
    cin >> N >> Y;
    
    for(int i=0; i<=N; i++){
        for(int j=0; j<=(N-i); j++){
            if(Y==i*10000 + j*5000 + (N-i-j)*1000){
                cout << i << " " << j << " " << (N-i-j) << endl;
                goto END;
            }
        }
    }

    cout << -1 << " " << -1 << " " << -1 << endl;
    END:
```

Nが固定値であり、他の２種類のお札の枚数が決まれば残り１種類の枚数は決まります。
k=(N-i-j)になります。


##ABC049C	白昼夢
問題文はatCoderにて読んでください。
与えられた文字列Sと下記４つの単語を組み合わせて作成するTはS＝Tとなりえるか。
"dream" "dreamer" "erase" "eraser"

単語の後にある"er"が問題ですね。
配列を削除するときと一緒で先頭からTを作成していくとできないです。
この手の問題は最後尾から作成します。
この問題はかなり簡単なのでコードは書きません。

##ABC086C	Traveling
問題文はatCoderにて読んでください。
私は最初に問題のポイントは、

- int型を使用
- ループによる全検索
- X+Y<=T、X、Y座標の合計が時間より大きい場合は成立しない
- 時間が奇数なら移動距離も奇数、偶数なら移動距離も偶数

を考え実装しました。

```
    int N, ans=0;
    cin >> N;

    for(int i=0; i<N; i++){
        int x,y,t;
        cin >> t >> x >> y;
        
        if(t%2==(x+y)%2){
            if(t>=(x+y)){
                ans++;
            }
        }
    }
    
    if(ans==N){
        cout << "Yes" << endl;
    }else{
        cout << "No" << endl;
    }
 
    return 0;
```
上記で提出した場合、ACで通りました。
分かった気になっていました。

しかし、この記事を書いている際に、

```
2
10 1 9
16 1 1
```

みたいなテスト入力でもACが出てしまいました。
この問題には通過点があります。
前回の地点からの変化量の絶対値に対して今まで考察した条件を適用しないといけません。

```
    int N, ans=0;
    cin >> N;
    
    int ox=0,oy=0,ot=0;
    
    for(int i=0; i<N; i++){
        int x,y,t;
        cin >> t >> x >> y;
        
        if((t-ot)%2==(abs(x-ox)+abs(y-oy))%2){
            if((t-ot)>=abs(x-ox)+abs(y-oy)){
                ans++;
            }
        }
        ot=t;
        ox=x;
        oy=y;
    }
    
    if(ans==N){
        cout << "Yes" << endl;
    }else{
        cout << "No" << endl;
    }
 
    return 0;
```

ACにて通りました。
これでAtcoder Begginers Selectionを理解したのではないかと思います。

##C問題に求められるものとは
４つの変化する値は、３つ決まれば残り１つは決定する。奇数、偶数に関する理解。最初からではなく最後から処理するなどを咄嗟に見つけることだと思います。
次回はD問題について記載したいと思います。
［Node.js + PostgreSQL］Node.js アプリから PostgreSQL DB に接続

### 書くこと
Node.js で作成したアプリから、PostgreSQL DB に接続する方法

### 前提条件
接続するDBは、下記記事で作成したものを利用する。
[［DB/SQL］要件をテーブルに落とし込む手法のメモ書き（複式簿記のテーブル設計を例に）](https://qiita.com/tanakadaichi_1989/items/09e0ce35f3ebc9afc352)


### フォルダ構成
```
NodeJSSampleApp
┣ app.js
┣ node_modules
┣ package-lock.json
┣ package.json
┣ public
┗ views
  ┗ journal.ejs
```

### コード

```js:app.js
const express = require('express');
const app = express();

app.use(express.static('public'));

var {Client} = require('pg');

var client = new Client({
	user: 'DB USER NAME', // DB のユーザー名を指定
	host: 'localhost',
	database: 'SampleApp',
	password: 'DB PASSWORD', // DB のパスワードを指定
	post: 5432
})

client.connect();

var query = 'select journal.id as 仕訳ID,journal.date as 日付, (select accounts_title.name from accounts_title where accounts_title.id = journal_details.debit_accounts_id) as 借方科目,journal_details.credit_amount as 借方金額,(select accounts_title.name from accounts_title where accounts_title.id = journal_details.credit_accounts_id) as 貸方科目,journal_details.credit_amount as 貸方金額,journal.memo as 摘要 from journal_details join journal on journal_details.journal_id = journal.id;';

app.get('/',(req,res)=>{

	client.query(query,(error,result)=>{
		console.log(result);
		res.render('journal.ejs',{results: result}); // results に格納した取得結果を journal.ejs で表示
		client.end();
	});
	
});

app.listen(3000);
```

```ejs:views/journal.ejs
<html>
<head>
<title>複式簿記</title>
<link rel = "stylesheet" type="text/css" href = "/css/style.css">
<head>
<body>
<h1>複式簿記</h1>
<table>
<thead>
<tr>
<th>仕分ID</th>
<th>日付</th>
<th>借方科目</th>
<th>借方金額</th>
<th>貸方科目</th>
<th>貸方金額</th>
<th>摘要</th>
</tr>
</thead>
<% for(var i=0;i< results.rowCount;i++) {%>
<% var year = results.rows[i].日付.getFullYear(); %>
<% var month = results.rows[i].日付.getMonth() + 1; %>
<% var day = results.rows[i].日付.getDate(); %>
<tr>
<td><%= results.rows[i].仕訳id %></td>
<td><%= year + '/' + month + '/' + day %></td>
<td><%= results.rows[i].借方科目 %></td>
<td><%= results.rows[i].借方金額 %></td>
<td><%= results.rows[i].貸方科目 %></td>
<td><%= results.rows[i].貸方金額 %></td>
<td><%= results.rows[i].摘要 %></td>
</tr>
<% } %>
</table>

</body>
</html>
```

### アプリを実行し、ブラウザから `localhost:3000` にアクセス

```command
$ cd NodeJSSampleApp
$ node app.js
```

### 表示結果
![2020-05-06 16.04.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199441/0176cd6a-9744-e533-1f86-0c43d9f0d253.png)
FBX SDK Pythonを使ってプログラムを作るにはどんなスキルが必要なの？

# FBX SDK Pythonを使ってプログラムを作るにはどんなスキルが必要なの？

3DCG知識ゼロのプログラマー（仮にAさんとします）に、「FBX SDK Pythonを使ってプログラムを作るにはどんなスキルが必要か教えてください」と言われたので、簡単なまとめ資料を作りました。

意外と同じ悩みを持つ人が他にもいるかもしれませんので公開します。

Aさんにとってわかりやすい表現となるように資料を作りましたので、用語解説があまり正確ではないかもしれません。なにとぞご了承ください。

大きく3つのカテゴリーに分けました。

- 数学
- 3DCG
- プログラミング



# 数学編
3DCGやプログラミングの経験があったとしても、数学スキルがないとFBX SDK Pythonを利用するのは難しいです。まずは数学の勉強から始めることをオススメします。



### 3次元ベクトル

(x,y,z)の3つの数値で、3次元空間内の位置や方向を表現する手法です。

3次元ベクトルの加算・減算・内積・外積はよく使うので、抑えておいた方がよいです。



### ディグリー[°]とラジアン[rad]

どちらも角度の単位です。180°=π[rad]になります。

ラジアンは三角関数を理解するための前提知識となります。




### 三角関数

sin, cosのことです。

オイラー角を計算するための前提知識となります。



### オイラー角

3回の回転で回転方向を表現する手法です。

![](https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Euler2a.gif/220px-Euler2a.gif)
※Wikipediaから引用

「どの軸をどの順番で回転させるか？」で、 `z-y-x` や `z-x-y` 等の表現方法があり、全部で12通りあります。

以下の記事が詳しいです。
[https://ja.wikipedia.org/wiki/%E3%82%AA%E3%82%A4%E3%83%A9%E3%83%BC%E8%A7%92](https://ja.wikipedia.org/wiki/オイラー角)



### クォータニオン（四元数）

(x,y,z,w)の4つの数値で回転方向を表現する手法です。

クォータニオンの乗算や共役クォータニオン等を抑えておくとよいと思います。

以下の記事が詳しいです。
https://qiita.com/kenjihiranabe/items/945232fbde58fab45681



### 右手系と左手系

3次元座標系の向きの話です。

これによってベクトル・クォータニオンの正負が変わってしまいますので、注意が必要です。

以下の記事がわかりやすいです。
[https://ja.wikipedia.org/wiki/%E5%8F%B3%E6%89%8B%E7%B3%BB](https://ja.wikipedia.org/wiki/右手系)

どちらもよく登場しますので、間違えないように注意する必要があります。



# 3DCG編
数学とプログラミングの経験があっても、3DCG関連の知識がないと、FBX SDK Pythonを利用するのは難しいです。

ここでは3DCG関係の知識・スキルを列挙します。




### y-upとz-up

天空方向がy軸なのか、z軸なのかという話です。

y-upとz-upどちらもよく登場しますので、間違えないように注意する必要があります。



### メートル単位とセンチメートル単位

長さの単位が、1メートルなのか1センチメートルなのかという話です。

どちらもよく登場しますので、間違えないように注意する必要があります。



### スケルトン（ボーン・ジョイント・アーマチュア）

人型キャラクターの骨格のことです。

たとえば、右肩を動かせば、右肘も追従して動きます。しかし、右肘を動かしても、右肩は動きません。

そういった関節同士の関係は、右肩→右肘→右手首といった階層構造で表現します。

関節1つ1つに回転方向（クォータニオンやオイラー角）を設定することで、全身のポーズ（姿勢）を決めることができます。

詳しくは以下をご覧ください。
https://styly.cc/ja/tips/blender-modeling-start5-2/



### Tスタンス

Tスタンスとは、人型キャラクターのポーズの一種です。初期姿勢としてよく使われます。



### アニメーションカーブ

横軸を時間軸、縦軸を変化量とする領域に描かれる折れ線グラフのことです。

たとえば関節のオイラー角の時間変化をアニメーションカーブとして記録します。

詳しくは以下をご覧ください。
https://docs.unity3d.com/ja/2018.4/Manual/animeditor-AnimationCurves.html



### フレームレート

1秒間に何個のフレームがあるかということです。

30や60がよくつかわれます。



### FBX

3DCG系のファイルフォーマットです。

ポリゴン・スケルトン・アニメーションカーブ等を保存できます。




# プログラミング編
FBX SDK Pythonを扱うのに必要なプログラミング関係スキルもまとめました。



### Python

まずは、Pythonを使える必要があります。

下記のレッスンがオススメです。
https://dotinstall.com/lessons/basic_python_v4



### FBX SDK Python

当たり前ですが、FBX SDK Pythonを導入する必要があります。

詳しくは以下をご覧ください。

- Windows : https://qiita.com/segur/items/5d0dff790e784760a547
- Mac : https://qiita.com/segur/items/e09d464b5e2ff0c8725e



### パッケージ管理ツール

FBX SDK Pythonと直接は関係ありませんが、Pythonのライブラリを管理するツールを導入した方がよいです。

個人的にはPoetryがオススメです。

詳しくは以下が参考になります。
https://qiita.com/sk217/items/43c994640f4843a18dbe



### テストフレームワーク

FBX SDK Pythonと直接は関係ありませんが、単体テストを書くためのフレームワークを導入するかと思います。

個人的にはPytestがオススメです。

詳しくは以下が参考になります。
https://dev.classmethod.jp/server-side/python/pytest-getting-started/



# さいごに

ずらずらと列挙させていただきました。

未経験からとなると非常に遠い道のりですが、がんばりましょう！

参考になりましたら幸いです。
Laravel6 エラーメッセージ日本語化

エラ〜メッセージを日本語にしたくて

必要な作業は全部済ませたがどうしても日本語になってくれなかった。



app.phpのlocaleは　’ja’に修正済み

しかし、どう言うわけかviews/lang/jaディレクトリまでパスがとどいていないみたいだったので、仕方がないから直接ルーティングを設定した

今後同じようなことが会ったときのための備忘録。

###参考記事
http://dim5.net/wordpress/change-locale-error-message.html
【Rails 】LoadError(Unable to autoload constant コントローラ名, expected〜〜)のエラー

##状況
タイトルの通り、LoadErrorが出て少し詰まったので備忘録として残します。


<img width="1432" alt="スクリーンショット 2020-05-06 15.51.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/9badb125-d4db-d717-5224-4076b7402b54.png">

##エラー文

エラー文には、「Unable to autoload constant ChatRoomsController, expected /Users/ユーザー名/アプリ名/app/controllers/chat_rooms_controller.rb to define it」と記載がある。

google翻訳だと、「定数ChatRoomsControllerを自動ロードできません。/Users/ユーザー名/アプリ名/app/controllers/chat_rooms_controller.rbを定義する必要があります」
と出てくる。

##「あれ、ChatRoomsControllerなんて一番初めに作ったのにな・・」と思いながらChatRoomsControllerのファイルを見に行く。

<img width="626" alt="スクリーンショット 2020-05-06 15.59.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/db4ceabc-8382-e6c6-197a-436f5c4df552.png">

##classで定義している「RoomssController」になっていました・・・

##解決策
原因はclassで定義しているコントローラ名が間違っていることだったので、RoomsControllerから
ChatRoomsControllerへと変更。

無事エラーが解決できました。
ケアレスミスに気を付けたいと思います・・
Flaskのアプリケーションの設定

# はじめに

ここでは、Flaskのアプリケーション関連設定について解説します。


# ビュー関数

ここでは例として、ユーザー認証の機能を例に書きます。

```python:auth.py
import functools

from flask import (
    Blueprint, flash, g, redirect, render_template, request, session, url_for
)
from werkzeug.security import check_password_hash, generate_password_hash

from todo.db import get_db


bp = Blueprint('auth', __name__, url_prefix='/auth')


@bp.route('/signup', methods=('GET', 'POST'))
def signup():
    error = {}

    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        password_re = request.form['password-re']
        db = get_db()

        if not username:
            error['username'] = 'ユーザー名を入力してください。'

        if not password:
            error['password'] = 'パスワードを入力してください。'

        if not password_re:
            error['password_re'] = 'パスワード（確認用）を入力してください。'
        
        if username and password and password_re:
            if password == password_re:
                registered_user = db.execute(
                    'SELECT id FROM user WHERE username=?', (username,)
                    ).fetchone()
                if registered_user is not None:
                    error['username'] = 'そのユーザー名は既に登録されています。'
            else:
                error['password_re'] = 'パスワードが一致していません。'

        if error == {}:
            db.execute(
                'INSERT INTO user (username, password) VALUES (?, ?)',
                (username, generate_password_hash(password))
            )
            db.commit()
            return redirect(url_for('auth.login'))

    return render_template(
        'auth/form.html',
        type='signup',
        error=error
        )


@bp.route('/login', methods=('GET', 'POST'))
def login():
    error = None

    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = get_db()
        user = db.execute(
            'SELECT * FROM user WHERE username = ?', (username,)
        ).fetchone()

        if user is None or not check_password_hash(user['password'], password):
            error = 'ユーザー名かパスワードが間違っています。'

        if error is None:
            session.clear()
            session['user_id'] = user['id']
            return redirect(url_for('index'))

    return render_template(
        'auth/form.html',
        type='login',
        error=error
        )


@bp.before_app_request
def load_logged_in_user():
    user_id = session.get('user_id')

    if user_id is None:
        g.user = None
    else:
        g.user = get_db().execute(
            'SELECT * FROM user WHERE id = ?', (user_id,)
        ).fetchone()


@bp.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('auth.login'))


def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):
        if g.user is None:
            return redirect(url_for('auth.login'))

        return view(**kwargs)

    return wrapped_view
```


# まとめ

ここでは、Flaskのアプリケーションの設定の基本について解説しました。
次回はHTMLテンプレートについて取り上げる予定です。
Vuex で複数の子componentで値を共有してみるカウンタの例 ( Vuex child component share store data example #Vue #Nuxt )

# NOTE

- 初学、学習中
- dispatch とかよくわからんレベル
- Nuxtでプロジェクト作成した環境

# pages/state-counters.vue



```vue
<template>
  <div>
    <div>
      <stateCounter/>
      <stateCounter/>
      <stateCounter/>
    </div>
  </div>
</template>

<script>

import StateCounter from '~/components/stateCounter.vue'

export default {
  components: {
    StateCounter
  }
}
</script>

```

# components/stateCounter.vue

```vue

<template>
  <div>
    <div>
      <h1> {{ count }} </h1>
      <input type="button" @click="incrementCounter" value="Increment!">
    </div>
  </div>
</template>

<script>

export default {
  computed: {
    count () {
      return this.$store.state.increments.count
    }
  },
  methods: {
    incrementCounter (e) {
      this.$store.commit('increments/increment')
    }
  }
}
</script>

<style>
body {
  text-align: center;
}
</style>

```

# store/increments.js

```vue
export const state = () => ({
  count: 1
})

export const mutations = {
  increment (state) {
    state.count++
  },
}

```

# View

どのcomponentのボタンを押してもすべてのカウンタで値が増える

![image](https://user-images.githubusercontent.com/13635059/81037304-2ea98680-8edd-11ea-9eba-df2d11d33546.png)
![image](https://user-images.githubusercontent.com/13635059/81037305-2f421d00-8edd-11ea-9bb9-7b268f00313f.png)
![image](https://user-images.githubusercontent.com/13635059/81037307-2fdab380-8edd-11ea-88f4-a3e2db299428.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3148











<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【BootstrapVue】tableでクリックされたレコードの値を取得する

# はじめに
Vue.js + Bootstrapのtableのレコードの値を取得する方法のメモです。
初めての投稿となるので、日本語がおかしいかもですが、誰かの役に立てれば幸いです。

# やりたいこと
以下の画像はBootstrapVueのTables Componentを利用して作成したテーブルです。
今回は、テーブルの中の佐藤 健さんのレコードをクリックした時に、レコードの値を取得します。
<img width="805" alt="スクリーンショット.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519667/26fd6c43-12f3-5efb-92c7-96c67291a74c.png">

以下がコードです。ちょっとだけ解説します。

\<b-table>はBootstrapのテーブル形式でデータを表示するためのコンポーネントです。
:itemsにソースデータの配列を渡してあげると、よしなにしてくれます。(めっちゃ楽)

```
<template>
  <div>
    <b-table striped hover :items="items"></b-table>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        items: [
          { age: 20, first_name: '太郎', last_name: '田中' },
          { age: 31, first_name: '健', last_name: '佐藤' },
          { age: 45, first_name: '花子', last_name: '山田' },
          { age: 60, first_name: '謙', last_name: '渡辺' }
        ]
      }
    }
  }
</script>
```

# 実装
`row-clicked` イベントリスナーでレコードの値を受け取れるみたいです。また、itemsに対する配列のインデックスを、任意の2つ目の引数として受け取れるらしい。

```
<template>
  <div>
    <b-table striped hover :items="items" @row-clicked="row"></b-table>　// 変更
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { age: 20, first_name: "太郎", last_name: "田中" },
        { age: 31, first_name: "健", last_name: "佐藤" },
        { age: 45, first_name: "花子", last_name: "山田" },
        { age: 60, first_name: "謙", last_name: "渡辺" }
      ]
    };
  },
  methods: {　          //追記
    row(record) {
      console.log(record);
    }
  }
};
</script>
```

# 結果
以下は佐藤 健さんのレコードをクリックした時の結果です。

```
Object {age: 31, first_name: "健", last_name: "佐藤"}
```

レコードの値を受け取ることができました。

# 参考
https://bootstrap-vue.org/docs/components/table#row-select-support
ホットペッパーAPIを使ったLINEbotお店検索

## やりたいこと
LINEを使って位置情報からホットペッパーに載っているお店の情報を返すというBOTの作成

## 位置情報を取得してその戻りを確認する
まずホットペッパーAPIを利用するにあたってAPIキーを発行する。
https://webservice.recruit.co.jp/register/

`http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=[APIキー]&lat=[緯度]&lng=[経度]&range=5`
参考：[ホットペッパーグルメ　APIリファレンス](https://webservice.recruit.co.jp/hotpepper/reference.html)

## 位置情報を元にjsoncodeを取得する
curlを使用し、上記のグルメサーチAPIの戻りを取得する。

```
　　$ch = curl_init();//curlセッション初期化
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//curl_exec()の返り値を文字列で返す。
    $response = curl_exec($ch);//URLの情報を取得し、ブラウザに渡す
    $result = json_decode($response, true);//取得したURLのjsonコードをデコードする
    curl_close($ch);//セッション終了
```
この際、上記のURLで取得しても`$result`は**null**になる。
理由→レスポンス形式が初期値では`xml`であるから。

グルメサーチAPIで`format`を`json`に指定する。

jsonとは？
参考：[JSONってなにもの？ | Think IT（シンクイット）](https://thinkit.co.jp/article/70/1)

取得したURLの情報を`$response`に代入し、さらに`json_decode`で取得したjsonコードをデコードする。

## お店があるかのチェックを行う
返ってきた情報を元にお店情報があるかどうかのエラーハンドリングを行う。
また、位置情報ではなくテキストやスタンプが送られてきた場合のレスポンスも設定する。

## foreachで取得した結果を回し、店名とURLを変数に代入する

```
    foreach ($[取得したお店情報] as $key => $value) {
        $shopinfo .= $value[店名] . "\n";
        $shopinfo .= $value[ホットペッパーURL] . "\n\n";
    }
```
**取得する件数をif文で指定する**
`$key`が2になったら`break`することで3件だけ取得することができる。

```
    foreach ($[取得したお店情報] as $key => $value) {
        $shopinfo .= $value[店名] . "\n";
        $shopinfo .= $value[ホットペッパーURL] . "\n\n";
        if ($key == 2) {
             break;
        }
    }
```

## メッセージを返すメソッドを別ファイルに書く
位置情報取得や上記の処理を`webhook.php`に記載すると位置情報のコードが増えてしまう。
そのため、お店情報を取得する処理を別ファイルに記載して、`webhook.php`にはメソッドを書くだけにすることでコードがスッキリになる。
また、メソッドを別に書くことによって見やすく修正もしやすくなる。
SGIのWSにVGAモニタをつなぐとき

### SGIのWSにモニタを接続

通常のVGAモニタを接続しても映らない．
まず端子形状が違う．
そして信号が特殊である．

### 端子形状13W3

SGI本体側の端子はこれである．

![スクリーンショット 2020-05-06 14.58.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629832/715fc63b-283c-af11-ac9d-c89af53efdfa.png)

SUNのWSと同じ．
[この人の説明を参考した](https://orumin.blogspot.com/2017/09/sgi-db13w3-vga.html)

なるほど．
コンバーターはヤフオクでたまに出品されている．
何個か購入したが1500円〜3000円くらい．

それをVGA端子に取付て，モニタはVGA，WS側は13W3とする．

### 信号がsync-on-green

SGIのビデオ信号は「シンクオングリーン(sync-on-green）」という形式らしい．
RGBのGに同期信号がのっている．
これを解釈できるモニタでないとVGA端子にケーブルを繋げても表示しない．

いろいろ探したが，NECのMultisyncというタイプは比較的最近のものまでsync-on-greenに対応している．
これもヤフオクで色々と出品されている．
NEC 2090UXi, MD212MC というモニタをヤフオクで入札したが，問題なく映っている．
4:3のほうがよく，16:9だとWS側が対応していないので間延びしてしまう．
マニュアルをWEBで検索し，sync-on-greenかどうかを確認すればよい．

ただし，SYNC信号がいらないので，VGA側のピンを折ってしまうことで余計な信号をモニタに入れない．

![スクリーンショット 2020-05-06 14.58.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629832/403d78bb-4997-3e0a-661e-b2f378818ccc.png)

VGAの最下列の５本あるうちの左から３，４本目のピンを折っている．
[この人のやったことを参考した](https://phaq.phunsites.net/2006/08/25/using-a-sun-13w3-vga-adaptor-on-a-sgi-indy/)

大胆だなと思ったが，ピンをおらないと画面がちらつく事がある．
この処置が正しいのかどうは知らない．
これでIndy/Octan/Octan2/Onyx2は映っている．

また，VGAケーブル側を折るようにすれば，折るものに失敗してもまた購入すればいいし．




Voila (^-^)/
Rustで nHr の全探索（重複可の組み合わせ）

[ABC165C](https://atcoder.jp/contests/abc165/tasks/abc165_c) が解けなかったので整理します

nPr, nCk, nHr といったヤツらの各組み合わせをRustで全探索する方法をまとめます

## 選択肢1. itertools

Rustの `itertools` クレートには、「順列」「組み合わせ」「重複可の組み合わせ」に対応して `permutations`, `combinations`, `combinations_with_replacement` というメソッドが存在します(参考: [itertoolsのDocument](https://docs.rs/itertools/0.9.0/itertools/trait.Itertools.html) ) 。したがって例えば以下のように 3つから2つを重複可で取り出す 6つの組み合わせが得られます:

```rust
use itertools::Itertools;
fn main() {
    (0..3).combinations_with_replacement(2).for_each(|xs| print!("{:?}",xs));
}
/* 出力: [0, 0][0, 1][0, 2][1, 1][1, 2][2, 2] */
```

組み合わせの数「だけ」を知りたい場合は nPr, nCr, nHr の公式から得られますが、各組み合わせにおいて何らかの計算をしたい時や、それらに対する何らかの操作（最大値を求めたり、総和を求めたり）をしたい時には上述のように具体的に一つ一つの組み合わせがどのようなものかを知る必要があり、`itertools` はそのための道具になります。

## 選択肢2. 深さ優先探索（DFS）
`itertools` を使わなくても、上記のような組み合わせを作るのは簡単です。3つから2つを重複可で取り出す組み合わせは2重ループで簡単に求まります:

```rust
for i in 0..3 {
   for j in i..3 {
        print!(r"[{},{}]", i,j);
   }
}
// 出力: [0,0][0,1][0,2][1,1][1,2][2,2]
```

しかし一般の場合では`r`重ループを記述できないので再帰をつかいます:


```rust
fn main() {
    let (n, r) = (3, 2);
    let mut buf = vec![0;r];
    dfs(&mut buf, 0, 0, n);
}

// 深さd においてd番目の値を決める。lb/ubはその選択肢の下限/上限
fn dfs(buf:&mut Vec<usize>, d:usize, lb:usize, ub:usize) {
    if d == buf.len() { // 「depthがバッファ長に等しい」 = 「leafの時」
        print!("{:?}", buf);
    } else {
        for i in lb..ub {
            buf[d] = i;
            dfs(buf, d+1, i, ub);
        }        
    }
}
// 出力: [0,0][0,1][0,2][1,1][1,2][2,2]
```

組み合わせを保持するメモリ領域は長さrのVec 1つ分で済むことは注目に値します。

## その他補足
- nHr の英語は combination with replacement となりますが、「replacement」ってどういう意味？置き換え？みたいに混乱していましたが、replacement は duplicate と読み替えてよいという感じの記述をInternetで見つけました。それなら「重複ありの組み合わせ」と直訳できるので納得です
- ABC165Cでは完全に全探索する必要があるので `itertools` を使った解法が最も簡潔に記述できますが、問題によっては、再帰の途中で枝刈りが可能な場合も多く再帰を使った解法を覚えておくことは必須だと思います
- DFSの方法で nPr, nCr を列挙するのは少しループ周りの変数をいじることで対応可能です。
blender2.8でクリームぜんざいを作る-5あずき編

# いままでの記事
[blender2.8でクリームぜんざいを作る-1blenderセットアップ編](https://qiita.com/vrshuriken/items/54575f890185c4498ea7)
[blender2.8でクリームぜんざいを作る-2基本操作編](https://qiita.com/vrshuriken/items/9192c849ba87c3a1a12b)
[blender2.8でクリームぜんざいを作る-3器編](https://qiita.com/vrshuriken/items/cd4f2db7047dc41445eb)
[blender2.8でクリームぜんざいを作る-4クリーム編](https://qiita.com/vrshuriken/items/05f8fb9d473e5a633716)

# あずき一粒を作る
UV球変形で作っても良いですが今回は立方体(Cube)を変形して作ってみます
器などは邪魔になるの目のマークをクリックして非表示にしておきましょう。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/52277085-6fb5-1354-0008-73a704336d3e.png)
オブジェクトモードで
Ctrl+C,Ctrl+A,追加>メッシュ>立方体
で立方体を追加。大きさは適当に豆のサイズにしておきます。
※編集モードで追加すると同じオブジェクトに追加されてしまいます


![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/566e979d-d83d-8057-1f50-a25642a22eed.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/4aea54f8-0249-8a15-1239-5548e95755bf.png)
立方体を丸くするためにサブディビジョンサーフェースモディファイアを使います。
立方体オブジェクト選択,モディファイアプロパティ>モディファイアを追加>サブディビジョンサーフェース
細分化の数値は分割の細かさなので適当に1で。
※細かすぎるとポリゴン数が増えすぎる
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/32dcff1e-8e33-4814-e566-8e90f73509b7.png)
丸まりました。編集モードにして元の形状とモディファイア適用後の形を見ています。
※適用を押すと確定しますが、形状を先に整えるのでそのままで


丸すぎるので編集します。
ブディビジョンサーフェース面と面の間が丸く小さくされるイメージです。なので面(辺)を増やすと元の立方体の形状に近づきます。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/5ddb3280-4f68-23f1-2e6d-92c281217c5f.png)
編集モードで Ctrl+Rのループカットで辺を足すと四角に近づきます。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/97532312-6725-c904-0cd5-efca446b8309.png)
編集モードでSキーでサイズの比率調節。
※オブジェクトモードだとオブジェクトの比率が変わってしまうので編集モードで


![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/20cd92c6-968e-b67f-a677-1cdb2090626b.png)
編集モードの辺選択状態で端の辺をShift+クリックで選択し、
S,Shift+Xなどで縮小し形を整えます。
※中心に向かって縮小されないときは操作の基準を決める「トランスフォームピボッドポイント」の設定を変える

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/1fa39703-9695-0470-4f08-af9d3da60e16.png)
辺を増やす時はCtrl+Rのループカットで。
逆に減らしたければAlt+辺クリックで辺選択し、
右クリック>辺を融解で減らせます。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/a1e82090-e216-71f6-1bfd-ccbe8ab6c037.png)
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/1881d05b-f225-1f0e-cb2e-e0212a5872b4.png)
なめらかにするため、編集モードでCtrl+Aですべての面を選択し、面をスムーズにを適用しておきます。

※配置は後で編集モードであずきを選択しShft+Dで複製し、Gキーで移動、Rキーで回転など行い配置していきます。

# あずき同様にしらたま１つを作成
しらたまはUV球を置くだけです。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375610/0d04bd3a-d22c-4323-fc86-1768eda6c9ca.png)
オブジェクトモードでCtrl+C,Ctrl+A 追加>メッシュ>UV球
セグメント数、リングは適当に6くらいで。
Ctrl+Aですべての面を選択して「面をスムーズ」にを選択。
サイズはSキーで適当に調整。

# 次の記事へ
[blender2.8でクリームぜんざいを作る-6配置・fbxエクスポート編](https://qiita.com/vrshuriken/items/d1867a6698085218fdeb)
pythonメモ - getoptでオプション指定

# はじめに
CLIでpythonプログラムを実行するときに引数指定をするならgetoptを使うので
基本的な動きを色々と試してみた。

# 基本的な使い方
参考URL：https://szarny.hatenablog.com/entry/2017/08/17/231356

```:書式
import getopt
opts,args = getopt.getopt(text, shortopts, longopts=[])
```

```:例
import getopt
opts,args = getopt.getopt(
    sys.args[1:],
    "hle:t:cp:,
    ["help", "listen", "execute=","target=","command","port=" )
```

|引数|説明|
|:----|:---|
|opts|引数を解析した対象。shortopts, longoptsに合致する対象がリスト形式でセットされる|
|args|引数を解析した対象。shortopts, longoptsに合致しない対象がリスト形式でセットされる|
|text|引数を解析する対象。プロンプトから与える引数であればsys.args[1:]でOK
|shortopts|略記でのオプション指定。引数が必要なオプションはコロンを付ける。例でいうと、h,l,cは引数不要でe,t,pは引数必要なオプション|
|longopts|詳記でのオプション指定。リスト形式で指定する。引数が必要なオプションはイコール(=)を付ける。例でいうと、execute, target, portが引数必要|

なお、shortoptsとlongoptsはそれぞれ対応するのでそこんところ気を付けたらよいです。

# 実装例
色々試したので余計なコードも混ざってますが…


```:show_arg.py
import sys
import getopt

def main():
    if not len(sys.argv[1:]):
        print("argument is nothing")
        sys.exit()
    
    text = sys.argv[1:]
        
    try:
        opts,args = getopt.getopt(
            text,
            "t:p:m:h",
            ["target=", "port=", "message=", "hogehoge"]
            )
        print("Options:", opts)
        print("Arguments:", args)
    except getopt.GetoptError as err:
        print(str(err))

main()
print("finished")
```

実行結果はコチラ。略記指定ならハイフンひとつ。詳記指定ならハイフンふたつ。
一回目はshortopts、longoptsを試してみた結果（argsに入りそうな結果は出ないパターン）
二回目はargsに値が入ってくるように引数をセットしてみた結果

```:実行結果
$ python show_arg.py -t 127.0.0.1 -p 8888 --message hello --hogehoge
('Options:', [('-t', '127.0.0.1'), ('-p', '8888'), ('--message', 'hello'), ('--hogehoge', '')])
('Arguments:', [])
finished
$ python show_arg.py -t 127.0.0.1 -p 8888 --message hello --hogehoge hoge hage hige
('Options:', [('-t', '127.0.0.1'), ('-p', '8888'), ('--message', 'hello'), ('--hogehoge', '')])
('Arguments:', ['hoge', 'hage', 'hige'])
finished
$ 
```

# おわりに
getops、sys.argvとセットで使えるようにしとくと超便利でした。
私家版 Slim Framework チュートリアルをslim4でやってみた　メモ

##参考
https://qiita.com/nunulk/items/4b5c15f13ade660cafbc

##概要
上記の記事が個人的にとてもわかりやすかったので、そのチュートリアルをやったことのまとめ。
slim3と4で書き方に違いがあり、私はslim4で記事はslim3であったので
その際のハマった箇所を記録として記載。

##注意事項
こちらの記事では、私が未熟で理解できてない事も多いので
説明などではなく、どうしたら動いたのかを記載してます。

##3ルーティングの書き方
    // Sample log message
    $this->logger->info("Slim-Skeleton '/' route");

    // Render index view
    return $this->renderer->render($response, 'index.phtml', $args);


下記に変更↓

    $view = new \Slim\Views\PhpRenderer('./../templates/tickets/');
    return $view->render($response, 'create.phtml');


##4.2. 新規作成
    $subject = $request->getParsedBodyParam('subject');
    // ここに保存の処理を書く
    // 保存が正常にできたら一覧ページへリダイレクトする
    return $response->withRedirect("/tickets");

下記に変更↓

    $subject = $request->getParsedBody('subject');
    // ここに保存の処理を書く
    // 保存が正常にできたら一覧ページへリダイレクトする
    return $response->withHeader('Location', '/tickets')->withStatus(302);

参考
http://taka512.hatenablog.com/entry/2019/11/17/161445


    $app->get('/tickets', function (Request $request, Response $response) {
        return $response->write('tickets');
    });


下記に変更↓

    $app->get('/tickets', function (Request $request, Response $response) {
        $response->getBody()->write("tickets");
        return $response;
    });
Jupyter notebook コードを折りたたむ機能の実装方法

#1 目的
Jupyterで書いたコードの折り畳みを行うためには、Nbextensionsをアドオンする必要がありますが、多少手間がかかるので、やり方をメモしておきます。なお、ここではWindowsでのやり方を書いています。

#2 やり方

(1)Anaconda Promptをオープンします。

<img width="396" alt="72.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/efe52877-2208-507d-a71b-1caf9fc13129.jpeg">

(2)Nbextensionsをインストールする。Anaconda Promptに下記を入力する。

```console:
pip install jupyter-contrib-nbextensions
jupyter contrib nbextension install --user
```

(3)インストール完了後、「Jupyter」のメニューに「Nbextensions」が追加されていることを確認する。確認後、「Nbextensions」をクリックしてConfig画面をオープンする。

<img width="523" alt="73.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/3e9fa53e-68c1-7a55-b7ea-2c1aaf109c19.jpeg">

(4)「Nbextensions」の画面にて「Codefolding」にチェックを入れる。下記のキャプチャー図と同じ状態にする。

<img width="619" alt="74.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/7f80832a-e1e6-2b92-789d-a897cfe2dbe6.jpeg">


(5)コードを開くと、折り畳みができるようになっている。(折り畳みができない場合は一度jupyterを終了させて再度起動するといい。)

<img width="573" alt="75.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/db0ec938-61f6-8f47-fb01-e04ae857005a.jpeg">
Railsチュートリアル：８章(わからないとこメモです)

7章かいてたのに、途中で消してしまいました。

ということで飛ばして8章。

全部は時間の無駄ということに気づいたので、
わからん単語や考えたことの備忘録とします。



resources :users

このメソッドで

基本すべてのルートを設定できるらしい

ただ、今回は↓

Sessionリソースではフルセットはいらないので、「名前付きルーティング」だけを使います。この名前付きルーティングでは、GETリクエストやPOSTリクエストをloginルーティングで、DELETEリクエストをlogoutルーティングで扱います。

つまり手動で。

テストのセッションコントローラーにもパスを追加。

テストコントローラーは先ほどのジェネレイトで自動生成。

テストのパスはいまだ理解できてない。




セッションモデルは
Active Recordのモデルを使っていない
ユーザーもでるは
Active Recordのモデルを使っている

どこでそう定義されたのか不明。
モデルのジェネレイト？？



```
rails generate integration_test users_login
```
テストを作成する。
ここにきてテストの生成単位がブランチ名なのでは？と気づく。



ヘルパーメソッドを定義できたので、やっと、ユーザーログインを行ってセッションのcreateアクションを完了し、ユーザーのプロフィールページにリダイレクトする準備ができました。作成したコードをリスト 8.15に示します4。

↑やはりヘルパーの意味がわかってない



digestメソッドを使ってテストする。
これは便利。らしいけどいみがわからん。



ユーザー登録したときにもヘルパーをつかう。
どうやら、コントローラーの記述を簡素にするためにヘルパーを用意して
コントローラーで呼び出すという仕組みなことに気づき始める。



今回は無事herokuにプッシュ完了。
#Vue #Nuxt run method in created hook example ( ReferenceError: methodName is not defined )

write `this.methodName()`

```vue
<template>
  <div>
    <h1> Created run method </h1>
  <h2>{{ message }}</h2>
  </div>
</template>

<script>
export default {
  created () {
    this.setMessage()

    // ReferenceError: setMessage is not defined
    // setMessage()
  },
  methods: {
    setMessage () {
      this.message = "Hello"
    }
  }
}
</script>

```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3147











<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ExcelのCRUD操作ができるツールを作ってみた #golang

# はじめに
`excelize`という便利なライブラリを見つけたので、`cobra`と組み合わせてコマンドラインツールを作ってみました。
`CRUD`操作したかったので、`kubectl`調のサブコマンド構成にしてみました。

# man
<img width="1817" alt="demo.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423952/6092838e-e1e0-a81f-143e-eb8d535afd5b.jpeg">

# このツールでできること
コマンドラインから以下操作が可能です。
* ブック作成、削除
* シート作成、削除、リネーム、ダンプ(全値出力)
* セル値出力、更新

# バイナリ
以下においています。
https://github.com/kuritayu/gotools/releases

# impl

## cobra
コマンドライン部分は、
* `cobra init --pkg-name パッケージ名`
* `cobra add サブコマンド`
でテンプレを作ります。

以下はgetの例です。`Run:`の箇所をいじっていきます。
```go

	RunE: func(cmd *cobra.Command, args []string) error {
		if len(args) < 1 || len(args) > 3 {
			return errors.New("引数が不正です。")
		}
		f, err := goexcel.Load(args[0])
		if err != nil {
			return err
		}
		switch len(args) {
		case 1:
			if err := goexcel.PrintSheetName(f); err != nil {
				return err
			}
		case 2:
			if err := goexcel.Dump(f, args[1], ","); err != nil {
				return err
			}
		case 3:
			if err := goexcel.PrintValue(f, args[1], args[2]); err != nil {
				return err
			}
		}

		return nil
	},

### ポイント1
`Run:`を`RunE`に変更し、errorを返却するように変えています。

### ポイント2
今回のgetの場合、`goexcel get ブック名 シート名 セル名`みたいに使います。
get以降の文字列は、`args`に格納されているので、argsから値を取り出して、各種関数を呼び出す仕組みです。

### ポイント3
引数の数に応じて呼ぶ関数を変えるので、`switch`使って分岐しています。

## excelize
すごくシンプルなライブラリでした。以下を愚直に呼び出す感じですね。
https://github.com/360EntSecGroup-Skylar/excelize

ただ、cobraで常に`error`を返却する必要があったので、excelizeラッパーも常にerrorを返すようにしています。