OmniAICreator/Qiita-1.07M huggingface dataset:
【通信】ModbusTCPについてまとめ

----
# ModbusTCPについて
　ModbusTCPて、FA業界のいろんな産業用ロボットと通信をするために使用される代表的な通信方法の一つですよね。だけど、あまりその中身を認知している人は少なくて、すこし残念なところがあります。そんな難しくないことと、割りと結構使うので、まとめることにしました。

　下記が通信イメージです。
　　![ModbusTCP_Image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397413/eee1a5a4-a515-6d16-7d78-6ac6dbdb7357.png)


  
　ModbusTCPは、TCP/IP上でModbus通信を行うためのプロトコルです。送信者側（マスタと言ったりもします）がSocketで言うクライアント、受信者側（スレーブと言ったりもします）が、サーバという立ち位置で通信を行います。ModbusTCPには、専用のデータフォーマットがあり、適したスキーマでデータを作成し、送信してあげないと、レジスタの読み書きができません。


# ModbusTCPの電文のデータスキーマ　ヘッダ部
　ModbusTCPのデータスキーマ　ヘッダ部を下記に示します。ファンクションコードやデータスキーマ部以外のところは一回作れば、おおよそ同じで行けると思います。また、複数の送信者（マスタ）がいる場合でも、ユニットIDを用いることで、識別をすることができます。

　![ModbusTCP_DataSchema.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397413/b1c06476-f306-5b36-e746-a83bf9778ea0.png)

　個人的には、このフォーマットの中で意外と重要だなて思うのが…。トランザクションIDです。
ModbusTCPの通信て、実際はスレーブの参照テーブルが複数ある場合が多いんですけど、それを一気にみたいな！と思い…ブロックを超えたアドレス範囲でデータ操作を要求。しかし、これをやっても実は上手く行かないんですよね。ここが少しModbusTCPのめんどくさいところ。何を言っているかというと・・・

例：
　ロボット状態（1000-1010）： 状態文字列、状態詳細、エラーコード…
　ロボット座標（1020-1030）：　X,Y,Z,θ…
　　空き　　　 (1030-1039)
　ロボットI/F (1040-1045) ：　DI０,DI１,…

　例のように、ロボット状態〜ロボットI/Fの状態を一気に取りたいな！て思うのが人情ですが、実はそれはできない産ロボたちが多いです（エラーやデータが返ってこないなど）。よって、ロボット状態（1000-1010）で一つの電文。ロボット座標（1020-1030）で一つの電文。…と、トランザクションを分けて送受信をしないと行けないことが多いです。
　そんなときに、役に立つのが**トランザクションコード**、返ってくる電文の**トランザクションコード**を識別子として持っとけば、なんのブロックコードが返ってきたか一目瞭然です！送信時の順番の前後入れ替えなどは、TCPでは起こりえませんが、受信者側（スレーブ）が受信してから、内部処理を通して、送信されるため、送信者（マスタ）側が覚えている順番とは、全然違う順番で来ることが多いので、この**トランザクションコードを使用することをオススメ**します。

## ファンクションコード

よく使うファンクションコードを載せます！
　他のもあるけど、あまり使いません。一回で複数書き込み[10]とか、指定した範囲のビットを指定した範囲に書き込む[0F]とか、対応していない産ロボとかありますし、前述しましたブロック問題もあり、個人的にはあまり使わないです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397413/003b353b-7fbc-afca-9b37-6c0e645b495e.png)




## データスキーム
 - **Write**
   - Send
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397413/a81e2539-738a-3bf4-3926-68d64c43600d.png)

   - Recieve　    
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397413/272bfd6e-c0ec-abbc-f78f-adb7d62829ae.png)


 - **Read**
   - Send
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397413/c897a65e-d06f-e070-d285-11f4fc0e77cc.png)

   
   - Recieve　
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397413/f85febb4-208d-190e-71ff-03b152df3e1d.png)

## その他　気をつけること
　産ロボの場合、だいたいModbusTCPの有効無効設定とか、参照テーブルの設定とかコンフィグ画面でやる下準備があります。メーカの取説等を読んでいただき適切な方法で初期設定をしていただくのが良いです。
　
　ModbusTCPはかんたんなプロトコルで、一度電文のヘッダを作ってしまえばいろんなModbusTCP対応機器との通信ができるようになります！

あと、データスキマに書き込むデータの**エンディアン**には気をつけてくださいね。
ビックエンディアン、リトルエンディアンありますからね！

お試しあれ！


 　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　ー以上ー
----
SynchRoid(BizRobo!)でChromiumを使うときに、改行が適応されない

#何がおこったか
OutlookをDAのChromiumを使用して、自動化しようとした際
メール本文を変数で管理し、それを入力させるようにした。

しかし、ここで問題が。

改行設定しているはずのLongtext変数を貼りつけしようとしても、
いざ実際にロボットを動かすと改行が無効化されているのである。




これでは困る。


いや、見づらい。

#記入例

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

【例 -本来はこうなってほしい-】

こんにちは。
私の名前は田中太郎です。

今日はいい天気ですね。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

【例 -だが実際はこう-】

こんにちは。私の名前は田中太郎です。今日はいい天気ですね。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

#解決法

じゃあどうすればいいか。


答えはこう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420678/daae9858-05ec-40d0-a58f-30dc54b9a01b.png)


変数の改行をDA仕様に変更するというもの。
(入力する前にDSで事前処理する方がおそらくやりやすい)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420678/c66ec1e8-9686-bd77-26a6-ff2ca5327e14.png)


このように、パターンの置き換えをすることでChromiumで値を入力するときも、改行が適応されるようになる。


####動作環境
(動作環境　SynchRoid v10.4.02)
gRPCのインストール

# gRPCのビルド

