OmniAICreator/Qiita-1.07M huggingface dataset:
Python版FBX SDKをMacにインストールする

# Python版FBX SDKをMacにインストールする

Python版FBX SDKをMacにインストールしました。

以前、Windowsにインストールしたので、同じ要領でやってみました。いくつかつまづいた点があったので、忘れない内にメモを残します。

Windowsの時の記事はこちらです。
[Python版FBX SDKをWindowsにインストールする](https://qiita.com/segur/items/5d0dff790e784760a547)

環境はこんな感じです。

- MacBook Pro
- macOS High Sierra 10.13.6
- Python 2.7 （理由は後述）
- FBX SDK 2019.5 (2019年9月26日時点で最新)



# Python版FBX SDKのインストーラーを入手する

こちらのサイトにアクセスします。
[Autodesk FBX Software Developer Kit](https://www.autodesk.com/developer-network/platform-technologies/fbx-sdk-2019-5)

![スクリーンショット 2019-10-07 12.00.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/da4927eb-35c8-c928-3771-71315d03f832.png)

少しスクロールすると、 `FBX SDK 2019.5 Python Mac` というリンクがあるので、クリックすると、 `fbx20195_fbxpythonsdk_macos.pkg` というインストーラーがダウンロードされます。

インストーラーを起動して、指示に従ってインストールします。
インストール先のフォルダはデフォルトのままの場合、以下になるようです。

`/Applications/Autodesk/FBX Python SDK/2019.5`

これでインストール完了かと思いきや、まだ開発を始めることはできません。



# Python 3.7版 ではなく 2.7版 を選ぶ

`/Applications/Autodesk/FBX Python SDK/2019.5/lib`
を開くと、2.7版と3.7版があることがわかります。

<img width="553" alt="スクリーンショット 2019-10-07 12.11.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/958c2e50-ae16-7287-22d9-e5b35d9e4f05.png">

私のWindows環境のFBX SDKでは2.7版を利用しているため、ソースコードを共有化するために、Macでも2.7版を利用することにします。

Windows環境で2.7を利用している理由はWindows版の記事をご覧ください。
[Python版FBX SDKをWindowsにインストールする](https://qiita.com/segur/items/5d0dff790e784760a547)



# Python 2.7をインストールする

Macの場合、以下にPython 2.7がプリインストールされています。

`/Library/Python/2.7`

pyenvを使っている場合、以下にインストールされています。

`~/.pyenv/shims/python2`



# Python 2.7にFBX SDKをインストールする

`/Applications/Autodesk/FBX Python SDK/2019.5/lib/Python27_ub`

を開きます。以下の３つのファイルがあります。

- `fbx.so`
- `FbxCommon.py`
- `fbxsip.so`

これらを、 `site-packages` フォルダ直下にコピーします。
`site-packages` フォルダのパスは、以下のように利用するPythonの実行ファイルによって異なります。

- プリインストールのPythonの場合:  `/Library/Python/2.7/site-packages`
- pyenvの場合: `~/.pyenv/versions/2.7.（バージョン番号）/lib/site-python`
    - `site-packages` ではなく `site-python` なので注意してください。

これでインストール完了です！



# `fbx` がインポートできるか試す

Pythonのコードから `fbx` がインポートできるか試してみましょう。

`test.py` というファイルを作って、以下のコードを記述します。

```python:test.py
from fbx import *
```

このコードを **Python 2.7** で実行してみます。

```bash
python test.py

# pyenvを利用している場合
python2 test.py
```

この際、特にエラーが発生しなければ、インポートは成功です！



## `ModuleNotFoundError` が発生する場合

もし、以下のエラーが出た場合は、FBX SDKをインストールした `site-packages` のパスが間違っている可能性があります。

```
ModuleNotFoundError: No module named 'fbx'
```

`fbxという名前のモジュールが見つかりません` という意味のエラーメッセージです。

こちらの記事の方法で、 `site-packages` のパスを調べることができますので、ご確認ください。
[【Python】site-packagesのパスを確認する方法【pip install・pyenv】](https://qiita.com/chatrate/items/eb4b05cd1a6652529fd9)

また、Python 3系で実行してしまっている場合も、同様のエラーが表示されると思います。Python 2.7で実行できているか確認してみてください。



# さいごに
こちらの記事を参考にさせていただきました。わかりやすい記事をありがとうございます。

- [【Python】site-packagesのパスを確認する方法【pip install・pyenv】](https://qiita.com/chatrate/items/eb4b05cd1a6652529fd9)
Atomの「Remote FTP」を使用してSFTP（秘密鍵あり）を接続する

# 環境
Mac


## 接続手順
Atomの『Remote FTP』を使用して秘密鍵を利用してSFTP接続する。

01.パッケージの[Remote FTP]を選択。
02.[Create SFTP Config File]を選択。
03.[.ftpconfig]が作成される
04.下記コードに書き換える（ {{ }} で囲んでいる箇所は要変更 ）
05.PCの[/Users/xxxx/.ssh]に秘密鍵を入れる
※ 鍵が「.pem」でなければ「Fille Zille」などを使用して分解させる（個人的な方法）
06.Atomで[Remote FTP] >  [Toggle]で接続確認
07.接続完了


```ruby:.ftpconfig
{
    "protocol": "sftp",
    "host": "{{ ホスト(123.123.123.123 ...など) }}",
    "port": {{ ポート番号 }},
    "user": "{{ ユーザー名 }}",
    "pass": "{{ パスワード }}",
    "promptForPass": false,
    "remote": "{{ 接続先のパス(/var/www/...など) }}",
    "agent": "",
    "privatekey": "{{ 秘密鍵がある場合（/Users/xxxx/.ssh/xxx/id_rsa.pem） }}",
    "passphrase": "{{ 秘密鍵のパスワード }}",
    "hosthash": "",
    "ignorehost": true,
    "connTimeout": 10000,
    "keepalive": 10000,
    "keyboardInteractive": false
}
```
Play de アプリ開発 ~PlayFrameworkの基本を知ろう~

## はじめに
`Play de アプリ開発`ということで[前回](https://qiita.com/Hiroro0970/items/93d9050b0eaf56809e4c)は環境構築が終わったのでこれから開発していきたいと思います。
環境構築から始める人は前回の記事を参考にしてください。

## 開発構成
今回は簡単家計簿アプリを作成します。
ただし、少し趣向を変えて行きたいと思います。
・**フロントエンドはAngularを採用してSPAにします**
Playでは`Twirl`と呼ばれるJavaでいうJSPのようなテンプレートエンジンが採用されているのですが、モダンなWebアプリの開発を視野に入れているためSPAフレームワークの`Angular`を採用します。Angularである理由は最近私がよく使っているからであってそれ以外は特にありません。

・**フロントエンドとバックエンドは異なるサーバーに配備するようにします**
バックエンドはJSON形式でレスポンスを返すようにし、あえてサーバーを分けることでそれぞれが独立して使用できるようにします。APIがしっかり独立して機能するようにすれば今後iPhoneやAndroidのアプリを開発したとしても開発が容易になるからです。


## 事前知識
ところで、PlayFrameworkを使っていくにあたり知っておかなければならないことがいくつかあります。
ここで簡単にまとめておきます。


### Action
`Action`とはPlayFrameworkで用いられるメソッド。リクエストを処理してレスポンスをクライアントに返す際に使用される。Actionは`Result`と呼ばれる型を返す。
**PlayFrameworkでは基本中の基本**。

```index.scala
// text形式でレスポンスされる
def index = Action {
   Ok("Hello!")  
}

// json形式でレスポンスされる
def hoge = Action {
   Ok("{'msg' : 'Hello!'}").as("application/json")  
}

// 引数あり
def fuga(id:Long) = Action {
   Ok("The ID is" + id)
}
```
`Ok`はステータスコード`200`を返す。
他にも`NotFound`, `BadRequest`, `InternalServerError`があり、適切なステータスコードを返してくれる。


### Route
`Route`はURLからどの処理を実行するかを記載した設定ファイル。
`:id`や`*name`とすることで動的に対応することもできる。

```route
GET   /                     controllers.HomeController.index()
GET   /hoge/                controllers.HomeController.hoge()
GET   /fuga/:id             controllers.HomeController.fuga(id: Long)

POST  /hoge/                controllers.HomeController.hogePost()
```


### JSON
**個人的によくハマったところ。**
PlayではJSONを扱えるようにするためのライブラリーがデフォルトで用意されている。
使いこなすためにはいくつか知っておくべきことがある。
詳しくは公式ドキュメントを確認することをオススメする。

#### JsValueとJson
`JsValue`はPlayで扱うJSON型のデータ。
`Json`は`JsValue`を扱うために用意されたユーティリティが格納されたオブジェクト。主に変換に用いられる。

例えば以下のようなJSONデータがあったとする。

```hoge.json
{
  "name" : "Watership Down",
  "location" : {
    "lat" : 51.235685,
    "long" : -1.309197
  },
  "residents" : [ {
    "name" : "Fiver",
    "age" : 4,
    "role" : null
  }, {
    "name" : "Bigwig",
    "age" : 6,
    "role" : "Owsla"
  } ]
}
```
これをPlayで扱うには以下のように記載する。

```hoge.scala
import play.api.libs.json.{ JsNull, Json, JsString, JsValue } // 必ずインポートすること

val json: JsValue = Json.obj(
  "name" -> "Watership Down",
  "location" -> Json.obj("lat" -> 51.235685, "long" -> -1.309197),
  "residents" -> Json.arr(
    Json.obj(
      "name" -> "Fiver",
      "age" -> 4,
      "role" -> JsNull
    ),
    Json.obj(
      "name" -> "Bigwig",
      "age" -> 6,
      "role" -> "Owsla"
    )
  )
)
```

また、自ら定義したモデルクラスをJson形式に変換することもできる。
例えば以下のようなファイルがあるとする。

```Resident.scala
package models

import play.api.libs.json._


object Resident {
    // 独自クラスからの変換には必ず定義しなければならない
    implicit val residentWrites = Json.writes[Resident]
    case class Resident(name: String, age: Int, role: Option[String])
}
```

このファイルをimportすればJSONに変換することができる。

```ResidentConverter.scala
package controller

import play.api.libs.json._

import models.Resident._

val resident = Resident("Hiroro", 26, None)
val json = Json.toJson(resident)
```

## まとめ
ここではPlayFrameworkでおさえておかなければならない点について触れました。
詳しく理解するにはやはり公式ドキュメントを参照するのが一番です。
私もまだ十分に理解できていないので公式ドキュメントをみながらしっかり学習していきます。
ESlintを--save-devもしくは--devに入れてバージョン確認したい

# ESlintをグルーバルに入れないとパスが通らない


[ESLint をグローバルにインストールせずに使う](https://qiita.com/mysticatea/items/6bd56ff691d3a1577321)
こちらの記事を参考にしてグローバルでは無く`devDependencies`に入るように入れてみました。

するとnot foundと返されてしまいます。
どうやらパスが通っていないことが原因みたいです。

```
$ eslint -v
> not found
```

とりあえず応急処置として`pakage.json`の`scripts`に書けば間違いなく動くでしょう。
（というとりあえず目的は達成するスタイル）

### 応急処理！！

```json:pakage.json
{
    "scripts": {
        "eslint -v": "eslint -v"
    }
}
```
これでとりあえず確認できる！！

```
$ npm eslint -v
> 6.9.0
```

### おわりに
コメントなどで色々とご教授いただけると幸いです！！


### 追記
npmとyarnのそれぞれの非グローバルインストール方法

```
$ npm install --save-dev eslint

$ yarn add --dev eslint
```
flutterのdebugと書かれたバナーを消す方法

flutter run等でデバッグビルドすると画面右上に赤い帯が出る

消したい場合は
MaterialAppに
```debugShowCheckedModeBanner: false
```
を入れれば、消える。

全体はこんな感じ。

```
return MaterialApp(
      title: 'flutter',
      debugShowCheckedModeBanner: false,
      home: MyHomePgae(),
    );
```
VBA　AutoFilter可視セルの操作

# AutoFilter

Colm = rTarget.EntireRow.Find(what:="keyword", LookIn:=xlValues, Lookat:=xlWhole).Column
rTarget.AutoFilter Field:=Colm, Criteria1:=">=1"
LRow = ActiveSheet.AutoFilter.Range.Rows.Count
If LRow > 1 Then
   Rows("2:" & LRow).SpecialCells(xlCellTypeVisible).Delete
End If
rTarget.AutoFilter
「初心者向け」JavaとKotlinの違い

# Kotlinとは
- Kotlinは、JetBrains社が作っているJVM上で動作する言語。
- Kotlinは、Javaと完全に相互運用が可能である。あるクラスをJavaで書いて、それを継承したクラスを Kotlinで書いて、さらに継承したクラスをJavaで書くことができる。
- Javaで書かれていたプロジェクトに、追加開発分だけ Kotlin で書くことでき、導入しやすい。
- Google が Android での Kotlin 公式サポートを発表している言語である。

# 変数宣言
定数に対してはval、変更可能な変数に対したはvarを利用します。

```java:test.java
String str = "文字列";
final int value = 0;
```

```kotlin:test.kt
var str: String = "文字列"
val value = 0
```

Kotlinでは型推論が可能なので型を省略して変数を定義することもできる。セミコロンは不要である。

# if文

```java:test.java
String value = bar < 10 ? "abc" : "xyz";
```

```kotlin:test.kt
 var value = if (bar < 10) "abc" else "xyz"
```
ifやelseブロック内の結果を直接代入することができます。

# for文

```java:test.java
for(int num : numbers)
{
System.out.println(num);
}
for(int i = 0; i< 4; i++)
{
System.out.println(i); 
} 
```


```kotlin:test.kt
for (num in numbers)
{
  println(num)
}
for (i in 0..3)
{
  println(i)
}
```

Kotlinはinを利用する。

# 関数

```java:test.java
public int add(int a, int b) 
{
    return a + b;
}
add(1,2);
```

```kotlin:test.kt
fun add(a:Int, b:Int): Int {
    return a + b
}

// 呼び出し側
add(1,2)
```

Kotlinの場合、アクセス修飾子が省略された場合はpublic扱い。さらに、コンパイラーが型推論をできるような戻り値の型であれば、戻り値の型の定義を省略することも可能です。
バッチ1発でMySQLサーバーをインストール&構築する ～Windows10～

# 目的
・LattePanda(Windows10)にMySQLServerを構築し量産したい
　↓
・量産工数を少しでも減らすために、各デバイスでの環境構築はなるべく自動化したい
　↓
・MySQLをバッチで一発インストールできるようにしたい (可能なら同時にDBも構築したい)

# 前置き
上記の方法を調べても日本語での情報は皆無。
スタックオーバーフロー等で英語圏にそれっぽいQAがあるが、記述されているサンプルではどれも上手くいかないものばかり。
かなりレアケースだと思いますが、試行錯誤したら実現できたので共有します。

# 方法
1. [MySQL公式](https://dev.mysql.com/downloads/installer/)より必要なバージョンのインストーラーをダウンロードしておく。(当方ver8.0.17)
2. バッチファイルを作成。(以下動作確認済みサンプルコード)
　→適宜バージョンやパスを変更

```mysql_installer.bat
# MySQLバージョン 8.0.17

# ※管理者として実行
#「mysql-installer-community-8.0.17.0.msi」と「dumpファイル」を事前にCドライブ直下に配置
# passwdやFilePathは適宜変数化
# 構築環境に合わせてオプションを変更する

@echo off
echo Installing MySQL Server. Please wait...

msiexec /i "C:\mysql-installer-community-8.0.17.0.msi" /qn /norestart
echo Configurating MySQL Server...

"C:\Program Files (x86)\MySQL\MySQL Installer for Windows\MySQLInstallerConsole.exe" community install server;8.0.17;x64:*:type=config;openfirewall=true;generallog=true;binlog=true;serverid=3306;enable_tcpip=true;port=3306;rootpasswd=PASS; -silent
echo MySQL has been installed successfully!

# 環境変数にPathを追加
setx PATH "C:\Program Files\MySQL\MySQL Server 8.0\bin"

echo Restoring database ...
mysql -u root -pPASS -e "CREATE DATABASE `DBNAME` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci"

mysql -u root -pPASS DBNAME --binary-mode < "C:\dump_file.sql"
echo Database has been restored successfully!
pause
```
3. 1で取得したインストーラーとdumpファイルを任意の位置(サンプルはCドライブ直下)に配置
4. バッチファイルを管理者として実行

# 流れ
1. 「msiexec /i」  にてインストーラーを実行
2. 「"C:\Program Files (x86)\MySQL\MySQL Installer for Windows\MySQLInstallerConsole.exe" community install」 でMysqlServerインストール
3. 「setx PATH」 で環境変数にmysqlのpathを追加
4. 「mysql -u root -pPASS -e」　にて事前にDBを作成
5. 「mysql -u root -pPASS DBNAME --binary-mode <」　にてリストア(4で作成したDBを記述)

# 最後に
肝となるのは「MySQLInstallerConsole.exe」です。
[こちら](https://dev.mysql.com/doc/refman/5.6/ja/MySQLInstallerConsole.html)にリファレンスがあるので、環境に応じてオプションなどを変更してください。
上記コマンド実行時に 「community」がないと商用版がインストールされ、無料では使えないと思われます。
スタックオーバーフローの海外QAにはconfigほにゃららを使ったやり方が散見されますが、どれも上手くいきませんでした。

なんとか成功したやり方なので、他に良いやり方があれば是非ご教授ください。
【JavaScript】オブジェクトが格納されている配列で複数のキーでソート

## :book: こんな感じの配列があるとします
```js
const items = [
  { id: "6", price: "340", name: "大根" },
  { id: "5", price: "230", name: "ポテト" },
  { id: "1", price: "100", name: "パセリ" },
  { id: "2", price: "340", name: "にんじん" }
]
```

## :boom: 価格昇順でソートしたい場合
```JavaScript
items.sort((a,b)=>a.price - b.price);
```
単純に価格昇順にしたいのであれば簡単で、これで実現出来ます。
ただし、これだけではpriceが同じものがあった場合idが昇順になってくれず

```js
const items = [
  { id: "1", price: "100", name: "パセリ" },
  { id: "5", price: "230", name: "ポテト" },
  { id: "6", price: "340", name: "大根" },
  { id: "2", price: "340", name: "にんじん" }
]
```

こうなります。

## :boom: 価格昇順でソート & 同じ価格ならid昇順 にしたいとする
つまりこうしたいです。

```js
const items = [
  { id: "1", price: "100", name: "パセリ" },
  { id: "5", price: "230", name: "ポテト" },
  { id: "2", price: "340", name: "にんじん" },
  { id: "6", price: "340", name: "大根" }
]
```


## :ok_hand: 実現方法
```JavaScript
items.sort((a,b)=> {
  if(a.price > b.price) return 1
  if(a.price < b.price) return -1
  if(a.id > b.id) return 1
  if(a.id < b.id) return -1

  return 0;
});
```

このようにして実現出来ます。

もし2つではなく、3つ4つと比較したいキーが増えても条件分岐を増やして行けば良いです。

## 追記
コメントにて、@hayashi-ay さんより 1行で簡潔に書ける方法を教えて頂きましたので追記しておきます。

```JavaScript
items.sort((a,b)=> (a.price - b.price) || (a.id - b.id) );
```
Google Drive上のcsvファイルにpandasでアクセスする

# TL;DR

PythonでGoogleDrive上のファイルにアクセスできるようにすればファイル管理が楽になるなあと思ったので調べました。もっといい方法があれば教えていただきたいです。

## 1. Google Driveで共有リンクを取得
共有リンクを取得します。

### 2019年10月07日
取得したリンクは以下のようになっていると思います。

`https://drive.google.com/open?id=xxxxxxxxxxxxxxxxxxxxx`

これを以下の様に書き換えます。(open -> uc)
`https://drive.google.com/uc?id=xxxxxxxxxxxxxxxxxxxxx`

### 2020年7月22日

リンクを取得すると、以下のようなものが得られます。

`https://drive.google.com/file/d/xxxxxxxxxxxxxxxxxxxxx/view?usp=sharing`

これを、以下のように書き換えます。
`https://drive.google.com/uc?id=xxxxxxxxxxxxxxxxxxxxx`

まだ同様のAPIが使えるけど、いつまで使えるのかはいまいちわかりません。もう少しいい方法を考えたい。また、注意点として大きいファイルはウィルススキャンできないという理由でエラーが起きます。大きすぎるファイルを読み込む際は注意してください。

## 2. 読み込み

`requests`を使ってファイルを取得して、`io`でパースしたものを`pandas`に読み込ませます。

```python
import io
import requests
import pandas as pd

URL = "https://drive.google.com/uc?id=xxxxxxxxxxxxxxxxxxxxx"

r = requests.get(URL)
df = pd.read_csv(io.BytesIO(r.content))
```

GoogleDrive API的なのを使えばもっとスマートにできる気しかしませんが、とりあえずGoogleDrive上のCSVに直接アクセスできるので個人使用な分には便利かなと思います。
Vimでタブ文字を一時的に入力する

タブキーを入力すると半角スペースにするようにしていましたが、一時的に入力したかった事があるのでメモ

`insertモード : Ctrl + v -> tab` で可能です。

こんなのが入ったらOK `»`

<img width="100" alt="スクリーンショット 2019-10-07 12.50.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/4ded02e0-63b0-8900-12ec-fe3a532bf4f5.png">
【忘備録】日付の自動取得、営業日に変換、フォーマット調整

* pythonでの日付取得
    * 自動更新などに用いるための日付取得
        * 土日を抜かした日付のみ自動でファイルを作成したいときなどに利用
    * フォーマットの整理(ここではYYYY/MM/DDで出力)


```python
import datetime

def adj_bd(date):
    """ Function for Calendar date to previous Business-day
    """
    if datetime.date.weekday(date) == 5:  # if it's Saturday
        outlastbd = date - datetime.timedelta(days=1)  # then make it Friday
    elif datetime.date.weekday(date) == 6:  # if it's Sunday
        outlastbd = date - datetime.timedelta(days=2)  # then make it Friday
    else:
        outlastbd = date
    return outlastbd
```

使用例

```python
# 前営業日
pre_day = datetime.datetime.today() - datetime.timedelta(1)
pre_day_bd = adj_bd(pre_day)
```



```python
#月初営業日
b_month_ = adj_bd(pre_day.replace(day=20)).replace(day=1)
b_month_bd = adj_bd(b_month_).strftime("%Y/%m/%d")

# 前月末営業日
last_e_month_ = b_month_ - datetime.timedelta(days=1)
last_e_month_bd = adj_bd(last_e_month_).strftime("%Y/%m/%d")

```



```python
# X営業日前
def lag_bd(t0_, lag=1):
    lag_day = adj_bd(adj_bd(t0_) -
                     datetime.timedelta(lag)).strftime("%Y/%m/%d")
    return lag_day

# e.g. 2営業日前
lag_bd(pre_day, 2)

```
【CoreML】iPhoneのセンサーデータを機械学習させてロックダンスの動きを識別してみた

# AIにロックダンスの動きを識別させてみた
以前、iPhoneの加速度や角速度といったセンサーデータを[CoreMotion](https://developer.apple.com/documentation/coremotion)を使って取得し、CSVファイルとして記録するiOSアプリを作成しました。

[【CoreMotion】iPhoneのモーションデータ（加速度や角速度など）をCSVで記録するアプリを作成してみた](https://qiita.com/FollowTheDarkside/items/d16870a6535bdb5cb1f0)

このアプリを使ってストリートダンスの1つであるロックダンス（Lockin'）のモーションデータを記録し、機械学習ライブラリの[Keras](https://keras.io/ja/)で構築したモデルに学習させました。その学習済みモデルを[CoreML](https://developer.apple.com/jp/documentation/coreml/)を使って上記のiOSアプリに組み込みリアルタイムでロックダンスの動作識別をしてみました。
![ai_lockdance_test_190929_4-min.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218869/61ae1a81-fe41-e732-c6e4-9f9951243516.gif)
見えづらくてすみません！こちらはロックダンス中のスマホ画面をキャプチャーしたものです（動画は[Twitter](https://twitter.com/eatora22/status/1178240239631888384?s=20)の方にも載せてあります）。動作の順番は「トゥエル」→「ロック」→「ポイント」のつもり。

自分はダンサーではありますがロック専門ではないのでめちゃくちゃ下手ですし、今回は学習データ量も少ないのでモデルとしてはあまり良いものではありません（泣）。ただ、スマホでもある程度は動作の識別が可能ということが分かりました！

#MLModelから予測結果のラベルを取得する例
今回のアプリのソースコードは[GitHub](https://github.com/FollowTheDarkside/SensorDataRecorder/tree/feature/with-coreml)にも載せているのですが（そのうちリポジトリ変えるかも）、組み込んだ[MLModel](https://developer.apple.com/documentation/coreml/mlmodel)にデータを入力し予測結果のラベルを取得するまでの実装例を抜粋しておきます。

```swift
func getCoremlOutput(){
    // store sensor data in array for CoreML model
    let dataNum = NSNumber(value:inputDataLength)
    let mlarray = try! MLMultiArray(shape: [dataNum], dataType: MLMultiArrayDataType.double )
        
    for (index, data) in compAccArray.enumerated(){
        mlarray[index] = data as NSNumber
    }
        
    // input data to CoreML model
    let model = iPhoneModel()
    guard let output = try? model.prediction(input:
        iPhoneModelInput(input1: mlarray)) else {
                fatalError("Unexpected runtime error.")
    }

    classLabel = output.classLabel
}
```
今回は学習データとしてiPhone本体の加速度XYZを使っています。ただし、本体の向きの影響を受けないように実際にはその合成加速度を入力としています。compAccArrayにはその配列が格納されていると思ってください。データ長（inputDataLength）は今回**50**としました。
また、モデルに入力するデータの型として[MLMultiArray](https://developer.apple.com/documentation/coreml/mlmultiarray)に変換する必要があるので注意です。

Kerasでモデルを出力する際は「iPhoneModel.mlmodel」という名前にしました（モデルの出力手順は[こちらの記事](https://qiita.com/FollowTheDarkside/items/6abe40d4f01aa2a3724d)でも少し触れています）。そのためインスタンスの生成は`let model = iPhoneModel()`となっています。
最終的な予測結果（分類クラスのラベル）はclassLabelに文字列として格納されます。

#さいごに
今回はAIによるロックダンスの動作識別を試してみました。もちろん、データ次第で他の分野にも応用可能です。ちなみに私はブレイクダンサー（BBOY）なのでそちらのAIをメインに開発しています。

[【深層学習】AI（人工知能）にブレイクダンスの動きを識別させてみた【行動認識】](https://hahaeatora.hateblo.jp/entry/2018/10/14/183000)
[【ダンスAI】情動状態の判別・可視化に関する動画を公開しました【機械学習】](https://hahaeatora.hateblo.jp/entry/2020/03/01/200000)

他にもブログやSNSで自己満な情報を色々と発信していますので、よろしければ是非チェックしていただけると嬉しいです！
laravel認証機能

# 要件
既存のテーブルを使い認証処理
php artisanの認証機能を使う

# 認証機能作成

```
php artisan migrate
php artisan make:auth
```

# ログイン後リダイレクトされるurl指定

 
 - app\Http\Controllers\Auth\LoginController.phpのプロパティ変更

```php:LoginController.php
protected $redirectTo = '/test';
```
jquery Ajax に連想配列で渡したいけど渡らない時

```js:error

//↓この配列を渡したい 
var paramData = [];
paramData['a'] = "aa";
paramData['b'] = "b";

var result = $.ajax({
		type : "GET",
		url : "/api/index.php",
		async: false,
		data :paramData
	}).responseText;

document.write(result);

```

paramData を「/api/index.php」に渡したいけど渡らない、、

```js:ok
//配列の初期化が問題でした
//↓これにしたらOK
var paramData = {};

paramData['a'] = "aa";
paramData['b'] = "b";

var result = $.ajax({
		type : "GET",
		url : "/api/index.php",
		async: false,
		data :paramData
	}).responseText;

document.write(result);
```
これ、何が違うのだろう?後日調査。
var paramData = [ ];
var paramData = { };
docker-compose up -d --buildとは

何も考えずに`docker-compose up -d --build`って打つのはあかんよな…

## オプションの説明

### デタッチモード `-d`オプション
オプションの`-d`でデタッチモードとして起動する！
バックグラウンドでコンテナを起動してくれるので同じターミナルで作業を続行する事ができます！

```
$ docker-compose up
// コンテナは起動するけど、このターミナルでコンテナを起動しているので別の作業をさせてくれない

$ docker-compose up -d
// コンテナをバックグラウンドで起動！！同ターミナルで作業を続行できる。
```

### イメージ構築 `--build`オプション

`--build`オプションを使えばDockerfileの書き換えなどのビルド処理の変更をイメージに反映させます。
その後そのイメージを元にコンテナを起動します。

```
$ docker-compose up
// イメージを元にコンテナを起動します。イメージがなければイメージのビルドから始めます。

$ docker-compose up --build
// イメージのビルドから始めてコンテナを起動します。
```
nRF52でBLEデバイスを開発する（３）nRF52840のRTTでログ出力する

この記事は、[nRF52でBLEデバイスを開発する（２）OTAアップデート Buttonless DFUとSecure DFU](https://qiita.com/jiro-aqua/items/97c8ec6910d584281b7a)の続きです。

# はじめに

　nRF52840-DKにFeather nRF52840をSWDケーブルで接続すると、FeatherのUARTはDKのデバッグマイコンには接続されないため、UARTでのログ取りができません。SWDのRTT(Real Time Terminal)機能でログを出力する必要があります。

# SDKの設定

　nRF52 SDKの各種設定のために、各プロジェクトは sdk_config.h をインクルードするように設定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89529/7d592987-f820-d56b-d1a0-db44d8778a70.png)

　各モジュールの設定値を変更する際は、この中を書き換えることになります。

# RTTログの設定
　RTTログを有効にするためには、sdk_config.h内の以下の部分を変更します。

```sdk_config.h
// ログ機能の有効化
#ifndef NRF_LOG_ENABLED
#define NRF_LOG_ENABLED 1
#endif

// RTT ログの有効化
#ifndef NRF_LOG_BACKEND_RTT_ENABLED
#define NRF_LOG_BACKEND_RTT_ENABLED 1
#endif

// UARTログの有効化
#ifndef NRF_LOG_BACKEND_UART_ENABLED
#define NRF_LOG_BACKEND_UART_ENABLED 1
#endif
```
　ここの設定値に１を定義することで、各機能が有効になります。

　nRF52832では、ここの設定のみでsesのターミナルウインドウにログが出力されるようになります。

# nRF52840

　ですが、nRF52840では、上の設定だけではログが出ません。少し前のSDKからのバグのようです。

```
#ifndef NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED
#define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 0
#endif
```
　上の定義を0にすることで、nRF52840でもログが出るようになります。

# ログ機能の初期化
　以下のコードでログ機能の初期化を行います。通常main.cの先頭の方で呼ばれます。

```
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();
```
　ログ出力は以下のマクロで。

```
    NRF_LOG_INFO("Application started.");
```
 nrf_log.hに各種マクロが定義されています。
- NRF_LOG_XXXX() 系はprintf関数として動作します。
- NRF_LOG_HEXDUMP_XXXX() 系は、ポインタの先をダンプします。
- NRF_LOG_FLOAT() でfloatの固定フォーマット出力が出来ます。


以上です。
NLBでTLS終端を行いAtlasのLiveMigrationを行う

## MongoDB Atlasの[LiveMigration](https://docs.atlas.mongodb.com/import/live-import/)を用いるときの覚書2

前回 [AWS上のMongoDBをAtlasにLiveMigrationする](https://qiita.com/georgeOsdDev@github/items/1c46ad38a1a8ee402aed) の続き

Atlas上でLiveMigrationを実行する際、`Is SSL enabled?` というトグルスイッチがある。


Atlasのドキュメントでは
>If the source cluster uses TLS/SSL, toggle the SSL button.
>If the source replica set uses TLS/SSL and is not using a public Certificate Authority (CA), copy the contents of the source cluster’s CA file into the provided text box.

とある。
これは LiveMigrationのバックエンドである `mongomirror` シェルにおける [`--ssl` オプション](https://docs.atlas.mongodb.com/reference/mongomirror/#cmdoption-ssl) に該当しているものと考えられる。

もともとEC2上のDBサーバーは、同一のプライベートサブネット内のAPサーバーからのみアクセスされており、[TLS/SSL起動オプション](https://docs.mongodb.com/manual/tutorial/configure-ssl/)は指定していない。

今回LiveMigrationを利用するためインターネット経由でDBサーバーへアクセスできるようにする必要があり、そのためにNLBを導入した。
インターネットを経由するので、`Is SSL enabled?`は有効にして、Atlasとの通信は暗号化したい。
TLS/SSL起動オプションを付与してDBサーバーを再起動することは避けたいため、NLBにてTLS終端することで、この課題を解決する。
下図の１の通信が該当する。

```
[Atlas LiveMigration] <-1-> [NLB] <-2-> [MongoDB on EC2]
```

方法は以下の通り、
1. NLBのListenerの設定を `TLS 27017`とする。
2. 証明書はACMに存在するものを利用する。
3. ターゲットグループ側のProtocol/Portは`TCP 27017`にする。
4. Route53で所有するドメインにおいて任意のサブドメインを作成し、NLBへのエイリアスに紐付ける。

こうすると、

| コマンド       | 接続可否 |
|:-------------|:---------:|
|`mongo mongodb://<LBのDNS> --ssl`|☓|
|`mongo mongodb://<LBのDNS> --ssl --sslAllowInvalidCertificates`|○|
|`mongo mongodb://<Route53で設定したDNS>`|☓|
|`mongo mongodb://<Route53で設定したDNS> --ssl`|○|

となる。

AtlasでLiveMigrationのHostには、`<Route53で設定したDNS>` を利用することで安全にLiveMigrationが利用できる。


参考
- [Amazon Web Services ブログ 新機能 – Network Load Balancer の TLS 終端](https://aws.amazon.com/jp/blogs/news/new-tls-termination-for-network-load-balancers/)
Rails6 のちょい足しな新機能を試す90（process_middleware.action_dispatch編）

# はじめに

Rails 6 に追加された新機能を試す第90段。 今回は、 `process_middleware.action_dispatch` 編です。
Rails 6 では、`ActiveSupport::Notifications.subscribe` で、`process_middleware.action_dispatch` で実行される middleware の情報を取得できるようになりました。

Ruby 2.6.4, Rails 6.0.0 で確認しました。

```shell
$ rails --version
Rails 6.0.0
```

今回は、User の CRUD を作り、各コントローラのアクションを実行したときの情報を取得してログに出力してみます。

# プロジェクトを作る

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

# User の CRUD を作る

name をもつ User の CRUD を作ります

```shell
bin/rails g scaffold User name
```

# Subscribe する

`config/initializers/notification_subscriber.rb` を作成します。
`ActiveSupport::Notifications.subscribe` を呼び出すときに、引数で、`process_middleware.action_dispatch` を指定して、ミドルウェアの情報をログに出力するようにします。

```ruby:config/initializers/notification_subscriber.rb
ActiveSupport::Notifications.subscribe 'process_middleware.action_dispatch' do |event|
  Rails.logger.info(event.payload[:middleware])
end
```

# User の登録などをしてログを確認する

実際に `rails server` を実行してブラウザから http://localhost:3000/users にアクセスします。

以下のようにコンソールに出力されているはずです。

```
...
Rack::TempfileReaper
Rack::ETag
Rack::ConditionalGet
Rack::Head
ActionDispatch::ContentSecurityPolicy::Middleware
ActionDispatch::Flash
ActionDispatch::Session::CookieStore
ActionDispatch::Cookies
ActiveRecord::Migration::CheckPending
ActionDispatch::Callbacks
ActionDispatch::Reloader
ActionDispatch::ActionableExceptions
ActionDispatch::DebugExceptions
WebConsole::Middleware
ActionDispatch::ShowExceptions
Rails::Rack::Logger
Sprockets::Rails::QuietAssets
ActionDispatch::RemoteIp
ActionDispatch::RequestId
Rack::MethodOverride
Rack::Runtime
ActiveSupport::Cache::Strategy::LocalCache::Middleware
ActionDispatch::Executor
ActionDispatch::Static
Rack::Sendfile
ActionDispatch::HostAuthorization
Webpacker::DevServerProxy
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try090_instrument_middleware

# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [Instrument middleware processing](https://github.com/rails/rails/commit/04ae0b0b5e594e0bb99c5cd608921745977bcdcd)
heroku・solidusのアドミンの作成

#この記事の目的
　solidusをherokuにデプロイ後、データを追加したい！データの持つ要素を変更したいと思った事ありませんか？
　ローカルでアドミンを作成し、データを追加したり、データの要素を変更したりしていたのですが、herokuにデプロイしたら、それらが反映されませんでした。どうやったら、反映させることができるのかわからず、途方にくれていたところ、herokuでもadmin作成できたら解決できるのでは？？と思い、実行したところ、herokuでもsolidusのadminが作成できたので、その方法を書いていこうと思います。

#方法
heroku login後、
`$heroku run rake spree_auth:admin:create`
を実行する。
後は、ローカル時と同じで、mailアドレス等の入力を求められるので、入力していく。
これで完成！

後は、herokuのurl/adminでadminページへ移行して先程のemailなどを入力していくと、adminページに入れます
SVNで.gitignoreを使う

# `.gitignore`をSVNに使う
SVNのignore設定はgitの.gitignoreと文法は同じ。
例えば、Androidプロジェクトの`.gitignore`は以下の通りで、これをそのままSVNのリポジトリへ再帰的に無視に設定する。

```.gitignore:.gitignore
.svnignore
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
```

## Step1 改名
`.gitignore`を`.svnignore`として、管理するディレクトリ直下に保存する。

## Step2 propset
以下のコマンドで`.svnignore`を`svn:ignore`に当てる。再帰的に強制的に。
```
cd 管理するディレクトリ
svn propset svn:ignore -R -F .svnignore .
```
※svnのパスを通す`C:\Program Files\Apache-Subversion-1.11.1\bin`とか

## Step3 コミット
`.svnignore`をコミットしてしまう。

## Step4 無視リスト`svn:ignore`を確認
以下のコマンドで、階層以下のすべてで、指定したファイル郡を無視している設定を確認できる。
```
svn propget -R svn:ignore .
```

## Step5 リポジトリにプロジェクトを追加したら、無視されることを確認

## 注意
無視に設定しても、これからAddやCommitのときに無視されるだけで、既に管理しているファイルは消えない。
既に管理している上記ファイル郡は手動でDeleteすること。
VMware仮想マシンのMACアドレスを固定にする方法

もともとMACを自動発番にしていたけど、とある理由により現在振られているMACアドレスから動かないようにする必要が出てきたのでメモ。

## 【ダメなパターン】GUIから普通に設定
仮想マシンの詳細設定を開き、該当マシンのNIC設定からMACアドレスを手動に変えて保存します。
![nic_macstatic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97774/46342ad2-7634-fd56-6897-29706971f550.png)

設定変更自体は完了するのですが、仮想マシンを起動しようとするとこんなエラーが出てしまいました。
> 仮想マシン <マシン名> のパワーオンに失敗しました。固定イーサネットアドレス「XX:XX:XX:XX:XX:XX」は許可されません。VMwareが予約したMACと競合しています。

![staticmac_rejected.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97774/40018b62-5717-75d1-babf-886e811aa96b.png)

よくよく調べると「00:0C:29」で始まるMACアドレスはVMwareの自動発番予約MACとして定義されていて仮想マシン起動時にチェックされているみたいでした。


##【これでOK】仮想マシン定義(.vmx)を直接編集
対象の仮想マシンはシャットダウンしておきましょう。
仮想ホスト(ESXi)にSSH接続後、定義ファイルを修正していきます

```shell-session:
# cd /vmfs/volumes/<データストア名>/<仮想マシン名>   # ディレクトリ移動
# cp -p <仮想マシン名>.vmx <仮想マシン名>.vmx.bak    # 念のためバックアップ
# vi <仮想マシン名>.vmx
```
```shell-session:.vmx修正例
# 追記(あれば修正)
ethernet<NIC番号>.checkMACAddress = "false"     # 予約アドレスかどうかのチェックを無効化
ethernet<NIC番号>.addressType = "static"        # MACを手動設定
ethernet<NIC番号>.Address = "XX:XX:XX:XX:XX:XX" # 設定したいMACアドレス
# 削除
ethernet<NIC番号>.generatedAddress = "XX:XX:XX:XX:XX:XX" # 自動生成されたMACアドレス
```

上記作業後に仮想マシンを起動すればエラーなく起動するはずです。



## メモ
本来、VMware仮想マシンでMACを固定にするのであれば「00:50:56」から始まるMACにするのが正しいみたいです。
MACを固定にするのがあらかじめわかっているVMware仮想マシンであればそのようにしましょう。


## 参考
* 仮想 NIC の静的 MAC アドレスを設定する: https://kb.vmware.com/s/article/219?lang=ja
NodeでURLをループしてスクレイピングするツールを作成


### モジュールは`puppeteer`を使用

``` js:app.js
const puppeteer = require('puppeteer')
const URLS = require('./url.json')

!(async () => {
    try {
        // urlの数だけ。
        for (let i = 0; i < URLS.url.length; i++) {
            let browser = await puppeteer.launch()
            let page = await browser.newPage()

            let result = await getData(page, URLS.url[i])
            // ーーーーーgetデータ処理ーーーーーーー
            console.log(result)

            browser.close()
        }
    } catch (e) {
        console.error(e)
    }
})()

// データ取得ロジック
async function getData(page, url) {
    await page.goto(url) // ページへ移動
    let get_object = await page.evaluate(() => {
        // jsで取得データをリターン 欲しい要素をここで取る
        let data = document.getElementsByClassName('className')[0].innerHTML
        return data
    })
    return get_object
}

```


URLファイルのモジュールはこちら

``` json:url.json
{
    "url": [
        "https://qiita.com/",
        "https://qiita.com/timeline"
    ]
}
```


###　参考
https://qiita.com/tomi_shinwatec/items/a68cf7840c3da002c6e0
2次元配列（多次元配列）合計値、平均値などの求め方-java

*個人的な感覚でエクセルの行と列を基準としています

２次元配列では[]を二つ[][]と宣言する。

```java:sample
                int[][] score = {
                { 1, 2, 3, 4, 5 },          // 0行目
                { 10, 20, 30, 40, 50 },     // 1行目
                { 100, 200, 300, 400, 500 } // 2行目
	        };
        System.out.println(score[行目][列]);
        System.out.println(score[0][0]);    // 0行目の0列
        System.out.println(score[1][1]);    // 1行目の1列
        System.out.println(score[2][3]);    // ２行目の3列


	//0行目0列から始まることに注意する


		int[][] array = {
					{1,2,3,4},
					{10,20,30,40,50,60},
					{1000,10000}
				};

		// 2次元配列arrayに含まれるすべての整数要素を順に出力
for(int i=0; i<array.length; i++) { // 配列名.lengthで 列（縦方向）の要素数を取得
	for(int s=0; s<array[i].length; s++) { // 配列名[i].lengthで 行（横方向）の要素数を取得
		System.out.println(array[i][s]); //array[縦][横]
			}
		}
```        
  

コンソール結果
1
2
3
4
10
20
30
40
50
60
1000
10000


＊上記の配列の合計値の求め方

```java:sample
		int sum = 0;
		for(int i=0; i<array.length; i++) {
			for(int s=0; s<array[i].length; s++) {
				sum += array[i][s];
			}
		}
		System.out.println(sum);
	}
```
コンソール結果
11220

*平均値を求めるとき

```java:sample
		int sum = 0;
		int count = 0;
		for(int i=0; i<array.length; i++) {
			for(int s=0; s<array[i].length; s++) {
				sum += array[i][s];
				count++;
			}
		}
		System.out.println(sum/count);
	}
```
コンソール結果
935
NodeJSデーモン化

## 導入
`npm install -g forever`
 * グローバルに導入

- 起動   
`forever start -l forever.log -w app.js`   
`forever start -w app.js`
 * -w Node.jsファイルの中身を編集した際に自動的に検知して再実行してくれる監視機能が追加
- リスト
`forever list`
- ログ
`forever logs`
- 停止
`forever stop app.js`
macOSのシステムヘッダ

# /usr/includeロス

Mojaveからシステムヘッダ/usr/includeにインストールされなくなりました。システムヘッダを使うソースをコンパイルしようとすると，stdlib.hがないなどと文句が出て，コンパイルできないことがあります。

## インストールする?

Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkgからインストールする[方法](https://qiita.com/labocho/items/b966149e7e9700414bbc)が紹介されています。これで一応解決できるのですが，別の方法があります。

## システムヘッダのありか

実は/usr/includeにはありませんが，違う場所にインストールされています。これを`-isysroot`で指定すればコンパイルが通ります。
ヘッダの場所はSDK（例 /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk）の下です。

* [gccマニュアル](https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html)
* [clangマニュアル](https://clang.llvm.org/docs/UsersManual.html#command-line-options)

## CMake

[CMAKE_OSX_SYSROOT](https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_SYSROOT.html#variable:CMAKE_OSX_SYSROOT)を指定します。

## MacPorts

MacPortsでは${configure.sysroot}にSDKへのパスが入っています。 


## 履歴

* 2019-10-07 13:23 gcc, clangのマニュアルへのリンクを追加
Laravel5.8 メールの件名(From)が文字化けしてしまう時の対処法

# ユーザ向けの自動返信メールのFrom（送信者情報）を変えたところ文字化けしてしまったので自分用メモ

```php:app/Mail/Mail.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class Contact extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($mail)
    {
        // Fromメールアドレス
        $this->mail = $mail;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        // mb_encode_mimeheader()でFromをエンコードする
        return $this->from($this->mail, mb_encode_mimeheader('〇〇運営事務局'))
        ->subject('HPからのお問い合わせありがとうございます。')
        ->text('mails/contact');
    }
}
```

ぶっちゃけLaravelはそんなに関係ないメールあるあるだけど、迷える子羊のために（自分）残しておく
【Unity(C#)】キーボードの連続入力を禁止する

##入力にインターバルを設ける

連続を禁止する、それすなわち**入力にインターバルを設ける**ってことです。
もっとかみ砕いて言うと、
**n秒間隔でしか入力ができないオレオレカスタムインプット**を作ろうってことです。

##コード

前回作った[同時入力禁止](https://qiita.com/OKsaiyowa/items/e640a303daceab8f9bf9)のためのクラスに加筆しました。
かっこつけて見様見真似で`<summary>`を書いてます。間違ってたら陰で馬鹿にした後にご指摘お願いします。

```C#:CustomInput.cs
using UnityEngine;

namespace CustomInputKey
{
    /// <summary>
    /// Custom InputKey
    /// </summary>
    public static class CustomInput
    {
        static bool isCheck_Input;
        static bool preventContinuityInput;

        static float buttonDownTime;
        static float timer;

        /// <summary>
        /// Simultaneous input prohibited
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool SingleInputKeyDown(KeyCode key)
        {
            if (Input.anyKeyDown == false) isCheck_Input = false;

            if (isCheck_Input == false)
            {
                if (Input.GetKeyDown(key))
                {
                    isCheck_Input = true;
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Continuity input prohibited
        /// </summary>
        /// <param name="key"></param>
        /// <param name="intervalSeconds"></param>
        /// <returns></returns>
        public static bool Interval_InputKeydown(KeyCode key,float intervalSeconds)
        {
            timer = Time.time;

            if (Input.GetKeyDown(key) && timer - buttonDownTime >= intervalSeconds)
            {
                if (preventContinuityInput==false)
                {
                    preventContinuityInput = true;
                    buttonDownTime = Time.time;
                    return true;
                }
                else if(preventContinuityInput)
                {
                    preventContinuityInput = false;
                    buttonDownTime = Time.time;
                    return true;
                }
            }

            return false;
        }
    }
}
```

　　
呼び出すときは
namespaceに`using CustomInputKey;`を書いて

```C#:インターバル3秒に設定して呼び出し
    if(CustomInput.Interval_InputKeydown(KeyCode.Space,3))
    {
        print("3秒待つと押せるよ");
    }
```

でいけます。




##次回unity1week 10/14開催

次のunity1weekで活躍させて、操作性の向上につなげようと思います。
【VBA】標準関数で定義エラー！？

#はじめに
**「標準関数でオブジェクト定義エラー？」**っていう意味わからないことに遭遇しました。
学ぶことが多かったので、記事にしたいと思います。

#１．標準関数とは
プログラミング言語に組み込まれている、入出力や文字列操作などといった、基本的な関数のこと。
例えば、print文やfor文、if文といったような関数のことです。

#２．オブジェクト定義エラーとは
このエラーの意味は、そんな関数存在しませんよ！っていう感じですね、
よくあるのは**関数のスペルミス(print→pirnt)**とかですかね？
なかなか実際に存在しない関数（タイプミスとかではなくマジで存在しない関数）を呼び出すことは少ないと思います。

理由は、プログラムコードは自分の知っている関数と検索によって知った関数で構成されるから。

だから、関数の存在を確認、スペルミスの確認をすることでこのエラーは対応できる。
ってことで、
**関数の存在確認、ネットで確認するか～**ってやるのは、あまり良くない。
ネットで存在の確認をしたところで、自分の開発環境になければ意味がないからです。
**バージョンが違う可能性を考え、きちんと自分の開発環境上に関数が存在するかを確認しましょう!**

#３．関数の存在確認
関数の確認方法です。
**エクセルでマクロを開き、F2を押す**（オブジェクトブラウザが開く）。
そこで、関数を検索することができます。

自分の場合、ネットで関数の存在が確認でき、また自分の開発環境にも関数が存在することが確認できた。
しかし、なぜかエラーを吐いたファイルだけ、よく見ると、標準関数の参照先が変わっていることに気づきました。

気づいたはいいものの、、、
問題は、エクセルの標準関数の参照先の変え方が分からないこと。**そもそも変更不可能な可能性**すらあります。（標準関数の参照先の設定は、自動で行われるため）

結局新しくファイルを作り直すことで対応することはできましたが。そもそもなんで参照先が変更されたのか？

#４．標準関数の参照先変更が生じると思われる原因
ここからはあくまで推測です。可能性の話。

考えられる原因は、
**・古いバージョンのエクセルでファイルを開く
・最新の標準関数のファルダがなく、旧バージョンの標準関数のフォルダが設定された**

もちろん手動で変更ができるような項目ではなさそうなので、あまり原因の追究に意味はないかもしれないですが、古いバーションでファイルを開くことで、プログラムが変更される可能性があり、それが原因で動かなくなるといったことが発生するとことを学びました、

**不用意なファイルのやりとりはせず、できるだけ同じ開発環境で開発を続ける方がよいという事の意味を実感できるエラーでした。**

#おわりに
動作環境の違いによるエラーの対応は、今回が初めてで原因解明までかなりの時間を要してしまいました。ソフトウェアのリリースともなるとこのような問題はついてまわりそうですね。また、やはり推奨動作環境条件を満たすということも実感できました。推奨動作環境の定義とかって、どういう風に決定されているのか気になりました。
enumとenum class

# enum

```sampleEnum.cpp
enum SampleEnum : int
{
    se1,
    se2
};

void Function()
{
    auto val1=se1;    
    auto val2=SampleEnum::se2;
    std::cout << "val1:" << val1 << ",val2:" << val2 << std::endl; 
}
```
- スコープを持たない列挙型
- 暗黙的にint型になる

# enum class

```sampleEnumClass.cpp
enum class SampleEnumClass : int
{
    sec1,
    sec2
};


void Function(){
    // auto val1=sec1;  // !コンパイルエラー
    auto val2=SampleEnumClass::sec2;
    std::cout << "val2:" << static_cast<int>(val2) << std::endl; 
}

```

- 明示的なキャストが必要になる
- enum class 名を明示的なスコープとして指定する必要がある

# 共通すること


- enum (class) `hoge` の後に規定型を指定できる
- 前方宣言ができる

# 比較
| | 例 | enum | enum class |
| ------ | :------------------ | :------------------- | :----------------- |
| 規定型の指定 | enum SampleEnum : **int** | ○できる| ○できる |
| 前方宣言 | enum SampleEnum : int; | ○できる| ○できる |
| 列挙への直接的なアクセス | auto = se1;| ○できる | ×できない |
| 列挙への直接的なアクセス例 | | SampleEnum v = se1;<br>SampleEnum v=SampleEnum:se1; | SampleEnumClass v = SampleEnumClass:sec1;|
| 値をint型としてアクセス | | int i=v; | int i = static_cast\<int\>(v)|
webpackでビルドしようとした時に出たエラーでハマったとこ

webpackでビルドしようとした時に

```errorlog
Error: options/query provided without loader (use loader + options) in {
  "test": {},
  "use": [
    {
      "loader": "babel-loader"
    }
  ],
  "options": {
    "presets": [
      "@babel/preset-env"
    ]
  }
}
```
と出た時の解消にちょっとハマりかけたのでメモ

## 解決方法
```webpack.config.js
{
test: /\.js$/,
use: [
  {
    loader: "babel-loader",
    query: {
      presets: [
        "@babel/preset-env"
      ]
    }
  }
]
}
```
色々と調べてみたら、こう書いたら一応解消はできた。
正しいかどうかはわからないけど、ひとまず。
OCIでコンソールログインを検知する

# やったこと
デフォルトで取得されてる監査ログからEvent使ってメール通知をやりたかったが、イベントタイプに監査っぽいのがない！ので、ociコマンドと使って日次バッチ的にログイン履歴を取得する方法に方向転換。

# 事前に必要なもの
## ocicli
この記事を参考にインストール
[コマンドライン(CLI)でOCIを操作する - Oracle Cloud Infrastructureアドバンスド](https://community.oracle.com/docs/DOC-1019624)

##jq
普通に# yum install jq

# コマンド(bash前提)
・本日のコンソール・ログイン履歴を出力するコマンド

```
$ TENANCY_ID=ocid1.tenancy.oc1..aaaxxxxxx # 自身のテナントIDを入力
$ START_DAY=$(date '+%Y-%m-%d 00:00')
$ END_DAY=$(date -d '1 days' '+%Y-%m-%d 00:00')

※oci cliの接続先リージョンをホームリージョンに設定しないと、ログオンの監査レコードを取得できない
※[追記] JSONフォーマットが変更になったっぽく、以下のコマンドでは整形出来なくなった
$ oci audit event list  --start-time "${START_DAY}" --end-time "${END_DAY}" --all -c ${TENANCY_ID} --query 'data[?"event-source"==`IdentitySignOn`]' |jq -r '["event-source","event-name","user-name","event-time","response-status","request-origin"] ,(. [] | [."event-source",."event-name",."user-name",."event-time",."response-status",."request-origin"] )|@csv'~~

"event-source","event-name","user-name","event-time","response-status","request-origin"
"IdentitySignOn","InteractiveLogin","xxuser_namexx","2019-10-07T00:03:03.629000+00:00","200","xx.xxx.xx.xxx"
"IdentitySignOn","InteractiveLogin","xxuser_namexx","2019-10-07T01:21:02.032000+00:00","401","xx.xxx.xx.xxx"
"IdentitySignOn","InteractiveLogin","xxuser_namexx","2019-10-07T01:21:25.495000+00:00","200","xx.xxx.xx.xxx"
"IdentitySignOn","FederatedInteractiveLoginAttempt","","2019-10-07T02:32:01.625000+00:00","200","xx.xxx.xx.xxx"
"IdentitySignOn","InteractiveLogin","xxuser_namexx","2019-10-07T05:47:34.890000+00:00","200","xx.xxx.xx.xxx"
"IdentitySignOn","InteractiveLogin","xxuser_namexx","2019-10-07T05:47:58.850000+00:00","200","xx.xxx.xx.xxx"
"IdentitySignOn","InteractiveLogin","xxuser_namexx","2019-10-07T05:58:33.618000+00:00","200","xx.xxx.xx.xxx"

※ociコマンドで本日分のログイン履歴をjsonで取り出して、jqでcsvに整形
※xxuser_namexxは、実際はログインユーザ名が表示される。IDCSからのログイン(FederatedInteractiveLoginAttempt)の場合は出力されない。
※ステータスコードが200じゃない場合は、ログイン失敗(試した限り)

※[追記] 2019.11現在、以下のコマンドで取得できることを確認
oci audit event list  --start-time "${START_DAY}" --end-time "${END_DAY}" --all -c ${TENANCY_ID} \
 --query 'data[?"source"==`IdentitySignOn`]' \
  |jq -r '["event-time","source","event-name","principal-name","ip-address","status"],
   (. [] |[ ."event-time"
           ,."source" 
           ,(."data"."event-name")
           ,(."data"."identity"."principal-name")
           ,(."data"."identity"."ip-address")
           ,(."data"."response"."status")]
    ) |@csv'
"2019-11-04T11:04:07.845000+00:00","IdentitySignOn","InteractiveLogin","xxuser_namexx","xx.xxx.xx.xxx","200"
"2019-11-04T12:20:03.218000+00:00","IdentitySignOn","InteractiveLogin","xxuser_namexx","xx.xxx.xx.xxx","200"

```

# 結論
レコードの有無を判断して、検知はできそう。ほんとはEventで簡単に実装したい。
Vue.jsにBootstrapを適用させる方法

## はじめに
BootstrapにはVue専用のものがあり、タグも独自の物が存在するので自分と同じような駆け出しエンジニアの方に共有したいと思ってこの記事を作成致しました。
Bootstrapを適用させる方法は従来通り`class="btn"`などと記入する方法と、vue独自の`<b-button>`などのタグを使用する方法と二種類あるので、どちらも解説していきます。

## VueにBootstrapをインストールする
まずBootstrapにはVue専用の物がありますので、そちらをインストールしましょう。
ターミナル or コマンドプロンプトを開いて、

Bootstrapを適用させたいVueプロジェクトに移動
```
$ cd vue-app
```

Bootstrapをインストール
```
$ yarn add bootstrap-vue
```
これでok。
npmの場合は`yarn add`ではなく

```
npm install bootstrap-vue
```

## classでBootstrapを使用する場合
### Bootstrapをテンプレート内で使用できるようにする
src/main.jsに下記の記述を追加します。

```diff_javascript:main.js
import Vue from 'vue'
import App from './App.vue'
+ import 'bootstrap/dist/css/bootstrap.css'
+ import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.config.productionTip = false
```
これで準備はokです。あとは従来通り書いていくだけ。

### 確認してみる
src/App.vueにボタンを表示させてみましょう。

```diff_vue:App.vue
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/>
+   <button class="btn btn-primary">bootstrap</button>
  </div>
</template>
```
表示を確認してみましょう。
![localhost_8080_-min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/52f85b45-b176-babb-e302-be3fce35f8f5.png)

問題なくボタンが表示されているのが確認できました。
当たり前ですが、Vueではなく普通にHTML/CSSを書く時はこちらの記述方式でいくことになります。

## タグでBootstrapを使用する場合
続いて、Vue独自のBootstrapを使用してみましょう。
ちなみに、各タグのテンプレートは公式のこちらにあります。
https://bootstrap-vue.js.org/

### Bootstrapをテンプレート内で使用できるようにする
src/main.jsに下記の記述を追加します。

```diff_javascript:main.js
import Vue from 'vue'
import App from './App.vue'
+ import BootstrapVue from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
+ Vue.use(BootstrapVue)
Vue.config.productionTip = false
```
先ほどと違うのは、

```javascript
import BootstrapVue from 'bootstrap-vue'
```
Vue用のBootstrapを読み込む記述と、それを使用できるようにする為の

```javascript
Vue.use(BootstrapVue)
```
の記述が追加されています。
## 確認してみる
src/App.vueにボタンを表示させてみましょう

```diff_vue:App.vue
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/>
    <button class="btn btn-primary">bootstrap</button>
+   <b-button variant="primary">bootstrap</b-button>
  </div>
</template>
```
違いを比較すると、`class="btn"`が`<b-button></b-button>`に置き換えられて、`class="btn-promary"`は`variant="primary"`に置き換えられているという訳ですね。
では表示を確認してみましょう。
![localhost_8080_ (1)-min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/b1fd081a-9eaa-e118-306a-32b1e6564c91.png)

同じようにボタンが表示されているのが確認できました。

## さいごに
どなたかの参考になれば嬉しいです。
誤字脱字・発信した情報に間違い等ございましたら、ご指摘頂けますと幸いです:bow:
dbpediaの研究 その2

#概要

dbpediaが難解なので、手出してみる。
xhrで、json読んでみた。

#結果


```
{ "head": { "link": [], "vars": ["color_name", "color"] }, "results": { "distinct": false, "ordered": true, "bindings": [ { "color_name": { "type": "uri", "value": "http://ja.dbpedia.org/resource/\u9E7F\u6BDB" } , "color": { "type": "typed-literal", "datatype": "http://www.w3.org/2001/XMLSchema#integer", "value": "27" }}, { "color_name": { "type": "uri", "value": "http://ja.dbpedia.org/resource/\u9ED2\u9E7F\u6BDB" } , "color": { "type": "typed-literal", "datatype": "http://www.w3.org/2001/XMLSchema#integer", "value": "11" }}, { "color_name": { "type": "uri", "value": "http://ja.dbpedia.org/resource/\u6817\u6BDB" } , "color": { "type": "typed-literal", "datatype": "http://www.w3.org/2001/XMLSchema#integer", "value": "10" }}, { "color_name": { "type": "uri", "value": "http://ja.dbpedia.org/resource/\u82A6\u6BDB" } , "color": { "type": "typed-literal", "datatype": "http://www.w3.org/2001/XMLSchema#integer", "value": "2" }}, { "color_name": { "type": "uri", "value": "http://ja.dbpedia.org/resource/\u9752\u9E7F\u6BDB" } , "color": { "type": "typed-literal", "datatype": "http://www.w3.org/2001/XMLSchema#integer", "value": "2" }}, { "color_name": { "type": "uri", "value": "http://ja.dbpedia.org/resource/\u9752\u6BDB" } , "color": { "type": "typed-literal", "datatype": "http://www.w3.org/2001/XMLSchema#integer", "value": "1" }}, { "color_name": { "type": "uri", "value": "http://ja.dbpedia.org/resource/\u6803\u6817\u6BDB" } , "color": { "type": "typed-literal", "datatype": "http://www.w3.org/2001/XMLSchema#integer", "value": "1" }} ] } }
```

#成果物

http://embed.plnkr.co/EBgEDiUk7VYzpLx5Oix1/


以上。
dbpediaの研究

#概要

dbpediaが難解なので、手出してみる。
xhrで、読んでみた。

#クエリー


```
select distinct ?color_name (count(?color_name) AS ?color) where {
  {
    ?name prop-ja:wikiPageUsesTemplate template-ja:有馬記念勝ち馬.
  }
  ?name rdfs:label ?label ;
    prop-ja:色 ?color_name.
} ORDER BY DESC(?color)
```    

#結果
xml


```    
<sparql xmlns="http://www.w3.org/2005/sparql-results#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/sw/DataAccess/rf1/result2.xsd"> <head> <variable name="color_name"/> <variable name="color"/> </head> <results distinct="false" ordered="true"> <result> <binding name="color_name"><uri>http://ja.dbpedia.org/resource/鹿毛</uri></binding> <binding name="color"><literal datatype="http://www.w3.org/2001/XMLSchema#integer">27</literal></binding> </result> <result> <binding name="color_name"><uri>http://ja.dbpedia.org/resource/黒鹿毛</uri></binding> <binding name="color"><literal datatype="http://www.w3.org/2001/XMLSchema#integer">11</literal></binding> </result> <result> <binding name="color_name"><uri>http://ja.dbpedia.org/resource/栗毛</uri></binding> <binding name="color"><literal datatype="http://www.w3.org/2001/XMLSchema#integer">10</literal></binding> </result> <result> <binding name="color_name"><uri>http://ja.dbpedia.org/resource/芦毛</uri></binding> <binding name="color"><literal datatype="http://www.w3.org/2001/XMLSchema#integer">2</literal></binding> </result> <result> <binding name="color_name"><uri>http://ja.dbpedia.org/resource/青鹿毛</uri></binding> <binding name="color"><literal datatype="http://www.w3.org/2001/XMLSchema#integer">2</literal></binding> </result> <result> <binding name="color_name"><uri>http://ja.dbpedia.org/resource/青毛</uri></binding> <binding name="color"><literal datatype="http://www.w3.org/2001/XMLSchema#integer">1</literal></binding> </result> <result> <binding name="color_name"><uri>http://ja.dbpedia.org/resource/栃栗毛</uri></binding> <binding name="color"><literal datatype="http://www.w3.org/2001/XMLSchema#integer">1</literal></binding> </result> </results> </sparql>
```


#成果物

http://embed.plnkr.co/DQT0PCRvbX8MUYjtpJjK/

以上。
【Android】AndroidStudio3.5からAIDLファイルの自動生成に失敗する

# この記事は
問題解決共有。どなたかの助けになれば幸いです。

# 発生した現象
AndroidStudioを3.5にバージョンアップした時から、Windows限定でAIDLファイルからの自動生成に失敗するようになった。
自動生成が途中で終了し、中途半端なファイルが出来上がってしまう。

# 発生した環境
* Windows 10
* Compile Sdk Version 29
* Android Gradle Plugin Version 3.5.0
* Gradle Version 5.4.1

# 原因
Docコメントが悪さをしていた。全て消すか、//に変更すれば良い。

```
/**
 * Docコメントは使用できない 
 */

// スラッシュを使えばコメントは書ける
```

# 備考
何故かMacではビルドが通るので、気にする必要がない人が大半なのかもしれません。
Windows限定のAndroidStudioのバグ？