CMAKEが通るようにgRPCをビルド・インストールします。
**abseil-cpp** と **protobuf** 以外は **apt** でインストールしても行けそうですが
[テストスクリプト](https://github.com/grpc/grpc/blob/v1.27.3/test/distrib/cpp/run_distrib_test_cmake.sh) と同じく **openssl** だけ **apt** でインストールしました。

```
$ sudo apt install -y \
    autoconf \
    build-essential \
    cmake \
    git \
    libtool \
    pkg-config

$ sudo apt install -y libssl-dev 
```

### grpcソースの取得
```
$ git clone --recursive -b v1.27.3 https://github.com/grpc/grpc.git
```

### abslのインストール
```
$ cd grpc/third_party/abseil-cpp
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE ..
$ make -j 
$ sudo make install
$ sudo ldconfig
```

### c-aresのインストール
```
$ cd grpc/third_party/cares/cares
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make -j 
$ sudo make install
$ sudo ldconfig
```


### zlibのインストール
```
$ cd grpc/third_party/zlib
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make -j 
$ sudo make install
$ sudo ldconfig
```

### protobufのインストール
````
$ cd grpc/third_party/protobuf/cmake
$ mkdir build
$ cd build
$ cmake -Dprotobuf_BUILD_TESTS=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release ..
$ make -j
$ sudo make install
$ sudo ldconfig
````

### gRPCのインストール
```
$ cd grpc
$ mkdir build
$ cd build
$ cmake \
    -DCMAKE_BUILD_TYPE=Release \
    -DgRPC_INSTALL=ON \
    -DgRPC_BUILD_TESTS=OFF \
    -DgRPC_CARES_PROVIDER=package \
    -DgRPC_ABSL_PROVIDER=package \
    -DgRPC_PROTOBUF_PROVIDER=package \
    -DgRPC_SSL_PROVIDER=package \
    -DgRPC_ZLIB_PROVIDER=package \
    ..
$ make -j
$ sudo make install
$ sudo ldconfig
```
---

## テスト
```
$ cd grpc/examples/cpp/helloworld
$ mkdir build
$ cd build
$ cmake ..
$ make -j
```

### サーバ
```
$ cd grpc/examples/cpp/helloworld/build
$ ./greeter_server
Server listening on 0.0.0.0:50051
```

### クライアント
```
$ cd grpc/examples/cpp/helloworld/build
$ ./greeter_client
Greeter received: Hello world
```


### ライブラリだけ使うCmake
```cmake:CMakeLists.txt
cmake_minimum_required(VERSION 3.5.1)

project(sample-grpc)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(Threads)
find_package(Protobuf CONFIG REQUIRED)
find_package(gRPC CONFIG REQUIRED)

add_executable(sample-grpc-bin ${CMAKE_CURRENT_SOURCE_DIR}/main.cc)
target_link_libraries(sample-grpc-bin 
    Threads::Threads
    protobuf::libprotobuf
    gRPC::grpc++_unsecure)
set_target_properties(sample-grpc-bin PROPERTIES OUTPUT_NAME sample) 
```
PhpStormでGitリモートから直接ローカルの別ブランチを新規作成した後に追跡ブランチを変更する

お疲れ様です。

コロナ🦠がやばいので人と喋らずにプログラミングをやりましょう。

さて、タイトルの通り、PhpStormでGitリモートから直接ローカルの別ブランチを新規作成した後に追跡ブランチを変更する方法について記載します。

**追記：
バージョン2019.3から追跡ブランチが設定されないように仕様が変更されたことをコメントで教えてもらいました！
この事象で悩まされることも無くなると思います！**

### 結論
PhpStorm上でのやり方がなさそうなのでコマンドでやります。🤣

### 環境
PhpStorm 2019.2.4
Git

### originからCheckout As...しがち
PhpStorm上で完結できて非常に便利なため、私は右下のツールバーからブランチを操作しています。
この際、Checkout&pullしてからNew Branchをすればいいだけなのですが、
それすらも面倒になった私🤪は、リモートから直接ローカルの別ブランチを新規作成しがちです。
![スクリーンショット 2020-03-02 12.50.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103853/4f0c2abb-1fbf-d7aa-d78e-5baf8b99f31a.png)

このままの状態でpushしようとすると、リモートブランチが常にCheckout元（この場合origin/master）になってしまいます。
単発なら、この画面でブランチ名を修正してpushしちゃうのですが、複数回pushする場合、誤ってCheckout元にpushしちゃったりするので、修正したいです。
![スクリーンショット 2020-03-02 12.58.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103853/3fc89d08-9119-cc07-e126-f68a67b408c2.png)

### 解決策
Source treeなら（確か）追跡するリモートブランチの変更がGUI上で行なえたと思いますが、
PhpStorm上では探しても見つかりませんでした。
（知っている方がいたら教えてください。）

なので、コマンドでやっちゃいます。

```bash
# 新規リモートブランチの場合
git push -u origin feature/test1
```

```bash
# 既存リモートブランチの場合
git branch -u origin/feature/test1 feature/test1
```

というのが面倒なので、
やはりCheckout&pullしてからNew Branchをするのが良いかと思います。
Kotlin入門:ジェネリック型

##ジェネリック型
汎用的なクラス・メソッドに対して、特定の型を紐付けるための機能のこと。

入力例:

```Kotlin
val data:Array = arrayOf(1,2,"3.14")
```
これに対しジェネリック型を使用すると

```Kotlin
            //<要素型>
val data:Array<Int> = arrayOf(1,2,3)
```
こうなります。
これが特定の型を紐付けるということです。

###ジェネリック型の定義

```Kotlin
class Generic<E>(var value:E){
    fun getString():E{
        return this.value
    }
}
fun main() {
①  val gene1 = Generic<String>("Hello")
    println(gene1.getString())
    println(gene1.getString() is String)
②  val gene2 = Generic(123)
    println(gene2.getString())
    println(gene2.getString() is Int)
}
```

①で、`Generic`クラスに`String`型を割り当てて代入しています。
これで`gene1`の`E`型は`String`だと判定されるようになります。

②で、`Generic`クラスに`Int`型を割り当てて代入しています。
これで`gene2`の`E`型は`Int`だと判定されるようになります。
また、<要素型>は省略することもできます。

実行結果は以下の通りです。

```Kotlin
Hello
true
123
true
```

###型引数の制約

渡す型を制限したいとき、`<E:super>`の形式で型引数を指定します。
これで`E`型は`super`、もしくはその派生クラスであるという意味になります。
入力例:

```Kotlin
open class parent(){}
class child():parent(){
    val value = "Hello World"
}
//E:parentでE型はparentまたはその派生クラスでならなければならないという意味になります
class Generic<E:parent>(var value:E){
    fun getString():E{
        return this.value
    }
}
fun main() {
    val gene = Generic<child>(child())
    println(gene.getString().value)
}
```

##ジェネリック関数
引数や戻り値型を、関数を呼び出す際に決められる関数のこと。

構文:

```Kotlin
fun <E> name(args:type):rtype{}
```

`E`:型引数
`name`:関数名
`args`:引数
`type`:引数の型
`rtype`:戻り値の型
関数名の直前に`<>`で型引数を宣言します。

```Kotlin
fun main() {
    println(sayHello("Hello World"))
    println(sayHello<String>("Hello World"))
}
fun <E> sayHello(greeting:E):E = greeting
```
引数の型から、暗黙的に型引数の型を判定するため、特別な構文は不要です。
関数名の直後に`<>`の形式で型を明示することもできます。
実行結果は以下の通りです。

```Kotlin
Hello World
Hello World
```
呼び出し元メソッドをinspectを使わずに判別する

同ディレクトリ上に3つのファイルがある。

```python:test.py
import sys

class Aiueo(object):

    def common(self):
        print(1)
        print(2)
        print(3)

    def func_a(self):
        print(4)
        self.common()

    def func_b(self):
        print(5)
        self.common()
```

```python:test_a.py
import test
test.Aiueo().func_a()
```

```python:test_b.py
import test
test.Aiueo().func_b()
```

test_a.pyを実行すれば4123と打たれ、
test_b.pyを実行すれば5123と打たれる。
これが現在の仕様。

---

ところが後になって仕様変更があり、
4123、5123ではなく、4123、513と打つように変更する必要が出てきた。

ただし、チームの決めでinspectのimportはできない。
また、現実はこんな単純なprint文ではなく、
もっと複雑に組み込まれているので共通関数を崩すのも億劫。

まぁフラグ用の引数を渡してあげればいいだけの話なんだけど、
それ以外でもなんとかならないかちょっと調べてみた。

# 結論

sysはimport済みだったので、正体不明のアトリビュート（？？？）を使ってなんとかなった。

```python
if 'func_a' in str(sys.modules):
```

まだまだ勉強が足りない。
はじめてのFlask導入〜Blueprint適用

タイトルのことをなるべく簡単に行ってみます。

Blueprintを使用すると、アプリケーションの機能を分割して実装することができます。
肥大化したプロジェクトを整理するための手段として、公式でもBlueprintが推奨されています。

## Flaskのインストール

```
$ sudo pip3 install flask
```

## ディレクトリ構成

```console
$ cd ~/workspace/sample-flask/

$ ls
server.py
```

```server.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def func_1():
    return 'Hello world'

@app.route('/test')
def func_2():
    return 'Test'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)
```

## 実行コマンド

```console
$ python3 server.py
 * Serving Flask app "server" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 337-601-528
127.0.0.1 - - [02/Mar/2020 11:18:06] "GET / HTTP/1.1" 200 -
```


WARNINGはとりあえず無視して、
ブラウザから127.0.0.1にアクセスするとHello worldと表示されます。
続けて、ブラウザに127.0.0.1/testにアクセスすると今度はTestと表示されます。

## Blueprintで分割する

"/test"を別ファイルに分割してみます。
funcというディレクトリを作成し、その下にtest.pyを作成しました。

## ディレクトリ構成

```console
$ cd ~/workspace/sample-flask/func

$ ls
__init__.py
test.py
```

Blueprintをimportして、
切り出したtest.pyでBlueprintオブジェクトを生成します。

```test.py
from flask import Blueprint

# Blueprintのオブジェクトを生成する
app = Blueprint('func', __name__)

@app.route('/test')
def func_2():
    return 'Test'
```

server.py側で、分割したBlueprintを登録します。

```server.py
from flask import Flask
from func import test

app = Flask(__name__)
# 分割したblueprintを登録する
app.register_blueprint(test.app)

@app.route('/')
def func_1():
    return 'Hello world'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)
```

実行してルーティングが上手くいっているか確認してみます。

先ほどと同じようにブラウザから127.0.0.1にアクセスするとHello worldと表示され、
続けて、ブラウザに127.0.0.1/testにアクセスすると今度はTestと表示されます。

上記が無事上手く行けば、Blueprintを使用して分割が出来ています。

## 参考
https://www.subarunari.com/entry/2017/10/11/003225
WindowsにC#実行環境を整えてみたまとめ

　この記事では私がVisualStudioを用いず、コマンドプロンプトから.csファイルをコンパイル、実行するまでをまとめました。

### 実行環境
・Windows10

　VisualStudioを用いずにC#を実行するには、まず、.NET Frameworkをインストールする必要がありますが、.NET FrameworkはWindowsVista以降のWindowsOSに標準インストールされています。「C:\Windows\Microsoft.NET」の「Framework」または「Framework64」が.NET Frameworkのフォルダです。Framework64はWindowsの64bit版用のものになります。![frameworkfile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481365/ce020daf-99c9-830e-5d51-fc64ff656789.png)

今回は64bit版で進めました。

Framework64ファイルの中にある「v2.0.50727」「v3.5」「v4.0.30319」の３つのファイルの中に、それぞれC#のコンパイラである「csc.exe」がありました。
確認したところ、
私のPCではv2.0.50727の中のコンパイラが最新バージョンのようなので、これを使うことにしました。


―――――――――
（追記：2020/03/26）Windows標準の.NET FrameworkのC#コンパイラはv4.0.30319のものが最新でした。私が勘違いしてしまった理由としては、v4.0.30319のcsc.exeでコンパイルした際、cmdに


```
Microsoft (R) Visual C# Compiler version 4.8.3752.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.

This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5,
which is no longer the latest version. For compilers that support newer versions of the C# programming language,
see http://go.microsoft.com/fwlink/?LinkID=533240
```

というメッセージが表示され、これを私はコンパイルが失敗したものだと誤解してしまいました。このメッセージはコンパイラが古いからこのサイトから最新版を用意しろという注意だけで、実際にはコンパイルができることを確認しました。
――――――――――――
![compilerfile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481365/5e98b58d-96bc-455d-0ecc-618cf8c1cdd1.png)

　コンパイラをどこでも起動できるようにするため、環境変数を指定します。コントロールパネル>システムの詳細設定>環境変数 を開き、ユーザー環境変数のPathを選択し、編集を選択、「C:\Windows\Microsoft.NET\Framework64\v2.0.50727」の記述を追加しました。これでパスが通ったはずなので、さっそくコマンドプロンプトから実行してみます。あらかじめ用意した「Test.cs」をコンパイルしてみます。

```cs:Test.cs
using System;

class Test
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        Console.WriteLine("こんにちは");
    }
}
```
　![cmd1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481365/4a1dba5b-4237-bfcd-0da7-5031778b477c.png)

これでどうやらコンパイルが成功したようです。コンパイルしたことでTest.exeが作成されていました。
![cmd2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481365/e9bb1d22-db1f-9052-d830-0f42d3f12358.png)

「Test.exe」を実行します。![cmd3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481365/7210e904-1729-2de1-a995-fc89e74b840c.png)

無事に実行できたようです。しっかりと「Hello World」「こんにちは」の文字列がコンソールに反映されていました。

.exeを実行するコマンドを叩かず、.csのコンパイルが完了した時点で.exeを実行することもできるようなので、今後はその方法で実行できるようにしたいと思います。
JSONとは？JSONのフォーマット

JSONとは *JavaScript Object Notation* のこと。

JavaScriptのオブジェクト表記を使ってデータ構造を定義できるフォーマット。JavaScript以外の言語でもサポートしているので重宝される。

JSONファイルの例

```JSON:sample.json
[
 {"id": 1, "name":"商品A", "price":1280},
 {"id": 2, "name":"商品B", "price":480},
 {"id": 3, "name":"商品C", "price":980}
]
```

### 注意点

- 文字コードはUTF-8にすること。

- JavaScriptでは | キー:値 |のキーは自動的に文字列型とみなされるが、JSONでは明示的に""で括る必要がある。さもないとエラーになる。

```JSON:エラーの例1
[
 {id: 1, name:"商品A", price:1280},
 {id: 2, name:"商品B", price:480},
 {id: 3, name:"商品C", price:980}
]
```

- 値を文字列として扱いたい場合はダブルクオーテーション""で括る必要がある。JavaScriptのようにシングルクオーテーションを使うとエラーになる。

```JSON:エラーの例2
[
 {"id": 1, "name":'商品A', "price":1280},
 {"id": 2, "name":'商品B', "price":480},
 {"id": 3, "name":'商品C', "price":980}
]
```

- 配列の最後に「,」(ビリオド)があるとエラーになる。**ループで回してJSON配列を生成する際には最後に「,」が入ることがよくあるので要注意**

```JSON:エラーの例3
[
 {"id": 1, "name":'商品A', "price":1280},
 {"id": 2, "name":'商品B', "price":480},
 {"id": 3, "name":'商品C', "price":980},
]
```
phpMyAdminにPHPのバージョンが古いと怒られた時の対処法

#状況
[AWS公式のチュートリアル](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-LAMP.html#test-lamp-server-alami)に沿ってEC2インスタンス上にLAMPを構築しようとしたらphpMyAdminアクセス時に以下のエラーが出てつまずいた。

`PHP 7.1.3+ is required. Currently using PHP 5.6.`

環境は以下の通りです。
AMI: Amazon Linux AMI (fedora)
Version: 2018.03

チュートリアルの手順に沿って以下のパッケージをインストールしました。

```
$ sudo yum update -y
$ sudo yum install -y httpd24 php72 mysql57-server php72-mysqlnd
```
- Apache HTTP サーバー 2.4
- PHP 7.2
- MySQL 5.7
- MySQL Native Driver(拡張モジュールライブラリ) 7.2

# 調査したこと

ターミナルでPHPのバージョンを確認すると確かに7.2になっている。

```
ec2-user:/etc $ php -v
PHP 7.2.27 (cli) (built: Feb 18 2020 22:55:04) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
```

phpinfoをApacheのドキュメントルートに出力し、ブラウザからアクセスしてみる。

```
$ echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php
```

上記コマンドを実行した後、`http://[パブリックIP]/phpinfo.php`にアクセス。
※EC2のパブリックIPはEC2コンソールの左側インスタンスメニューから確認可能。

すると、phpinfoではPHPのバージョンが5.6で認識されていた。

# 解決方法
旧バージョンのPHPをアンインストールしてApacheを再起動する。

```
$ sudo yum remove php56*
$ sudo service httpd restart
```

その後、`http://[パブリックIP]/phpinfo.php`にアクセスしてみるとPHP7.2で認識された。
PHPMyAdminも正常にアクセスできた。
【Swift】Structでもmutatingじゃないメソッドなら再帰できる

気付き、ですね。

# 思い込み
https://stackoverflow.com/questions/36080491/swift-struct-type-recursion

この辺を見て、Swiftで再帰する＝クラスを使わなければいけない（Enumは再帰Enumがある？）と短絡的に思っていました。

# 気付き
しかし再帰のときに問題なのは、mutatingなメソッドであって、immutableなメソッドなら再帰できることに気付きました。

# つまり
```swift
struct Some {
    func some(input: String) {
        let word = input
        if word != "これで終わりや" {
            print(word)
            some(input: "これで終わりや")
        } else { print("returnするで"); return }
            print("終わるで")
    }
}

Some().some(input: "はじめや")
```

PlayGroundで実行すると、

```swift
はじめや
returnするで
終わるで
```

が出力するので、一度だけ再帰的にメソッドが呼ばれて、returnして、その後呼び出し元のメソッドに処理が返ったのがわかります。
ただ色々書いてみると感じますが、immutableな再帰関数ってかなり使いづらいので、再帰したいなら素直にClass使うのが推奨ですかね〜
PyCall.rb でメモリリークみたいな現象が起こったので workaround

# まさかのメモリリーク？
もはやぼくにとって手放せなくなった[mrknさんのPyCall.rb](https://github.com/mrkn/pycall.rb)ですが、メモリリーク的な現象に遭遇して困ったので逃げ道も含めて情報共有しておきます。

# 検証コード　
まずこちらは何の問題もない Python コードです。ふつうに動き、問題は起きません。

```Python
import cv2
for i in range(1000):
  img = cv2.imread("foo.jpg")
  print(img.shape)
```
これを PyCall を使って Ruby で書きます。

```Ruby
require "pycall"
cv2 = PyCall.import_module("cv2")
1000 times do
  img = cv2.imread("foo.jpg")
  puts img.shape
end
```
するとどうでしょう。なんとメモリがどんどん消費されていくではありませんか！どうもPyCall内で使われたメモリは参照が残るのかGCが処理してくれないようです。`img = nil` とか `cv2 = nil` とかしても無駄でした。

# workaround
で結局どうしたかと言うと格好悪いですがプロセス切り離しました。多少パフォーマンス落ちますが、さすがにここまでやれば大丈夫なようです。

```Ruby
require "pycall"
def quarantine
  cv2 = PyCall.import_module("cv2")
  img = cv2.imread("foo.jpg")
  puts img.shape
end

1000.times do
  Process.waitpid(
    fork {
      quarantine
    }
  )
end
```

誰かもっとスマートなやり方見つけたら教えてください。
ごちうさでわかるER図と多重度

#対象
・ごちうさを知っている
・ER図がよくわからない
・ネタ記事でもいい
#ER図とは
簡単に言うとDB(データベース)の設計図です。ER図では多重度というものを表し、
ちなみにERはそれぞれ


| E | R |
|:-:|:-:|
|[Entity](https://www.google.co.jp/search?ei=zntaXrrcDpD70gSKg5PoDg&q=Entity&oq=Entity&gs_l=psy-ab.3..0l8.7878.7878..8677...0.1..0.98.98.1......0....2j1..gws-wiz.......0i71.Nvx5OOt1xBc&ved=0ahUKEwi6-_7cgvfnAhWQvZQKHYrBBO0Q4dUDCAs&uact=5)[^1]|[Relationship](https://www.google.co.jp/search?ei=5ntaXv33DYKlmAWomq6wBg&q=Relationship&oq=Relationship&gs_l=psy-ab.3..0l8.14703.14703..15470...0.0..0.84.164.2......0....2j1..gws-wiz.......0i67j0i7i30.CTmHXyFMVdY&ved=0ahUKEwj9grfogvfnAhWCEqYKHSiNC2YQ4dUDCAs&uact=5)[^1]|
|[エンティティ](https://www.google.co.jp/search?ei=xHtaXuKCCsiVr7wPsYKGmAU&q=%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%83%86%E3%82%A3&oq=%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%83%86%E3%82%A3&gs_l=psy-ab.3..0i67l2j0l6.8766.8766..9405...0.1..0.78.78.1......0....2j1..gws-wiz.......0i71.9l7ymdPycNM&ved=0ahUKEwji9JfYgvfnAhXIyosBHTGBAVMQ4dUDCAs&uact=5)[^1]|[リレーションシップ](https://www.google.co.jp/search?ei=F3taXt2MD5CHoATgn5ioAg&q=%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B7%E3%83%83%E3%83%97&oq=%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B7%E3%83%83%E3%83%97&gs_l=psy-ab.3..0i71l8.0.0..2557...0.2..0.0.0.......0......gws-wiz.dzEQywo84KI&ved=0ahUKEwid9N2FgvfnAhWQA4gKHeAPBiUQ4dUDCAs&uact=5)[^1]|
のような意味を持っています。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374827/ae897e54-2e45-c0a4-a4e3-f0407c501dbb.png)
引用 : [若手プログラマー必読！５分で理解できるER図の書き方５ステップ](https://it-koala.com/entity-relationship-diagram-1897)

#多重度とは
エンティティからエンティティまでの関係のことを表します。
「1」または「多」(0以上 1以上)と表され
・１対１
・１対多
・多対多
などと呼びます。
##１対１
１対１というのは「０ではないし２以上でもない１という存在」対「０ではないし２以上でもない１という存在」という絶対に変わらない関係性のことを指します。
ごちうさで言うとチノとタカヒロの親子関係は「子１ー親１」で、１対１と言えます。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374827/8d452974-7291-8405-8209-da89bccd4ab0.png)

##１対多
１対多は先程の「０ではないし２以上でもない１という存在」対「０または１以上の存在」という関係性のことです。
この関係性はごちうさという１つのコンテンツに対してキャラクターという多が表されているので「１対多」と言えます。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374827/32174bf8-5edb-4f4e-c5cf-e1c9205592fe.png)

##多対多
ところでカップリングという言葉はご存知ですか？？？
[カップリング](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%83%E3%83%97%E3%83%AA%E3%83%B3%E3%82%B0_(%E5%90%8C%E4%BA%BA))とはキャラクターの恋愛関係を表す言葉らしい。(よく知らずに使ってた)
世の中には多くのカップリングがあります。ココチノだったりチノココだったり、シャロチノなんかもいいですよね！
ここまで読んでくれた方はおそらくお気づきだとは思いますが、この関係性というのは実は「多対多」なのです！
「０または１以上の存在」対「０または１以上の存在」の関係性に当てはまっています。
ちなみに↓の場合は「１以上のキャラクター」対「１以上のキャラクター」になります。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374827/9dcca2de-5a93-32a5-301d-260c44444279.png)

#おわり
いかがだったでしょうか？(定型文)
個人的には楽しみながら書けたので良かったです。


[^1]: ~~クソリンク~~
Rails6 のちょい足しな新機能を試す 122（enum negative warning 編)

# はじめに

Rails 6 に追加された新機能を試す第122段。 今回は、`enum negative warning` 編です。
Rails 6 では、 `enum` の要素で、 `not_` で始まるものがあるとワーニングが出るようになっています。
これは、Rails 6 では、 `enum` を使うと `not_` がつくデフォルトスコープが自動的に定義されるようになったからです。

Ruby 2.6.5, Rails 6.0.2.1, Rails 5.2.4.1 で確認しました。 (Rails 6.0.0 でこの修正が入っています。)

```shell
$ rails --version
Rails 6.0.2.1
```

今回は、 name と generation の属性を持つ Child モデルを作り、enum を定義してワーニングを確認します。

# Rails プロジェクトを作る

Rails プロジェクトを新たに作成します。

```shell
$ rails new rails_sandbox
$ cd rails_sandbox
```

# Child モデルを作る

`name` と `generation` を持つ `Child` モデルを作ります。

```shell
$ bin/rails g model Child name generation:integer
```

# Child モデルに enum を追加する

enum を定義します。このとき要素として、 `baby` と `not_baby` を定義します。

```ruby:app/models/child.rb
class Child < ApplicationRecord
  enum generation: %i[baby not_baby]
end
```

# マイグレーションを実行する

マイグレーションを実行します。

```shell
bin/rails db:create db:migrate
```

# rails console で確認する

`rails c` を実行します。

```shell
$ bin/rails c
Running via Spring preloader in process 344
Loading development environment (Rails 6.0.2.1)
```

`Child` を実行すると次のように2行のワーニングが出ます。

```
irb(main):001:0> Child
An enum element in Child uses the prefix 'not_'. This will cause a conflict with auto generated negative scopes.
Creating scope :not_baby. Overwriting existing method Child.not_baby.
=> Child (call 'Child.connection' to establish a connection)
```

# Rails 5 では

Rails 5.2.4.1 では、 `not_baby` のスコープが定義されないので、ワーニングも出ません。


# 試したソース

https://github.com/suketa/rails_sandbox/tree/try122_enum_negative_warning


# 参考情報

* [Add a warning for enum elements with 'not_' prefix.](https://github.com/rails/rails/pull/36380)
* [Rails6 のちょい足しな新機能を試す79（enum negative scope編）](https://qiita.com/suketa/items/93fa8a1324b83cbe1504)
【AWS】【SAA対策】SQS

# SQS(Simple Queue Service)
## サービス概要
分散されたソフトウェアシステムとコンポーネントを統合および分離することができる、安全で耐久性があり、利用可能なホストされたキューを提供するサービス。
デッドレターキューやコスト配分タグなど、一般的な構造を提供。
標準および FIFO キューの両方がサポート。

## 特徴
- キューに入れたメッセージを複数の受信者が並列で実行可能。
- 日次のバッチ処理など1日数時間かかる処理を分散して高速処理を可能にする。
- Amazon SQS キューとの間でメッセージを送受信できるユーザーは、お客様が管理。
- サーバー側の暗号化 (SSE) は、AWS Key Management Service (AWS KMS) で管理されたキーを使用してキューのメッセージのコンテンツを保護。
- 可視性タイムアウト：コンシューマーがメッセージを受信してから可視性タイムアウトの間、他のコンシューマーなどにキューを配信しない。
- メッセージ保持期間：SQSに登録されてから処理されずにSQSに溜まったメッセージが削除されるまでの期間。
- メッセージタイマー：キューに追加するメッセージの初期非表示期間。たとえば、タイマーを 45 秒に設定してメッセージを送信すると、そのメッセージはキューに入ってから 45 秒間はコンシューマーに表示されない。
- デッドレターキュー：正常に処理 (消費) できないメッセージの送信先として、他のキュー (ソースキュー) を使用する。


## 種類やタイプ
|                  |  スタンダードキュー        |   FIFOキュー        |
|:-----------------|:------------------|:-------------------|
| スループット            |  API アクションあたり、ほぼ無制限の数の1秒あたりのトランザクション (TPS) をサポート。 |   デフォルトで、バッチ処理を使用して、API アクションごとに1秒あたり最大 3,000 件のメッセージ (TPS) がサポート。バッチ処理を行わない場合、API アクション ごとに1秒あたり最大300件のメッセージがサポート|
|配信          | 少なくとも1回の配信:メッセージは少なくとも1回は確実に配信されるが、複数のメッセージのコピーが配信されることもあり。 | 1回だけの処理:メッセージは1度配信されると、ユーザーがそれを処理して削除するまでは使用可能な状態に保たれる。 |
|配信方式     | ベストエフォート型の順序付け:メッセージが送信されたときと異なる順序で配信されることがある。 | 先入れ先出し配信:メッセージが送信または受信された順序が厳密に保持。|
| ユースケース           |スループットを重視する場合 | 順序を重視する場合      |

## ベストプラクティス
- 一時的なトラフィック増として、スパイクが発生する処理では、SQSにキューを蓄積し、後続する処理ノードが順次処理する冗長構成をとることで、スパイクを吸収できる。
- SQSのキューをEC2で処理する場合で、EC2のAutoScalingを使用するケースとして、キューのサイズに基づくAutoScalingのターゲット追跡スケーリングを設定し、CloudWatchで監視するとよい。（ex.キューのサイズによってEC2インスタンスを追加）
- 新たにメッセージング機能アプリケーションを構築する場合は、SQSの利用が推奨されるが、既存のアプリケーションのメッセージング機能を移行する場合はAmazon MQを利用することが推奨される。
- デフォルトオプションでSQS作成時、メッセージ保持期間は4日間。（1分～14日までで設定可能。）もしこの保持期間が過ぎていれば、メッセージは削除される。
- 優先度付きキュー＝優先度の高きキュー/低いキューを用意し、クライアント側ではジョブの優先度でどちらのキューに登録するかを決め、ワーカー側では優先度の高いキューから優先的に実施する。
- 可視化タイムアウトが設定されている場合、有効期限内はほかのワーカーでの処理はされないが、期限を過ぎたら、別のワーカーへうつる。

## 用語
- プロデューサー・・・メッセージをSQSに送信するアプリケーション
- コンシューマー・・・SQSからメッセージをポーリングするアプリケーション
aws sts get-session-token の結果を環境変数に入れるシェルスクリプト

MFA が必要な IAM ユーザで AWS CLI を利用する場合、GetSessionToken API を用いて一時的な Credentials を取得する必要がある。

参考： [AWS CLI 経由で MFA を使用してアクセスを認証する](https://aws.amazon.com/jp/premiumsupport/knowledge-center/authenticate-mfa-cli/)

しかしこれが面倒くさい。

`aws sts get-session-token` コマンドを実行して表示された JSON から Credentials を抜き出して `~/.aws/credentials` に書き込むなり環境変数に設定するなりを毎回手作業でやらなければならない。

そこで、環境変数へ設定する作業を自動でやってくれるシェルスクリプトを書いた。

``` sh:set-aws-session-token
#!/bin/sh -eu

if [ ! -p /dev/stdin ]; then
  echo "Usage:"
  echo "  aws sts get-session-token [options] | source ${0}"
else
  json=$(cat - | tr -d '\n')
  export AWS_ACCESS_KEY_ID=$(echo ${json} | sed -E 's/^.*"AccessKeyId": *"([^"]+)".*$/\1/')
  export AWS_SECRET_ACCESS_KEY=$(echo ${json} | sed -E 's/^.*"SecretAccessKey": *"([^"]+)".*$/\1/')
  export AWS_SESSION_TOKEN=$(echo ${json} | sed -E 's/^.*"SessionToken": *"([^"]+)".*$/\1/')
  env | grep AWS
fi
```

macOS では動作確認をしているが、GNU 版 sed が入っている Linux では動かないかもしれない。
jq が入っている人は sed 部分を jq で書き直しても良さそう。

このスクリプトを PATH が通ってるどこかに置いておいて、以下のように使う。

``` console
$ aws sts get-session-token \
    --serial-number arn:aws:iam::0123456789:mfa/username \
    --token-code 000000 \
    | source set-aws-session-token
```

手作業でコピペする必要がなくなって便利。
MAMP の MySQL をコマンドラインから触りたい

PHP の学習で作った MAMP 環境の MySQL に phpadmin ではなく CLI からアクセスする方法を後で見返すために書きます。
環境
macOS10.14.6 Mojave
MAMP5.6(394)
## MySQL の場所
```bash
/Applications/MAMP/Library/bin
```
.bash.profile などにPATH通せばいいんですが、個人的都合で homebrew で入れた MySQLの方を優先したい。
なので、 /Applications/MAMP/Library/bin に移動してから

```bash
./mysql -u ユーザー名 -p
```
または

```bash
/Applications/MAMP/Library/bin/mysql -u ユーザー名 -p
```
【AWS】ELBのログをS3に保存して、Athenaで検索しよう

こんにちは

皆さんAWS使ってますか？
LB、使ってます？？

AWSのLBもいくつか種類がありますね
https://docs.aws.amazon.com/elasticloadbalancing/index.html
弊社も大変お世話になっています

そんなこんなでLBのアクセスログをS3に保存するととてもいいことがあります。
https://tech.basicinc.jp/articles/46
詳しいやり方はこちらのサイト様を参考にして頂いて・・・
S3に保存するとAthenaでSQLを使って検索が出来るようになるので非常に便利です。

よく使うクエリはこんな感じです。

○該当IPがアクセスしているURLを検索する

```SQL
select
  request_ip, url
from
  ELBログの保存先
where
  elb_name = ‘たくさんあると絞ってあげたほうがわかりやすいです’
    AND
  (regexp_like(request_ip, ‘111.111.111.111’))
limit 1000;
```

こんな感じで
○該当URLにアクセスしているIPを割り出す
○該当URLにアクセスしているIPのカウント数
○該当日時にアクセスしてきたIPやURLを割り出す
などが検索可能です。

更に応用としてはUAでGoogleBotがクローリングしているURLを割り出したり
（もちろんUAは偽装できてしまうので正確とは言えないですが・・・参考までに）
日毎のGoogleBotの件数を見てみたり（↓）

```SQL
SELECT substr(request_timestamp,
         1,
        10) AS ymd,
         count(*) AS cnt
FROM ELBログの保存先
WHERE  elb_name = ‘たくさんあると絞ってあげたほうがわかりやすいです’
        AND user_agent LIKE '%Googlebot%'
GROUP BY  substr(request_timestamp, 1,10)
ORDER BY  ymd;
```

あとはprocessing_time（何種類かあります）でorder by descすれば処理が重いページもわかったりします。
便利ですね！！

皆さんもELBのログをS3に保存して素晴らしいAthenaライフをお送りください！！
【改良】M5StickC UiFLOWブロックプログラミングで倒立振子(ピッチ角版)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/adad83dd-33cd-966c-5ea4-d4fb7e94912f.png)

##■はじめに
###以前書いた [「M5StickC UiFLOWのブロックプログラミングで倒立振子」](https://qiita.com/drafts/7b8c0559755549f8c96a/edit) の改良版です。大幅に単純化され安定性も向上しました。たったこれだけのプログラムで夢の倒立振子。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/16b7f233-be96-06fb-0544-e393e1a0e31e.png)

#■以前の記事からの主な変更点
***①加速度とジャイロから計算していた姿勢をピッチ角ブロック一発で取得できるようにし、大幅にプログラムが短くなりました。***

***②キャリブレ操作不要になり、いきなり立たせられるようになりました。***

***③飛躍的に安定性が向上しました。これは推測ですが「ピッチ角」ブロックの内部で、高精度と噂の「Madgwickフィルタ」を使っているためではないかと思います。***
(IDE版のM5.MPU6886.getAhrsData(&pitch,&rall,&yaw)関数は、Madgwickフィルタを使っている事を確認できています。)


#■見よ、この安定感
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ブロックプログラミングで倒立振子。<a href="https://twitter.com/hashtag/M5StickC?src=hash&amp;ref_src=twsrc%5Etfw">#M5StickC</a> <a href="https://twitter.com/hashtag/UiFLOW?src=hash&amp;ref_src=twsrc%5Etfw">#UiFLOW</a> のピッチ角ブロックを使った超超簡単 <a href="https://twitter.com/hashtag/%E5%80%92%E7%AB%8B%E6%8C%AF%E5%AD%90?src=hash&amp;ref_src=twsrc%5Etfw">#倒立振子</a> 。なかなかの安定っぷり。Qiita投稿準備中。 <a href="https://t.co/rF2IlQz29x">pic.twitter.com/rF2IlQz29x</a></p>&mdash; Google Homer (@google_homer_) <a href="https://twitter.com/google_homer_/status/1233995800981557250?ref_src=twsrc%5Etfw">March 1, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
##■車体の作り方は下記記事を見て下さい
###[実質500円&100Stepで作る超簡単「 ゆるメカトロ的 M5StickC 倒立振子」](https://qiita.com/Google_Homer/items/d0cdb2975491a5ea8129)

##■下記からブロックプログラムをダウンロードできます

###[BalanceCar(PitchVer).m5f](https://drive.google.com/file/d/1paTe5-b0P-t7LwkKxadrAvYilAarkjEd/view?usp=sharing)
UiFLOWのブロックプログラムのシェア方法がわからなかったので、とりあえずGoogle Driveに上げてみました。アクセスできない場合は連絡下さい。これをダウンロードして、UiFLOWで読み込んで下さい
##■調整方法
###下記4項目をコツコツ調整して下さい。かなり根気いります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234533/fe3661b0-b942-44cf-b1bf-de915adabed8.png)

##■最後に
PIDロジック部の細かい作用については未だ腹落ちしていないのですが、今回姿勢推定を「ピッチ角」ブロックに委ねる事で、PIDロジックに集中できるようになりました。***今後は、PID部の係数について簡単に調整する方法なども追及***して行こうと思います。そして、***もっともっと倒立振子のハードルを下げて***行こうと思います。
2群間の検定の選定と計算方法（Wilcoxonの符号付順位和検定）

## 検定の種類
大きく分けると

1. パラメトリック：母集団のデータが仮定した分布に従っている場合（正規性や等分散など）
2. ノンパラメトリック：母集団の分布に決まりはない

の2種類に分類されます．

## 対応のあるデータ，対応のないデータ
検定をする際には，「対応がある」か「対応がない」かを考える必要があります．

- **対応がある**
「対応がある」とは，3人に実験を実施したとすると，3人全員が全ての条件の実験を実施することを指します．
例えば，実験条件が3条件（A，B，C）あった場合，3人全員が全ての条件の実験を行った場合，対応のあるデータとなります．

- **対応がない**
一方で，「対応がない」とは，3人（D，E，F）に実験をした際，3人それぞれが異なる条件で実験を実施することを指します．
例えば，実験条件が3条件（A，B，C）あった場合，被験者DはA，Bの2条件，被験者EがA，B，Cの3条件，被験者FがB，Cの2条件の実験を行う場合などです．

## 2群間の検定の代表的な例
2群間の検定は，パラメトリックかノンパラメトリックか，対応があるかないかで決定します．代表的な検定を以下にあげます．他にも検定の種類はあるので，気になる人は調べてみてください．

| |　対応のある |　対応のない　|
|:-:|:-:|:-:|
|**パラメトリック**|対応のあるt検定|Studentのt検定|
|**ノンパラメトリック**|Wilcoxonの符号付順位和検定|Man-WhitneyのU検定|

##実際に考えてみる
10人の被験者に条件X，条件Yの実験を実施し，楽しさを5段階のリッカート尺度(1:全く楽しくない―5:非常に楽しい)で評価を行った場合を考えてみましょう．10人のアンケート結果がそれぞれ

|被験者|A|B|C|D|E|F|G|H|I|J|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|条件X|4|3|4|3|5|5|3|2|5|2|
|条件Y|2|3|2|2|3|3|4|3|2|3|

だったとき，条件Xと条件Yの間に統計的な差が存在するのか調べます．検定方法の選定は以下の観点から行います．

- 正規性
正規性の検定(Shapiro-Wilk検定)を行った結果，条件Xは正規分布に従っているが，条件Yは正規分布に従っていないので，今回使用する検定は**ノンパラメトリック検定**となります．

- 対応のありなし
今回の例では，10人全員が条件X，条件Yの両方の実験を行っているので，**対応のあるデータ**となります．

以上より，今回は正規性のない，対応のある2群間の検定である，**Wilcoxonの符号付順位和検定**を使用します．

### Wilcoxonの符号付順位和検定
**※この節では検定の計算方法を説明しますが，Rなどの統計ソフトを用いて検定を行う方が楽なので，実際に検定を行う際は統計ソフトを使用することをお勧めします．**

まず，各被験者の条件Xと条件Yの結果の差の絶対値Zを取ります．

|被験者|A|B|C|D|E|F|G|H|I|J|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|条件X|4|3|4|3|5|5|3|2|5|2|
|条件Y|2|3|2|2|3|3|4|3|2|3|
|差の絶対値Z|2|0|2|1|2|2|1|1|3|1|

次に絶対値Zの小さい順に順位付けを行います．同順位の要素が存在する場合は，順位の平均を各要素に割り当てます．例えば，2位が二つ存在した場合，(2+3)/2=2.5を各要素に割り当てることになります．ただし，条件Xと条件Yの差がない，つまり絶対値Zが0となる場合，順位付けは行わず，その分標本数も減らします（今回は被験者Bを除外するため，標本数は9となります）．

|被験者|A|C|D|E|F|G|H|I|J|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|データZ|2|2|1|2|2|1|1|3|1|
|順位|6.5|6.5|2.5|6.5|6.5|2.5|2.5|9|2.5|

次に，「条件Xのスコア>条件Yのスコア」となっている被験者の順位の合計値Tと，「条件Xのスコア<条件Yのスコア」となっている被験者の順位の合計値tをそれぞれ算出します．

T=6.5+6.5+2.5+6.5+6.5+9=**37.5**
t=2.5+2.5+2.5=**7.5**

求めたTとtで，小さい方を検定に使用します．今回はt=7.5が小さいのでこちらを使用します．
これ以降はN数（標本の数）に応じて作業内容が変わります．

- N数>25の場合<br>
統計量Wを考えます．

```math
W=\frac{|t-\frac{N(N+1)}4|}{\sqrt{\frac{N(N+1)(2N+1)}{24}}}
```

この統計量Wは標準正規分布N(0,1)に従うものです．よって，両側検定で有意水準p=0.05の検定（帰無仮説（条件Xと条件Yの間に差がない）が成立する確率が5%以下であるかどうか）を行いたい場合，Wが1.96以上のとき有意差ありとなります．この値は標準正規分布表から求めることができます．

- N数<25の場合<br>
統計量WがN数に応じて，下表の数値以下のとき，統計的有意差があると判断します．

|N数|両側 p<0.05(5%)|両側 p<0.01(1%)|片側 p<0.05|片側 p<0.01|
|:-:|:-:|:-:|:-:|:-:|
|5|-|-|0|-|
|6|0|-|2|-|
|7|2|-|3|0|
|8|3|0|5|1|
|9|5|1|8|3|
|10|8|3|10|5|
|11|10|5|13|7|
|12|13|7|17|9|
|13|17|9|21|12|
|14|21|12|25|15|
|15|25|15|30|19|
|16|29|19|35|23|
|17|34|23|41|27|
|18|40|27|47|32|
|19|46|32|53|37|
|20|52|37|60|43|
|21|58|42|67|49|
|22|65|48|75|55|
|23|73|54|83|62|
|24|81|61|91|69|
|25|89|68|100|76|

今回の例の場合，N=9であるため，両側検定でW<5以下の場合，有意差ありとなります．
実際に計算してみると，

```math
\begin{align}
W&=\frac{|t-\frac{N(N+1)}4|}{\sqrt{\frac{N(N+1)(2N+1)}{24}}}\\
&=\frac{|7.5-\frac{9(9+1)}4|}{\sqrt{\frac{9(9+1)(2×9+1)}{24}}}\\
&=1.777047
\end{align}
```

となり，W<5であるので，条件Xと条件Yの間に統計的な有意差(p<0.05)ありとなりました．

## まとめ
今回は2群間の検定のやり方について，自分の理解をまとめるためにこの記事を作成しました．
統計ソフトを使用すると上記の計算が一瞬で終わります．
実際に検定を行う際は統計ソフトを使いましょう（笑）
RasPythoncarにtensorflow（DQN）をインストールする方法

自分用メモ
RasPythoncarにtensorflowをインストールする方法


パスワード変更

```
$ sudo passwd pi
```

SDカードの容量変更（使用SDカードが16GB以上の時）

```
$ sudo apt-get install gparted
$ sudo gparted
$ df -h 
```

OSのカーネルバージョンアップ

```
$ sudo rpi-update
$ sudo reboot
$ sudo apt update
$ sudo apt dist-upgrade -y
$ sudo apt-get autoremove -y
$ sudo apt-get autoclean
$ sudo reboot
```

現在の自分のOSのコードネームやバージョン

```
$ lsb_release -a
```

tensorflowインストール

```
$ sudo apt install libatlas-base-dev
$ sudo pip3 install tensorflow
```

tensorflowのインストールが終わったら、DQNライブラリをインストール
参考サイトは以下のサイトを参考にしました。

[超シンプルにTensorFlowでDQN (Deep Q Network) を実装してみる 〜導入編〜](http://blog.algolab.jp/post/2016/08/01/tf-dqn-simple-1/)
[Tensorflow Deep Q-Network](https://github.com/algolab-inc/tf-dqn-simple)

以下環境構築

```
$ git clone https://github.com/algolab-inc/tf-dqn-simple.git
$ sudo pip3 install matplotlib
```
以上

RasPythonカー IDE に反映

```
GITからダウンロードしたファイル一式をUSBメモリなどに保存して、
「RasPythonカー IDE 」のサンプルプログラムが入っている場所にコピペする。
```

[実行テスト動画 YouTube](https://youtu.be/S2o2dfC7Mc0)


サンプルソースでは学習した結果を表示できないので、
以下のプログラムで実行する。

```RasPython_dqn_play.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Created: 2020/03/09 Mon  1:37

from wr_lib2wd import WR2WD
import time

from catch_ball import CatchBall
from dqn_agent import DQNAgent

wr = WR2WD()

print("スタート")
# environmet, agent
env = CatchBall()
agent = DQNAgent(env.enable_actions, env.name)
agent.load_model()

# variables
win, lose = 0, 0
state_t_1, reward_t, terminal = env.observe()

print(state_t_1)

while not terminal:
    state_t = state_t_1

    # execute action in environment
    action_t = agent.select_action(state_t, 0.0)
    """
    action_t:
    0: do nothing
    1: move left
    2: move right
    """
    if action_t == 1:
        wr.mc.front()
        print("前進")
    elif action_t == 2:
        wr.mc.back()
        print("後退")
    time.sleep(1)
    wr.mc.brake()
    time.sleep(1)
    env.execute_action(action_t)

    # observe environment
    state_t_1, reward_t, terminal = env.observe()
    print("----------------------")
    print(state_t_1)
    
if reward_t == 1:
	print("キャッチ")
elif reward_t == -1:
	print("ミス")
print("エンド")
```
LeetCode 141. Linked List Cycle 解答例 (Python)

LeetCodeの問題141. Linked List CycleのPythonでの解答例です。
https://leetcode.com/problems/linked-list-cycle/

#問題の概要
問題文はシンプルで、連結リストが与えられている時、それがサイクル（循環）を持つかどうかを決定せよ（Given a linked list, determine if it has a cycle in it.）という問題です。
引数は連結リスト（Linked List）となっています。


#解き方
解く時のアルゴリズムは単純です。ここでは例として問題文のExample 1.で考えてみましょう。
まず、問題のグラフ（高校数学までのグラフではなく、データ構造としてのグラフに似ているのでここではグラフと呼びます）です。

<img width="350" alt="IMG_663C064CD19D-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67762/3cc071c6-e132-80ee-2518-04c4140c380f.jpeg">

ここで、slow pointerとfast pointerを考えます。始点はここでは一番左の3です。slow pointerは一回につき1つ進む、fast pointerは一回につき2つ進みます。さて、ここで1回進むと、下図のようになります。

<img width="400" alt="IMG_BC0790961F0D-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67762/394b54ec-b0e6-6712-ec44-eefbc2d767d0.jpeg">

続いて2回進んだ後は下図のようになります。

<img width="400" alt="IMG_BC0790961F0D-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67762/cfb29c3a-e564-fb07-c1a0-b984e99f71d1.jpeg">

3回進んだ後は下図のようになります。

<img width="403" alt="IMG_B423B6363F33-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67762/9f671638-8179-26a1-216c-13d82971184f.jpeg">

この3回進んだ時点で、slow pointerとfast pointerが同じ場所（ノード4）に来ました。


#解答例
以下で解答例を2つ上げます。

##解答例1
```Python
class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        """
        type head: ListNode
        return type: bool
        """

        slow = fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True
        return False
```

解答例1の実行結果は以下のようになりました。この実行の時点では、Python3での提出の平均より64.54%速いようです。同様にメモリの使用量はそれより100%少ないようです。

<img width="634" alt="Screen Shot 2020-03-01 at 22.59.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67762/03c269f3-eeb2-0530-63e5-c80b3dfdd6b8.png">

##解答例2
```python
class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        """
        type head: ListNode
        return type: bool
        """

        try:
            slow = head
            fast = head.next
            while slow != fast:
                slow = slow.next
                fast = fast.next.next
                
            return True
        except:
            return False
```

解答例2の実行結果は以下のようになりました。この実行の時点では、Python3での提出の平均より33.8%速いようです。同様にメモリの使用量はそれより100%少ないようです。
解答例1より処理速度が遅いのは、try exceptが毎回判定処理をしており、if文が1つ増えた形になるためその分遅くなっていることが原因と考えられます。

![Screen Shot 2020-03-02 at 11.56.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67762/2f19acef-0870-90f2-4190-7ecfb470ee74.png)
生物学でわかる！オブジェクト指向

# はじめに
　オブジェクト指向について、最初自分はの本やウェブサイトに書いてあることが全然理解できませんでした。世の中のモノをモノとしてそのまま扱えるようにした？クラスとインスタンスはたい焼きの型とたい焼き？

**プログラムとたい焼きが何の関係があるんじゃー！！わからんわボケ！！**

……取り乱しました。

　とにかく説明がイマイチでうんざりしておりました。JavaやRubyと10年くらい戯れてみた結果、何とか自分が納得した理屈で説明をしたいと思い、このコラムを書きます。

# 対象読者

- オブジェクト指向でつまづいちゃって聞いただけで寒気がする人。
- オブジェクト指向ってなんぞなと思いながらいまいち釈然としないまま使っている人。

# クラスとインスタンス
　**クラスは遺伝子です！インスタンスは生物です！**

　ほぼこれで終わりなんですが、ちゃんと補足します。

　生き物は一つの受精卵から始まって、身体が作られます。その設計図となっているのが遺伝子です。ヒトの遺伝子はヒトそのものではありません。これが「たい焼きとたい焼きの型」のメタファーで言わんとしていることだと思います。

　そして「たい焼きの型」で説明できない「継承」の概念を遺伝子ならうまく説明できます。（突然変異を除けば）子供が持っている特徴は全て親ないしその先祖から脈々と受け継がれてきたものです。それは遺伝子に刻まれています。

　例えばある猫が耳をかじられて片耳になってしまったとします。でもその子供は片耳になったりはしません。それは片耳であるという情報が遺伝子には記録されず、新しい子猫が生まれるときに片耳という情報が受け渡されないからです。クラス（遺伝子）とインスタンス（生物）は違うものですから。

# 継承とその弊害
　クラスが遺伝子だとすると、その弊害も見えてきます。今の生き物は約38億年の継承の果てにあるものです。そして残念なことに現在の生物はそのせいで修正不能なバグだらけなのです！

　ヒトだけに限って言うと、一番顕著なのが目の盲点。なぜ盲点があるかというと目の神経の配線が非合理的なのを無理やり動くようにしているからです。

　目は光を感じるセンサーとその後ろにケーブルがついた視神経の集まりなのですが、普通に設計すると目玉の内側にセンサー、センサーの後ろにケーブルを逃がす穴をそれぞれ作って目玉の外側でまとめるという構造にすると思います。この構造なら盲点は出来ません。ちなみにタコ・イカなんかはこういう構造です。

　しかし実際のヒトの視神経はケーブルがセンサーと同じ側に出ています。で目の玉の中でケーブルをまとめて盲点というでかい穴から外に逃がす構造です。魚時代の最初の目の設計の欠点をそのまま引き継いでしまっているのです。

　オブジェクト指向において継承が素晴らしい機能ともてはやされた時代もありましたが、現在あまり言われないのはこういった先祖の根本的なバグがあった場合に影響範囲が大きすぎ、修正することが事実上不可能になるからです。

# 継承より委譲
　現在の流れとしては継承してもライブラリのクラスから１回のみとか、コンポジション（委譲）を使おうという方向性になっています。

　これは例えて言うと、いろんな匂いをかぎ分けられるようにヒトの遺伝子に犬を混ぜて犬人間を作ることと、匂いを嗅ぐのは犬に任せて、犬から内容を教えてもらうことの違いです。

　犬人間を作ってしまうと、犬の鼻の感覚が完璧に理解できるでしょう。ただ、犬のバグも引き継いでしまいます。おしっこの度に片足を上げる変なバグが出るかもしれませんね:stuck_out_tongue_winking_eye:

　対して犬に匂いを嗅がせてその内容を教えてもらう場合、犬が外に公開しているそぶり（しっぽをふる、吠えるetc.）からしか匂いの内容はわかりません。犬が実際にどう感じているかはいわばブラックボックスです。しかし、危険なものがあるかどうかだけを判別するならそれで十分かもしれません。

　さらにこの場合の利点は、犬が何かの匂いを誤判定した場合にそれが明確に犬、あるいは犬とのコミュニケーションに原因があるとわかることです。犬人間になってしまうと問題発生時の切り分けが難しくなります。

# カプセル化とインターフェース
　オブジェクト指向の大きな利点として良く言われるのがカプセル化です。これは、外部に公開するふるまい（インターフェース）はガッチリ決めて、内部はブラックボックスでいい、というより外から余計なことをさせない仕組みです。

　この考え方の利点の１つは、外部に対するふるまいが同じであれば、いろんなインスタンスを使い分けられることです。

　アヒルの鳴き声を録音したいとしましょう。まず簡単に思いつくのはアヒルを実際に連れてきて鳴かせることです。次に思いつくとしたら、いろんな鳥の声を収録したCDから理想のアヒルに近い声を探すことです。もっと変な方法を考えると、声帯模写の芸人さんにアヒルの鳴きまねをしてもらうことも出来ます。また遺伝子操作でアヒル人間になる手もあるかもしれませんが、それは一応除外します。

　アヒル・CD・芸人さん、これら3者にはもちろん親子関係はありません。しかし結果としてアヒルの声を収録する、という目的はどれでも果たすことが出来ます。Rubyではこれをまんま「Duck Typing」、アヒルっぽい声を出せるものは全部アヒルとして扱う、という考え方をとっています。

　そしてもう１つの最大の利点は「内部のことを知る必要が無い＝内部に干渉できない」ということです。
　生き物と同じで明確に境界があるのです。

　このアヒル声機能がライブラリとして提供されているとしましょう。オブジェクト指向以前には、アヒルを捕まえる（メモリの確保）、アヒルを鳴かせる、アヒルを放す（メモリの解放）を必ずこの順番に行う事、みたいなマニュアルが必要でした。さらに外部からアヒルの中身をいじくれてしまうので、別の機能の影響でアヒルが鳴かなくなってしまったり、アヒルが暴れだして周りを破壊して回る（メモリ破壊）なんてことも起こっていました。

　内部に干渉できないようにして、公開された手順での操作しか許さないことで、こういった事案を防ぐことが出来ます。

#まとめ
　古いパソコンではすべてを自分でプログラミングしなければなりませんでした。しかし時代が進み様々なライブラリが提供されると、そのライブラリを組み合わせて仕事をさせることの方が多くなりました。GUIなんかになると、もうライブラリを使わないと作れないレベルの複雑さです。

　作られたライブラリをより専門的な用途にするために、機能を付け加えることが出来るというのが**継承**です。そしてライブラリを使う側にはその内部の複雑さを見せないようにし、公開されたふるまい（インターフェース）のみを操作させる、これが**カプセル化**です。

　農家側はよりたくさんジャガイモが出来るよう品種改良する（よりよい遺伝子を残す）、しかし食べる側はジャガイモの生育方法、農薬の散布の方法、細かな性質を知らなくても調理の仕方さえ知っていればおいしく食べられる、こんな感じのイメージで私はとらえています。

　今までの説明で余計わからんのじゃボケ！となっている読者ももちろんいるでしょう。ただ、少しでもオブジェクト指向のイメージがつかめたら、そしてアレルギーが無くなれば、このコラムを書いた自分としてこれ以上嬉しいことはありません。
matplotlibで複数の図にタイトルを付ける方法

#はじめに
　Matplotlibで複数の図をまとめて表示するという記事は多くあります。しかし、複数の図にタイトルを付けるという内容は少なかったので記事にしました。

#方法

```python:plot.py
#ライブラリを読み込む
import numpy as np
import cv2
import matplotlib.pyplot as plt

#円を描画（白、赤、緑、青）
white = cv2.circle(np.zeros((200, 200, 3), dtype=np.uint8), (100, 100), 50, (255, 255, 255), thickness = -1)
red = cv2.circle(np.zeros((200, 200, 3), dtype=np.uint8), (100, 100), 50, (0, 0, 255), thickness = -1)
green = cv2.circle(np.zeros((200, 200, 3), dtype=np.uint8), (100, 100), 50, (0, 255, 0), thickness = -1)
blue = cv2.circle(np.zeros((200, 200, 3), dtype=np.uint8), (100, 100), 50, (255, 0, 0), thickness = -1)

#タイトル
titles = ['white', 'red', 'blue', 'green']

#グラフをリストの入れ子にする
graphs = [white, red, blue, green]

#表示領域を設定（行，列）
fig, ax = plt.subplots(2, 2)  

#図を配置
for i in range(0,4):
    plt.subplot(2,2,i+1)
    plt.title(titles[i], fontsize=20)    #タイトルを付ける
    plt.tick_params(color='white')      #メモリを消す
    plt.tick_params(labelbottom=False, labelleft=False, labelright=False, labeltop=False)
    plt.imshow(cv2.cvtColor(graphs[i], cv2.COLOR_BGR2RGB))   #図を入れ込む
    plt.xlabel('X', fontsize=15)        #x軸に名前をつける
    plt.ylabel('Y', rotation=0, fontsize=15, labelpad=20) #y軸に名前をつける

#図が重ならないようにする
plt.tight_layout()

#図を表示
plt.show()
```

出力は以下のようになります。
![plot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537831/f85d563a-6002-7fa8-fd7d-3d9daecbe25e.png)


#おわりに
　ご覧いただきありがとうございました。ご指摘等ありましたらコメント欄にお願いします。

#参考URL
https://openbook4.me/sections/1396
(閲覧: 2020年3月2日）
Node.js で DynamoDB のデータを読む

参考ページ
[Amazon DynamoDB Step 3.2: Read an Item](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.NodeJs.03.html#GettingStarted.NodeJs.03.02)
[Node.js からDynamoDBを操作するサンプル](https://qiita.com/inouet/items/b2246d2419daf1788f63)

前提ソフトのインストール

```bash
sudo npm install aws-sdk -g
```


Movies というテーブルから、　Scott という項目を読む

```js:get_item.js
#! /usr/bin/node
//
//
var AWS = require("aws-sdk");

var dynamodb = new AWS.DynamoDB({region: 'ap-northeast-1'})

const table = "Movies"
const user = "Scott"

const params = {
    TableName: table,
    Key:{
        "user":  {"S": user},
    }
}

dynamodb.getItem(params, function(err, data) {
    if (err) {
        console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2))
    } else {
        console.log("GetItem succeeded:", JSON.stringify(data, null, 2))
    }
})
```

テーブルの一覧

```js:list_tables.js
#! /usr/bin/node
//
//
var AWS = require("aws-sdk")


var dynamodb = new AWS.DynamoDB({region: 'ap-northeast-1'})

var params = {
    Limit: 100
}

dynamodb.listTables(params, function(err, data) {
    if (err) {
        console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2))
    } else {
        console.log("GetItem succeeded:", JSON.stringify(data, null, 2))
    }
})
```

テーブルの説明

```js:describe_table.js
#! /usr/bin/node
//
//
var AWS = require("aws-sdk")


var dynamodb = new AWS.DynamoDB({region: 'ap-northeast-1'})

var table = "Movies"
var params = {TableName: table}

dynamodb.describeTable(params, function(err, data) {
    if (err) {
        console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2))
    } else {
        console.log("GetItem succeeded:", JSON.stringify(data, null, 2))
    }
})
```
カスペルスキーのスキャンが遅い、Mac重いとお嘆きの方へ

##はじめに
カスペルスキーがスキャンしてると、Macがとても重くなり、作業が全然進まないときがある。
いらっとしますね。特にXcodeが重かったりね。AndroidStudioはそうでもないけど。

カスペルスキーには信頼リストというものがあり、フォルダを登録しておくと、スキャンから除外してくれます。私もファイルが多くて安全そうなフォルダは登録しています。

それなのにスキャン時間が異常に長かったり、終わらなかったりします。
今回やっとスキャン時間を短くできましたので、紹介します。

##スキャン時間を短くするには
最近のカスペルスキーは、信頼リストを更新すると、スキャン中でもすぐに反映してくれます。
スキャン中にはファイルパス名が表示されるので、時間がかかってて除外しても良さげなフォルダをどんどん信頼リストに入れましょう。

結構意外なフォルダで時間がかかってました。
~/.npm,~/.jenkins,~/.gradle,~/dartServer,~/Library/Application Support,/Users/他ユーザー,・・・
ああ、そういうのね・・・全く気づかず。
パッケージ系を除外していいのかはちょっと悩みますが、背に腹は変えられず。
受信メールもスキャンされますが、さすがにメールは除外できないので、古い受信メールは消しちゃいましょう。
##終わりに
1日経っても終わらなかったカスペルスキーのスケジュールスキャンが１時間以内になりました。

これで快適に開発できます。:kissing_closed_eyes:
在Unity中读取Blender的模型

#◆ 写在开头
想要用Unity制作3D游戏，3D模型是不可或缺的。
所以这次的内容是关于如何把做好的3D模型放入Unity的方法。

#◆ 系统环境
macOS Mojave 版本：10.14.6
Unity 2018.4.12f1
Android SDK
Blender 2.81

#◆ 模型的准备
这次主要讲的是如何把模型放入Unity
所以关于模型的制作说明这里就跳过了。
<img width="450" alt="01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541380/ca82a5ad-3a5d-8061-a3df-707b3a3a8010.png"><img width="144" alt="スクリーンショット 2020-02-28 20.31.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541380/4f4e3774-10c5-b24f-a268-868619fa6e50.png">
总之随便作一个可以认得出来的模型（这里作了个杯子），保存。
保存名是默认的。

#◆ 放入Unity中的方法与设置
这次呢，使用了
[【用Unity开发Oculus Quest用的APP】导入APP、进行运行状态确认](https://qiita.com/Kujirai_sakananosuke/items/7f0dacd447b5fa256796)中的Scene。
（当然不仅仅是Oculus，普通的3D Object下面的方法也同样适用）
<img width="600" alt="03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541380/59d8ce60-9af7-c640-dd03-4d78421ec94c.png">
要作的事情十分简单、
右键「Project」选择「Import New Asset」，载入刚才做好的文件便可。
<img width="321" alt="04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541380/b41b1972-ef44-1d3d-cd44-c69856a5d260.png">
可以看到有复数的文件存在，
这里面我们需要的只有「Cricle」。
<img width="321" alt="05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541380/9b7cf900-adde-2d07-bd8f-08cc08a57c1b.png">
在Hierachy中右键，选择「3D Object」→「Cube」，制作一个「Cube」。
<img width="386" alt="08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541380/41b4d90e-719d-7d77-a50f-135dd118d47c.png">
接着、
将「Cricle」放入，「Cube」Inspector中的「Circle」的「Mesh」里。
选择最下方的Add Component按钮，追加「Mesh Collider」。
<img width="383" alt="09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541380/de9068d1-ce8c-15fd-4a1a-917f79e2e2ac.png">
追加后记得删除，原本自带的「Box Collider」。

<img width="400" alt="10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541380/34938bb2-a238-9c21-3c4a-48975b73637f.png">
这样就设置完成了，
模型的物理，颜色等请根据自己喜好随意设置。
#◆ 运行确认
<img width="450" alt="スクリーンショット 2020-02-28 20.45.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541380/354f6958-c169-4bcc-b64b-31a2fe4317c0.png">

运行后，在画面上是这样样子的。
关于Blender的相关知识，等以后别的机会...
RecyclerViewをするするっとした時にどれぐらいViewが表示されているか確認する

# スクロールして、Viewが50%表示されたら何かするみたいな需要があるらしい

動画広告が自動的に再生されたりするあれですね。はい。

# 結論：こんな感じでどうでしょう

```kotlin:ViewExt.kt
fun View.visiblePercentage(): Int {
    val visibleRect = Rect()
    getLocalVisibleRect(visibleRect)

    return round(((visibleRect.right - visibleRect.left) * (visibleRect.bottom - visibleRect.top)).toFloat() / (width * height) * 100).toInt()
}
```

# 可視化

![out.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69858/14501b02-86a6-8365-ff1c-62ec70fb6926.gif)

きれいですね。

# パッと見、あってそう

そうじゃない、このパターンが抜けてるじゃないかというのがあったらプルリクお待ちしております。

https://github.com/mayahiro/VisibleAreaCheck
Rails 「findとfind_byの違いについて」

#はじめに
標題の通り、findとfind_byの違いでつまづいてしまいました。
何とか解決はできましたので、復習も兼ねてoutput致します。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。


#一言でいうと・・・
findメソッド　：　各モデルの**id**カラムのデータを指定して、レコードからデータを取得する
find_byメソッド　：　あるカラムを使って、レコードから最初に一致した**１件だけ**を返してくれる

findメソッドは探してるidがない場合エラーを出してきます。（idを検索キーとしているため）
find_byメソッドなら探しているidがない場合、nilが返ってきます。

#findメソッドとは
- **id**カラムの値を指定し、その値を持つレコードを取得する。

以下、例ではtasksテーブルのidを指定し、そのidのレコードを取得しています。

<img width="1042" alt="find1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576541/7b6c0645-44db-13b4-16d7-7b9cb771321d.png">

- 仮にDBに保存されていない**id**カラムの値を指定すると、ActiveRecordのエラーが出てしまいます。
<img width="1042" alt="find2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576541/296bfdf2-16a5-b756-e6f8-292764b12fa8.png">



#find_byメソッドとは

あるカラムを使ってレコードを検索し、最初に一致した１件だけ返してくれる。

例）titleカラムが「3/2 Todo」であるレコードを1つ取り出す。

<img width="1037" alt="findby1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576541/20bdf276-beb6-8687-26f4-4ef8fb3f151d.png">


#さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。
外部ライブラリの入れ方

外部ライブラリを入れる方法がわからなかったので、備忘録的なメモとして残しておきます。

# 環境
　Windows7
　Adopt Open JDK1.8

# 方法
　まず使用したい外部ライブラリのjarファイルをダウンロードしてきてください。

　次にそのダウンロードしてきたファイルをAdopt Open JDK1.8のフォルダ内のjre￥lib￥extフォルダにダウンロードしたjarファイルを配置することで使えるようになります。

　import文が必要なら適宜ソースにimportして使ってください。

# 終わりに
　検索してもそのままズバリを書いている方法がなかなか出てこなかったので書きました。
　もし間違いなどがありましたら指摘していただければ幸いです。