OmniAICreator/Qiita-1.07M huggingface dataset:
SQL 新しい税率の適用日のみテーブルからデータを取得する時に終了日を付与する

## 概要

新しい税率の適用日のみテーブルからデータを取得する時に終了日を付与する

## 例（消費税率

|税率|開始日|
|--|----------|
|3%|1989/04/01|
|5%|1997/04/01|
|8%|2014/04/01|
|10%|2019/10/01|


## テーブル構造とデータ

```SQL
CREATE TABLE tbm_tax (
  id int(10) NOT NULL AUTO_INCREMENT,
  tax_type int(10) NOT NULL DEFAULT 0 COMMENT '税区分',
  rate int(10) NOT NULL DEFAULT 0 COMMENT '税率',
  start_dt varchar(255) NOT NULL COMMENT '開始日',
  del_flg int(1) NOT NULL DEFAULT 0 COMMENT '削除フラグ',
  PRIMARY KEY (id)
) ENGINE=InnoDB;
```

データ tax_type=1は消費税 2は何か別のもの
開始日が文字列でyyyy/mm/ddで入っている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1765459/fab78d68-94f0-60c4-35fa-cb1c48e13a5f.png)


## クエリ

### tax_typeをwhere区で指定する時はLAGを使うのが一番短い

```SQL
SELECT
    id
  , tax_type
  , rate
  , CAST(start_dt AS DATETIME) AS start_date
  , CAST(IFNULL(LAG(start_dt) OVER(ORDER BY start_dt DESC), '2199/01/01') AS DATETIME) - INTERVAL 1 SECOND AS end_date
FROM tbm_tax
WHERE
    tax_type = 1 -- 必須
AND del_flg = 0
ORDER BY
    start_dt ASC;
```

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1765459/75ce3b59-50f3-e14c-7e90-daf81c7a66b3.png)

### tax_typeを指定せず全てのレコードを取得したい時は次の通り

``` SQL
SELECT
    t1.id
  , t1.tax_type
  , t1.rate
  , CAST(t1.start_dt AS DATETIME) AS start_date
  , CAST(IFNULL(MIN(t2.start_dt), '2199/12/31') AS DATETIME) - INTERVAL 1 SECOND AS end_date
FROM tbm_tax AS t1
    LEFT OUTER JOIN tbm_tax AS t2
    ON t1.tax_type = t2.tax_type AND t1.start_dt < t2.start_dt AND t2.del_flg = 0
WHERE
    t1.del_flg = 0
GROUP BY
    t1.start_dt
ORDER BY
    t1.tax_type ASC,
    t1.start_dt ASC;
```

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1765459/10340f61-6398-2701-ca58-c4976abe7014.png)


## あとがき

「テーブルに終了日を持たせて１レコードを画面で登録時に、全レコードの終了日を更新」する方が簡単かもしれませんね。（前後のレコードとの整合性や期間の歯抜けなどのチェックはダルいんで終了日は入力させたくないかな）

## 参考

https://twitter.com/hyakkiti/status/1438108647242878979
[ShimaBlock]Python＆Seleniumで起動済みブラウザ(Chrome)に再接続して操作するサンプル

###概要
[ShimaBlock for Python](https://shima-block.shima-soft.com/python.html)の操作サンプルです。
Python、Seleniumを用いた、ブラウザ操作コードを生成します。

使用サイト：[ShimaBlock for Python](https://shima-block.shima-soft.com/python.html)

###ソースコード概要
起動したChromeを別のpyファイルから再接続して、ブラウザを操作します。
###使用ファイル
####chrome_open.py
ブラウザ(Chrome)を起動し、接続用URLとセッションIDをpickleファイルに格納します。
####chrome_reconnect.py
pickleファイルから接続用URLとセッションIDを取得し、webdriver.Remoteで再接続します。
再接続したChromeのURLを変更します。
####data.pickle
上記のpyファイル間のデータ連携用ファイルです。
「chrome_open.py」実行時に自動生成されます。

###Chrome起動＆接続設定保存(ブロック)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566115/d569dc0b-4cc8-609f-48f1-06b4384465c9.png)
###Chrome起動＆接続設定保存(生成コード)
```Python:chrome_open.py
from selenium import webdriver
import pickle

driver = None
session_id = None
url = None


driver = webdriver.Chrome()
driver.get('https://shima-soft.com/')
session_id = driver.session_id
url = driver.command_executor._url
with open('data.pickle', 'wb') as f:
  pickle.dump(session_id, f)
  pickle.dump(url, f)
```
###Chrome再接続＆URL変更(ブロック)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566115/4de731a3-043f-0db7-50f3-9c95ebfa4de1.png)
###Chrome再接続＆URL変更(生成コード)
```Python:chrome_reconnect.py
import pickle
from selenium import webdriver
import time

session_id = None
url = None
driver = None


with open('data.pickle', 'rb') as f:
  session_id = pickle.load(f)
  url = pickle.load(f)
options = webdriver.ChromeOptions()
options.add_argument('--headless')
driver = webdriver.Remote(command_executor=url,options=options)
driver.close()
driver.quit()
driver.session_id = session_id
driver.get('https://shima-block.shima-soft.com/')
time.sleep(1)
driver.get('https://shima-soft.com/')
```
arduinoで温度センサー

#概要

arduinoでrohmのDB1020を使ってみた。

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f2ad5eba-bd90-fedc-ff1f-590457a065e5.jpeg)

#配線

vcc - 5v
gnd - gnd
out - A0

#サンプルコード

```
#include "BD1020.h"

int tempout_pin = A0;

BD1020 bd1020;

void setup() {
	Serial.begin(9600);
	while (!Serial);
	bd1020.init(tempout_pin);
	Serial.println("BD1020HFV Sample");
}

void loop() {
	float temp;
	bd1020.get_val(&temp);
	//Serial.print("BD1020HFV Temp=");
	Serial.println(temp);
	//Serial.print("	[degrees Celsius], ADC=");
	//Serial.println(bd1020.temp_adc);
	delay(800);
}




```

以上。
【Fiori】Query BrowserでView Nameを選択した際のエラー解消方法

Query BrowserでView Nameを選択した際にエラーが発生。

エラー内容によって方法は異なるかと思いますが、CDS Viewが有効化されていないことによるエラーの場合の解消方法について書きます。

#事象
Fioriで「Query Browser」のタイルを選択。
一覧上でView Nameのリンクをクリックしたら返ってこない。
![step3 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22526/43a753b0-db86-7365-919c-3c152c2e6bbd.png)

#エラーログの確認
T-CD:/IWFND/ERROR_LOG
![スクリーンショット 2021-09-17 223148_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22526/511e8a53-ca22-a2e7-1283-157a4c0b0832.png)
「Database returned the SQL code 459. Error text: invalidated function: CDSDEFQRY」
SQL View: CDSDEFQRYが不正。
CDS Viewの技術名称だとCDS_DEFINITION_QUERYなので、それを有効化する。

#CDS View の有効化
T-CD:SE38 でレポートRUTDDLSACTを実行
DDL Source or View Namesの欄に、"CDS_DEFINITION_QUERY"と入力して実行
![スクリーンショット 2021-09-17 222703.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22526/0609c87f-5327-2314-1ec7-64ddf5c0beae.png)

これでエラー解消。
特定ユーザーのQiita記事一覧を得る(4)

[前回の記事](https://qiita.com/ELIXIR/items/417275e4c751c1fb59a0)のアップデートです。
記事を作成日時でソートするようにしました。
増えてきた自分の記事を検索するのにも役立ちます。

[動作デモ](https://elix.jp/app/tools/qiita_index.html?uuid=ELIXIR)
前回同様ローカル環境でも動作します。

[更新部分]

```
    var ALL_DISP_TAG = 'All';

    function dispData(_resArr,_tag=""){
      createButtons(_resArr,_tag);
      var articles = [];
      for(var i=0;i<_resArr.length;++i){
        if((_tag=="")||(_tag==ALL_DISP_TAG)||(articleContainsTag(_resArr[i],_tag))){
          var tmpStr = '<a href="'+_resArr[i]['url']+'" target="_blank">'+ _resArr[i]['title']+'</a><br/>';
          articles.push({'title':tmpStr, 'created_at':_resArr[i]['created_at']});
        }
      }
      articles.sort(function(a,b){ return ( a.created_at < b.created_at ) ? 1 : -1; });

      var str="";
      for(var i=0;i<articles.length;++i)
        str += articles[i]['created_at']+" "+articles[i]['title'];

      document.getElementById('iResult').innerHTML = str;
    }
```

結果：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/3e888e67-5ba4-b290-38fd-a23a651a90e6.png)

作成日時ではなくアップデート日時ソートしたい場合は
created_at を updated_at にします。
ps -ef の結果からユーザ単位でプロセス個数を表示するプログラム


# 概要

<font color=red>(追記開始)
指摘をいただき、psコマンド単独で完結する方法を教わりました.
コメント欄をご参照ください.
なお本記事の目的は awk の使用例ですので、引き続き掲載を続けております.
(追記終了)</font>

ps -ef の結果から、次のようにユーザ単位でプロセス個数を表示するプログラム.
用途よりも awk の練習に近い.[^1]

```bash
略
postgres => 14   # ← 所有者 postgres のプロセスが 14個ある
root => 296      # ← 所有者 root のプロセスが 296個ある
rtkit => 1
syslog => 1
略
```

## コード ps_cnt_per_user.sh

```bash
#!/bin/bash

# ps -ef コマンドの結果を書き出すための一時ファイルパスを定義する
TMPFILE=`mktemp -p /tmp`

# ps -ef の結果 (2〜最終行) を一時ファイルに書き出す (例: 563個のプロセス)
ps -ef | sed -n '2,$p' > $TMPFILE

# ps -ef に出現したユーザ名を抽出する (例: 23個のユーザ名)
USERS=`cut -d' ' -f 1 $TMPFILE | sort -u`

# $TMPFILE ファイルを読み込む.
# このとき、シェル変数 $USERS を awk の変数 users として渡す.
awk -v "users=$USERS" '
BEGIN {
    # (空白文字区切りで) 変数 users を取り出して、配列 users_list に格納する. (例: 要素数 23)
    # また、users_list の総個数 (ユーザ数) が TU に格納される. (例: TU の値は 23)
    TU = split( users, users_list ) # TU: ユーザの総数(Total num Uses)
    # 配列 encount の領域を、ユーザ数分だけ獲得する. (例: 要素数 23個)
    encount[TU] = 0                 # 該当ユーザの出現回数
}
{
    # ユーザ数 x プロセス数 だけループさせる. 無駄になるが良い方法が思い浮ばず.
    for( i = 1; i <= TU; i++ ) {    # 1 オリジンに注意！
        # 全プロセス数が記された TMPFILE ファイル (例: 563個のプロセス)を 1行ずつ読み出す.
        # なお、下記で「$1 ~ users_list[i]」にしてしまうと部分マッチとなり、
        # ユーザID が「9」の場合に「992」「993」などにもヒットしてしまうので注意すること.
        if($1 == users_list[i]){
            # プロセスが出現するたびに、ユーザ名をキーに持つハッシュ配列 encount の値を加算する
            encount[i] =  encount[i] + 1    # 出現回数を加算する
        }
    }
}
END {
    ps_cnt = 0
    # ユーザごとにプロセスの出現回数を表示する
    for( i = 1; i <= TU; i++ ) {
        printf("%s => %d\n", users_list[i], encount[i])
        ps_cnt += encount[i]
    }
    printf("---------------\n")
    printf("ps_cnt => %d\n", ps_cnt)    # プロセス総数を表示する
}' $TMPFILE

rm -f $TMPFILE
```

## 結果

```bash
$ ps_cnt_per_user.sh
992 => 3
994 => 2
996 => 18
997 => 2
998 => 17
avahi => 2
colord => 1
dnsmasq => 1
gdm => 34
kernoops => 2
message+ => 1
mongodb => 1
robozushi10 => 113
netdata => 14
nobody => 1
postgres => 14
root => 296
rtkit => 1
syslog => 1
systemd+ => 10
www-data => 19
xrdp => 1
zabbix => 6
---------------
ps_cnt => 560

```


[^1]: 個人的には、この複雑さになってきたら Python、Ruby で実装する.
iSHでyoutube-dlを管理するときはpip3を使わないと詰む

#iPhoneやiPadなどのiOSでyoutubeの動画をダウンロードできるのか！？
と思い立ったので試してみた。その時のつまづきメモ

##結論
まずこの二つ
`~# apk add python3 py3-pip`

さっき入れた`pip3`を使ってパッケージ(`youtube-dl`)を管理する
`~# pip3 install youtube-dl`

使い方は至ってシンプル
`~# youtube-dl https://youtu.be/hogehoge`

完了したら⚙マーク押して`Fileststems`→`default`→`Browse Files`→rootフォルダの中にある
##詰んだやり方(失敗)
`~# apk add youtube-dl`

```
Youtube said: Unable to extract video data
```
と出たのでとりあえずアップデートしようとした

```
~# youtube-dl --update

It looks you installed youtube-dl with a package manager, pip, setup.py or tarball. Please use that to update.
```
とでてアプデができなかった。なので上記「結論」のやり方で対応。
SORACOMのs+camera試してみました。

SORQCOMのs+cameraを試してみました

SORACOMのs+cameraを試してみました.
SORACOMのs+cameraとは、電源をつなぐだけで通信するエッジAIカメラです。
SORACOM Airのセルラー通信を搭載しており、遠隔からAIアルゴリズム書き換えが可能なエッジ処理カメラです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/c5fdc3a9-5f5b-5298-b32a-1ac634566174.png)


もう少しわかりやすいように調べたところ、
ラズベリーパイベースで通信モジュール、SIMカード、カメラ、電源を一体化して、電源を入れるだけで通信も含めて稼働します。
エッジデバイスの管理ツールであるsoracom mosaicによって運用管理されます。
カメラのアルゴリズムに関しても、soracom mosaicによって遠隔管理されます。
画像処理のアルゴリズムに関しては、SORACOMから提供されるリファレンスアルゴリズム、自社で独自に開発する自社開発アルゴリズム、パートナーから提供されるサードパーティアルゴリズムの中から選択することができます。

実際に購入しなくてもトライアル機能を利用して試すこともできますので、試してみてもいいかもしれません。
[トライアル機能を利用して S+ Camera Basic を操作する](https://users.soracom.io/ja-jp/docs/mosaic/use-trial/)


実際にs+cameraのサンプルアプリで文字認識をやってみました。
[SORACOM レシピ：IoTカメラで計測機器のデータを可視化したい](https://soracom.jp/recipes_index/3967/)
こちらのページにしたがってSIMの初期設定を行いました。

カメラのアルゴリズムの切り替えもsoracom mosaicを利用することで簡単に行うことができました。
今回はレシピ通りにOCR機能を試してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/06015deb-8773-6cd3-3109-d3c2e6b745df.png)

このように認識はしていますが、デフォルトの状態では制度がいいとは言い難いと感じました。
読み取ったデータは登録してあるSORACOMカウントにJSON形式で保存されていきます。
おそらく画像の取得状態（撮像条件）などにも左右されると考えられます。
ですので実験がしやすいように手持ちのPCで試してみて、そこでフィックスしたものをカメラに適用しようと考えました。
用意されていたサンプルではtesseractというGoogleが開発しているオープンソースの光学式文字認識エンジンが使用されていましたので、この認識エンジンを試してみることにしました。

tesseractをPythonから使用するためにpyocrを使用しました。
今回は手っ取り早く開発環境を用意するためにGCPを利用しました。
GCPの中にtesseractをインストールしてGCPからMacbookの標準カメラを使用して画像の取り込みを行いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/7337d10d-690d-8f42-b895-11c3a273c6c3.png)

一応文字の認識はしていますが、まだ制度が良いとは言えません。

提供されているサンプルアルゴリズムではARucoという、AR向けマーカー認識ライブラリが使用されています。
おそらくARマーカーとopenCVを利用して画像の下処理をしてから文字の認識を行っていると考えられます。


今回は実験では、画像の前処理などを行っていませんので芳しい結果になっていませんが、
OCRを使用する前にopenCVで前処理を行うことで自分が必要とする機能を実装することができるのではないかと考えています。

参考情報
[トライアル機能を利用して S+ Camera Basic を操作する](https://users.soracom.io/ja-jp/docs/mosaic/use-trial/)
[SORACOM レシピ：IoTカメラで計測機器のデータを可視化したい](https://soracom.jp/recipes_index/3967/)
[Google ColabでTesseractOCRを使う方法](https://qiita.com/shoku-pan/items/7a67f484a10430da6678)
[ColaboratoryでTesseract-OCRを動かしてみる](https://qiita.com/m-hayashi/items/e2acc640fb436d09f128)
RedisをソースからインストールしたDockerイメージを作成する

ソースからredisをインストールする方法を記述します。
現在（2021/9/18）redisのdocker公式イメージは5と6です。それよりも古い場合はソースからビルドする必要があります。http://download.redis.io/releases よりバージョンを選択してください。

[redis公式dockerイメージ](https://hub.docker.com/_/redis/)

```dockerfile
FROM debian:bullseye-slim

SHELL ["/bin/bash", "-c"]

RUN apt-get update && apt-get install -y build-essential tcl wget
RUN wget -c http://download.redis.io/releases/redis-4.0.9.tar.gz \
&& tar -xvf redis-3.2.9.tar.gz \
&& cd redis-3.2.9 \
&& make \
&& make install \
&& cd utils \
&& ./install_server.sh

CMD redis-server --appendonly yes
```
Vue.js 基本的なディレクティブ　v-if編

#はじめに
Vue .jsを学習し始めたのでアウトプットしていきます
#v-if
要素の表示・非表示を切り替えをDOMレベルで削除

```html:index.html
<div id="app">
  <p v-if="thank">
  　Thankyou
  </p>
</div>
```

```javascript:app.js
var app = new Vue({
  el: '#app',
  data: {
  	tank: true
  }
})
```

上記のようにデータの真偽値をtrueにすれば画面に「Tankyou」が表示されます

```javascript:app.js
var app = new Vue({
  el: '#app',
  data: {
  	tank: false
  }
})
```
上記のようにデータの真偽値をfalseにすれば画面に何も表示されません。
ここで検証ツールを開いてみると

```
<body>
 <div id="app>
    <!---->
 </div>
```

となっておりp要素はDOMレベルで削除されていることがわかります。

###注意
要素を頻繁に表示/非表示を繰り返す場合描画コストが高くなる恐れがあります。
その場合は、cssにのdisplayプロパティを利用して表示/非表示を切り替える　　v-showディレクティブを利用する。
javascript: filterとmap

#はじめに
これはGASでスプレッドシートを処理する中で理解したことを忘れないための備忘録です

###データ
検証に利用する配列`CurretGradeObject.createObjects()`です。

```json:CurretGradeObject.createObjects()
[
  { memberId: 100234,
    grade: '一般',
    award: '最優秀',
  },
  { memberId: 100567,
    grade: '一般',
    award: '優秀作',
  },
  { memberId: '',
    grade: '',
    award: '',
  }
]
```
#filter
###　書き方
```javascript:
var memberData = CurretGradeObject.createObjects().filter(function(x) {
    return x
})
```
```json:返却値
[
  { memberId: 100234,
    grade: '一般',
    award: '最優秀',
  },
  { memberId: 100567,
    grade: '一般',
    award: '優秀作',
  },
  { memberId: '',
    grade: '',
    award: '',
  }
]
```
`CurretGradeObject.createObjects()`と同じ配列が返ってくるのでfilterの意味がない
`x`をループしてそのまま`x`を返却した配列になる

###空は出力しない

```javascript:
var memberData = CurretGradeObject.createObjects().filter(function(x) {
    return x.memberId
})
```
```json:返却値
[
  { memberId: 100234,
    grade: '一般',
    award: '最優秀',
  },
  { memberId: 100567,
    grade: '一般',
    award: '優秀作',
  }
]
```


###意味
memberIdに値のあるオブジェクトだけを絞り込んだ配列が返却される
スプレッドシート上の空行を除いてデータを取得したい場合に利用する


#map
###書き方
```javascript:
var memberIds = CurretGradeObject.createObjects().map(function(x) {
    return x.memberId
})
```
```json:返却値
[
  100234,
　　　　100567,
]
```
###意味
memberIdだけを抽出する
M5Stack UnitV2 着弾　　（セットアップ）

![UnitV2_3脚-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2042441/2ab7eb19-88ed-01d7-79f5-2448973045c2.png)

# １．はじめに

2021年5月26日に[SWITCHSIENCE](https://www.switch-science.com/catalog/7160/)で販売が開始された[M5StackUnitV2](https://docs.m5stack.com/en/unit/unitv2)が届きました！
M5StackUnitV2は小型ながらLinuxベースのAI認識処理が動くAIカメラです。
在庫は多数あるようで、夜に注文し、2日後の午前中には届くという早さでした。
セットアップと動作確認をしてみたいと思います。

ちなみに画像の三脚は百均のスマホホルダーでデジカメもネジで設置できるタイプがピッタリハマりました。

# ２．開封
![UnitV2_同梱物.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2042441/5bb88758-7fd8-670a-21ea-2fd81089a28e.png)

本体（MicroSDカード付）、USBコード、スタンド、Back Brickの4点のみ。
説明書のような紙も無し、箱に記載のURLも「m5stack.com」のみ。
使い方は自分で調べなさいよ、と、なかなかのマニア向けですね！

# ３．情報源

情報源は以下のあたりがよさそうです。
[公式ドキュメント：m5-doc](https://docs.m5stack.com/en/unit/unitv2)
[公式Twitter：@M5Stack](https://twitter.com/m5stack)
[Qiita UnitV2記事](https://qiita.com/search?q=UnitV2)

# ４．セットアップ

セットアップはこちらを参考にしました
[公式ドキュメント：m5-doc](https://docs.m5stack.com/en/unit/unitv2)
[M5UnitV2のインストールや備忘録](https://qiita.com/airpocket/items/e6f736e539e18a314ae2)

セットアップといってもPCと接続する際のドライバをインストールするだけです。

１．公式サイトの[DriverInstallation](https://docs.m5stack.com/en/unit/unitv2?id=driverinstallation)から「sr9900.inf_amd64.rar」をダウンロード
２．ドライバを解凍する（7zipなどで）
３．M5StackUnitV2とPCをUSBケーブルで接続
　　・ここでUnitV2が起動
　　・ドキュメントには「赤ランプが光る」とあるが、筐体内部の「青ランプ」が光る
　　・起動が完了したら青ランプは消える模様（割とすぐ消えます）
４．PCのデバイスマネージャーを開き、以下のデバイスが表示されていることを確認する
　　ほかのデバイス＞USB 10/100 LAN
５．ドライバのインストール
　　上記デバイスを右クリック＞ドライバーの更新＞コンピュータを参照してドライバーを検索
　　ドライバを解凍したフォルダを指定してインストールする
　　→Corechip SR9900 USB2.0 to Fast Ethernet Adapterとして認識される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2042441/ccde6154-cadb-23a1-be68-e810b26febc0.png)

これでセットアップは完了！

# ５．動作確認

ブラウザで「unitv2.py」（もしくは10.254.239.1）にアクセス
インストール済みで自動起動している画像認識アプリケーションにアクセスできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2042441/722b212d-aa0e-52f7-cd67-57eba1dedf14.png)

デフォルトで「Camera Stream」が選択されているのでカメラ画像が表示されています。

試しに「Online Recognition」を選んでみると、リアルタイムで物体識別をしてくれます。
たまたま映り込んだTVの俳優も「Person」として識別できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2042441/fff6e465-aaab-010a-b2bd-8f48b255277a.png)

JupyterNotebookも動いており、切り替えるとコーデイングが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2042441/730eadf6-cb16-b48a-641f-cb132b1ef23d.png)

SSHでターミナル接続も可能です。
Linuxベースというところでのとっつきやすさがありますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2042441/ac6fe361-ad95-bcca-979d-85d6dadcda2a.png)

# ６．問題点

* ファンはついていますが、画像処理をしているとそれなりに熱を持ってきます。長時間稼働で熱暴走してしまわないか心配です。
    * 初回起動時に色々な画像認識種別を切り替えていたら途中でハングしたようになり切り替わらなくなってしまった。

* 早速動作デモをオンラインMTGで披露しようとしたら、なかなかUnitV2の処理が進まなかった
    * 画像認識アプリの切り替わりが非常に遅い、など
    * USB接続でローカルネットワーク接続をしているようで、オンラインMTGの通信に圧迫されて遅くなったのかもしれない

* シャットダウン方法がUSBケーブルを抜くしかない
    * sudoを使うようにする手順があるようなのでSSH接続してシャットダウンするようにはできそう

* WiFiが使えてAPモードでも使えるはずだが、PCから接続しようとしてもUnitV2のAPは見つからず
    * ネットでも「APモードで使えない」という話が出ている模様

# ７．おわりに

小型でパワフルなAIカメラということで色々応用が広がりそうです。
Linuxベースでのとっつきやすさもいいですね。
うまくWiFiが使えるようになると設置の幅も広がりそうなので今後もいろいろ試してみたいと思います！
長い命名規則に則った Git ブランチを楽に作成して切り替えるコマンド作った

## 作成するコマンド

下記で `<prefix>/<date>/<name>/<work>` ブランチ（例えば `feature/20210918/yamada/create-something`）を作成して、そのブランチに切り替えるコマンド

```
$ gcb <work>
```

## 背景

少々長いブランチ命名規則に則っているプロジェクトがある。例えば下記ブランチ命名規則など。

`<prefix>/<date>/<name>/<work>`

上記ブランチ命名規則に則るブランチの例は下記。

`feature/20210918/yamada/create-something`

素直にこのブランチを作成して切り替えるには、下記の git コマンドを実行する。

```
$ git checkout -b feature/20210918/yamada/create-something
``` 

・・・ちょっと長い。

この長いブランチ名をタイピングすることを避けるために、今回コマンドを作成した。

## ディレクトリ構成

```
~
└──cmd
    └── gcb
```

## 作成手順

ディレクトリ・ファイルを作成する。

```
$ mkdir ~/cmd
$ vim ~/cmd/gcb
```

`gcb` ファイルの中身は下記のようにする（"yamada" や option の部分は適宜変更・追加する）。本来は usage など書くべきだが、面倒なので省略。

```shell:gcb
#!/bin/sh

p=feature
while getopts ":fu" optKey; do
	case $optKey in
		f) p=fixup shift ;;
		u) p=update shift ;;
	esac
done
d=$(date +%Y%m%d)
b=$(printf "%s/%s/yamada/$1" $p $d)
git checkout -b $b

```

権限を変更する。

```
$ chmod 755 ~/cmd/gcb
```

PATH を通す。

```shell:~/.zshrc(or_something)
...
export PATH=$PATH:$HOME/cmd
...
```
完成。

## 使用例

ブランチを作成する日付は 2021年9月18日 とする。

`feature/20210918/yamada/create-something` ブランチを作成して切り替える場合：

```
$ gcb create-something
```

`fixup/20210918/yamada/typo` ブランチを作成して切り替える場合：

```
$ gcb -f typo
```

`update/20210918/yamada/add-btn` ブランチを作成して切り替える場合：

```
$ gcb -u add-btn
```

## 参考

今回作成した `gcb` ファイル内に登場するコードで不明点があれば、下記を参照いただけると解決すると思われます。

* シェルスクリプト

    * [初心者向けシェルスクリプトの基本コマンドの紹介](https://qiita.com/zayarwinttun/items/0dae4cb66d8f4bd2a337)

    * [Bashの便利な構文だがよく忘れてしまうものの備忘録](https://qiita.com/Ping/items/57fd75465dfada76e633)

    * [bash によるオプション解析](https://qiita.com/b4b4r07/items/dcd6be0bb9c9185475bb)

* date コマンド

    * [date コマンド](https://hydrocul.github.io/wiki/commands/date.html)

* printf コマンド

    * [printf - フォーマット形式で文字列を表示する](https://linuxcommand.net/printf/)

以上です。閲覧ありがとうございました！
AR Foundation 3D Object Tracking を試した 2021.9

# 概要

こちらの記事を見て、現在も同じ感じなのか試してみました。

【ARKit】3Dオブジェクトをマーカーにする - おもちゃラボ
https://nn-hokuson.hatenablog.com/entry/2019/06/25/192111

# 環境

mac
Unity 2020.3.15f2
ARfoundation 4.1
iPhoneXS

# 事前調査

AR Foundation 4.1.7 では android は 3D Object tracking に対応していない模様。

![2021-09-05_11h36_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579071/7eec9ada-faac-198b-6be7-fda82dc869aa.png)


# モデルを用意

リアルモデルとARモデルを同じにしたかったので、以下からペーパークラフトデータとモデルデータをいただきました。ありがとうございます。

BlenderでSalesforce アストロくんのペーパークラフトを作る - Qiita
https://qiita.com/atskimura/items/056b4d904dd140589cf3

## コンビニで印刷して組み立て

ファミリーマートでA4光沢紙に印刷。

https://twitter.com/LaboZeroKH/status/1439099688737656834

完成

![IMG_0034.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579071/982ca96c-054d-7b3b-3b73-c11d21babc90.jpeg)

## 特徴点測定

スキャン用のプロジェクトをダウンロード、ビルドしてiPhoneにインストール。

Scanning and Detecting 3D Objects | Apple Developer Documentation
https://developer.apple.com/documentation/arkit/content_anchors/scanning_and_detecting_3d_objects

起動してぐるっと測定

https://twitter.com/LaboZeroKH/status/1439106209487867904

生成された.arobjectファイルをmacに持っていく。

# ARFoundationSampleを改造

- ARFoundationのObjectTrackingを開く
- ReferenceObjectLibraryに.arobjectを登録

![mac_ss_2021-09-05 20.20.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579071/aee513e0-0040-3cb6-ad3a-18cc7e8849dd.png)

![mac_ss_2021-09-05 20.21.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579071/1fa423ab-4d71-7683-b984-dd2df023a5c6.png)

- AR表示する3Dオブジェクトは初期参照されている Large TriAxis を複製してそれにぶらさげたLarge TriAxis Astro として作りprefab化しました。

![mac_ss_2021-09-05 20.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579071/782dd1c8-aa52-64ab-bdb7-0ac8f3ebc58f.png)

- 作成したprefabを設定。

![mac_ss_2021-09-05 20.21.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579071/ee96eafa-6557-2997-9aee-57205e97e2df.png)

- ビルド。iPhoneにインストール

# 結果

無事認識しモデルが表示されました。MarkerBasedよりは固定される印象。

https://twitter.com/LaboZeroKH/status/1439106978790318080

# これはどうやってるんだろう

元記事にあった動画はどうやって実現してるのかわからずじまい。同じことやりたい。

https://twitter.com/tasonco_company/status/1143459292994916352
pyenvでpython環境構築時、PythonPATHが/usr/bin/pythonから切り替わらない時の対処法

<br />

pyenvでのpython3環境構築で、
pyenv globalをしてもpythonのpathが変更されない問題でちょっと詰まったので、
解決手法をメモしておきます。

基本的には[こちらの記事]( https://qiita.com/y-tsutsu/items/54c10e0b2c6b565c887a )を参考に、pyenvのセットアップを行いました。


## 問題点


```pyenv versions```では変更されているのに

```
~ ❯❯❯  pyenv versions
  system
  3.8.12
* 3.9.7 (set by /usr/local/var/pyenv/version)
```



``python --version``で確認したところディフォルトバージョンから変更できていない。
python のpathも変更されていない。

```
~ ❯❯❯  python --version
Python 2.7.16
~ ❯❯❯ which python
/usr/bin/python
```

## 解決方法

```
eval "$(pyenv init -)"
```
を

```
 eval "$(pyenv init --path)"
```
に変更

<br />

[こちらの記事](https://timesaving.hatenablog.com/entry/2021/05/15/150000)を参考にしました。
アップデートで、pyenv のpathの設定が変わったようでした。


※pyenv環境でのmoduleインストールは
普通にpipコマンドで良い



<br />

## 参考記事等  
https://qiita.com/y-tsutsu/items/54c10e0b2c6b565c887a

https://timesaving.hatenablog.com/entry/2021/05/15/150000
環境変数の設定（Mac）

# はじめに
環境変数とは、OS上で設定できる変数。tokenなどのファイルに記述したくない情報を、OSに保存しておくことで機密性が保たれる。pythonの場合, osライブラリを用いることで環境変数を呼び出すことができる。
以下、利用例及び設定方法を説明する。

# 利用例

- tokenを環境変数で設定。ファイルに記述すると、情報が漏洩してしまうので良くない。

# 設定方法

## 一時的なセッションの間、環境変数を有効にしたい場合

仮想環境（pyenvなど）をactivateしてから、ターミナルで以下を実行。

`export "YOUR_TOKEN"="xxxxxx"`

OS全体に環境変数を設定すると、重複の判別が困難になるので、仮想環境ないだけで利用する環境変数を設定する。

なお、**同じ環境変数名に異なる値を入れた場合、上書きされる**。

## 永続的に有効にしたい場合

シェルに応じて、.zshrcファイルや.bashhrcファイルなどを作成して、そこに同様にexport文を記述。

以下のように、シェルスクリプトを実行。

`source .zshrc`

# 設定した環境変数を確認するコマンド

以下のコマンドを入力。

`export -p`

# 設定した環境変数を削除するコマンド

以下のコマンドを入力。

`unset YOUR_TOKEN`

# Pythonで環境変数を取得

```python
import os

token = os.environ["YOUR_TOKEN"]
print(token)
```

# 参考

- [https://qiita.com/soarflat/items/d5015bec37f8a8254380](https://qiita.com/soarflat/items/d5015bec37f8a8254380)
【Flutter】強制アップデートダイアログを表示させる

# はじめに
　アップデートダイアログを表示させなきゃーって思って調べてみると、FirebaseにRemoteConfigを使って表示させる方法ばかり出てきて、いちいちRemoteConfigの値を変更しなきゃいけないのも何だかなーって思っていたところ、使えそうなパッケージを見つけたので、使ってみました。

# 更新履歴
2021.9.18 初回投稿

# 環境
 - Flutter (Channel stable, 2.2.3, on macOS 11.5.2 20G95 darwin-x64, locale
    ja-JP)
 - Android toolchain - develop for Android devices (Android SDK version 31.0.0)
 - Xcode - develop for iOS and macOS
 - Chrome - develop for the web
 - Android Studio (version 2020.3)
 - VS Code (version 1.60.1)

# 参考にしたサイト
特になし


# package
https://pub.dev/packages/new_version/install

# やりたいこと
1. 簡単にアップデートダイアログを表示させる
1. アップデートダイアログをカスタマイズ表示させたい


# 手順
1. パッケージをインストール
2. WidgetをStatfulに変更
3. initStateを実装し、各アプリのバンドルIDを設定する
3. 実装する

# 実装
## 超簡単に実装(但し表示は英語になります)

```sample.dart
void initState() {
    super.initState();

  final newVersion = NewVersion(
      androidId: '<AndroidのアプリケーションID>',
      iOSId: '<iOSアプリのバンドルID>',
      iOSAppStoreCountry: 'JP',//AppStoreの登録している国コード(日本の場合JP)
    );

    newVersion.showAlertIfNecessary(context: context);
  }
```

これだけです。


## ダイアログ内容をカスタマイズ

上記の方法はめちゃくちゃ簡単ですが、英語でしか表示されないので、日本語で表示させたいところです。

### カスタマイズ表示させる

```dart
void initState() {
    super.initState();
    final newVersion = NewVersion(
      androidId: '<AndroidのアプリケーションID>',
      iOSId: '<iOSアプリのバンドルID>',
      iOSAppStoreCountry: 'JP',//AppStoreの登録している国コード(日本の場合JP)
    );
    advancedStatusCheck(newVersion);
  }
  advancedStatusCheck(NewVersion newVersion) async {
    final status = await newVersion.getVersionStatus();
    if (status != null && status.canUpdate) {//アップデートが必要か否かチェック
      String storeVersion = status.storeVersion;
      String releaseNote = status.releaseNotes.toString();
      newVersion.showUpdateDialog(
        context: context,
        versionStatus: status,
        dialogTitle: 'アップデートが必要です。',
        dialogText:
            'Ver.$storeVersionが公開されています。\n最新バージョンにアップデートをお願いします。\n\nバージョンアップ内容は以下の通りです。\n$releaseNote',
        updateButtonText: 'アップデート',
        allowDismissal: false,
      );
    }
  }

```

キャンセルボタンを追加する場合はallowDismissalをtrueにして、dismissButtonTextを追加する。
キャンセル時に何か実行させる場合はdismissActionを追加する。

### キャンセルボタンを追加

```dart
advancedStatusCheck(NewVersion newVersion) async {
    final status = await newVersion.getVersionStatus();
    if (status != null && status.canUpdate) {//アップデートが必要か否かチェック
      String storeVersion = status.storeVersion;
      String releaseNote = status.releaseNotes.toString();
      newVersion.showUpdateDialog(
        context: context,
        versionStatus: status,
        dialogTitle: 'アップデートが必要です。',
        dialogText:
            'Ver.$storeVersionが公開されています。\n最新バージョンにアップデートをお願いします。\n\nバージョンアップ内容は以下の通りです。\n$releaseNote',
        updateButtonText: 'アップデート',
        // allowDismissal: false,
        dismissButtonText: 'あとにする',
        dismissAction: () {
          Navigator.pop(context);
          print('あとであっぷでーとするみたいです');
        }
      );
    }
  }

```

allowDismissalをtrueもしくは外せば、dismissActionを追加せずとも、dismissボタンが表示されます。
allowDismissalをfalseにすると強制的にアップデートさせることが可能です。

以上
【PHP】for文を使って配列に値を格納する

以前作ったポートフォリオアプリの、レコードを作成してDBへ保存する処理。

https://qiita.com/hinako_n/items/d9b7c51972c18556a1e7

このコードをふと見ていると、繰り返しの処理がベタ書きされていて気になりました。
for文を使って短縮できたので、メモしておきます。

##元のコード
一気に複数の値をDBに保存するため、配列に値をまとめてinsertメソッドを使用しています。

**※insertメソッドの注意点**
タイムスタンプがnullとなる、複数代入から保護されていないのでセキュリティ的に危険というデメリットもあります。今回はユーザーからの入力の可能性がないので、insertメソッドを使うこととします。

```php
$players = [
          ["name" => null,
          "room_id" => $room_id,
          "user_id" => 1],
          ["name" => null,
          "room_id" => $room_id,
          "user_id" => 2],
          ["name" => null,
          "room_id" => $room_id,
          "user_id" => 3],
          ["name" => null,
          "room_id" => $room_id,
          "user_id" => 4]
        ];

RoomPlayer::insert($players);
```

##ループ処理（for）を使う
今回の例では4レコードの作成と決まっているので、元のコードでも記述は可能でしたが、件数が増えるほどにループ処理を使う必要性は増します。

```php
$players = [];

for ($i=0; $i<4; $i++){
  $players[] = [
     "name" => null,
     "room_id" => $room_id,
     "user_id" => $i+1
     ];
}

RoomPlayer::insert($players);
```

以上、覚え書きでした(^^)/
【Java】初めてのJavaプログラミング　オブジェクト指向

オブジェクト指向について少しだけ学んだので、簡単なプログラムをアウトプット

```java:Main.java
import player.*;

public class Main {

    public static void main (String [] args){
        System.out.println("プレイヤーの名前を入力してください");
        String pname = new java.util.Scanner(System.in).nextLine();
        
        if (pname != ""){
            Hero h = new Hero(pname);
            h.charge();
        } else {
            Hero h = new Hero();
            h.charge();
        }       
    }
}
```

```java:Hero.java
package player;///①

public class Hero {
    String name;
    int hp;//HP
    int ap;//攻撃力
    
    //コンストラクタ///②
    public Hero(String name){
        this.name = name;
        this.hp = 100;
        this.ap = 5;
    }
    //未入力（オーバーロード）///③
    public Hero(){
        this.name = "サトウ";
        this.hp = 100;
        this.ap = 5;
    }
    
    public void charge(){
        System.out.println(this.name + "は力を溜めた");
        this.ap += 5;
        System.out.println(this.name + "の攻撃力は" + this.ap);
    
    
    };

};
```

<b>Main.javaの処理</b>
①playerパッケージの全ての関数をimport(importしないとFQCNで指定しないと動きません)
②Hero.javaの内容をインスタンス化したものをhインスタンス(名前:pname)とする。
③hインスタンスでHero.javaのcharge関数を実行。

<b>Hero.javaの処理</b>
①パッケージplayerと定義（他のキャラクタを追加する際などに細分化）
②コンストラクタ(Main.java内でインスタンス化されたときに実行する事で意図した初期値に戻す)
③Main.javaで引数pnameが未定義のケースをオーバーロードし、デフォルトネームを"サトウ"とする。
Junit TestTemplate使ってみた

### はじめに

`TestTemplate`を使おうと思った経緯

日付をinputにして、  
outputが日付から算出されているテストがあった。

検証はinputからoutputが期待通り出ているかという点のみだった。

これ、1個のテストメソッドの中に何個も日付のパターン書いていくのスマートじゃなくね？(なんて思ういきった時期もあったのかもしれない…)

調べてみたら、`TestTemplate`ってのが見つかったから使ってみた。

### TestTemplateでなにができる？

>同じテストを異なるコンテキストで実行するための準備処理などを行う。

ここでいう準備処理は、`@BeforeEach` `@AfterEach`のアノテーションの動きのこと。
これをテスト実施前に変更して、異なる前提条件でテストメソッドを実行できるという機能！

### どうやって使うの？

```java:実装クラス
// TestTemplateInvocationContextProvider を実装する
public class TestExtension implements TestTemplateInvocationContextProvider {
    // @TestTemplateを付けたテストメソッドはこのメソッドが実行される
    @Override
	public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
		List<Date> datelist= new ArrayList<Date>();
        // テストしたい日付を追加する 
		List<TestTemplateInvocationContext> invList = new ArrayList<>();
	    // 	設定日付の分処理を追加
        datelist.forEach(target-> invList.add(addInvocation(target)));
		return invList.stream();
	}

    // 
    private static class QiitaTestTemplateInvocationContext implements TestTemplateInvocationContext {
        private final String name;
        private List<Extension> extension;

        /**
         * コンストラクタ
         */
        public QiitaTestTemplateInvocationContext(String name, List<Extension> extension) {
            this.name = name;
            this.extension = extension;
        }

        @Override
        public String getDisplayName(int invocationIndex) {
            return this.name;
        }

        @Override
        public List<Extension> getAdditionalExtensions() {
            return this.extension;
        }
    }
}
```

```java:テストクラス

@ExtendWith({QiitaTestExtension.class})
public class MyTest  {
    @TestTemplate
    public void test1() {
        // 任意のテスト
    }
}
```

上記の実装で`// テストしたい日付を追加する `の箇所で対象日付を追加して
`test1()`を実行すると対象日付の回数分、日付の名称でテストが実行される。


### おわりに

結局、スマートになったかはわからないな…

あんま、使ってそうな人いないし、勉強にはなったからいいか！笑
Rails ajaxでコメント機能などを実装した時にflashメッセージを消す方法

ajaxで実装すると、結構面倒になるのがflashメッセージの表示。
そしてそれ以前にredirect_toも効かないから面倒臭い。

まずredirect_toに関してだが、これは
render :js => "window.location = '/posts/#{@post.id}'"
このように記述することでajaxでも機能させることができる。

そしてflashメッセージの代入はいつも通り上記のリダイレクト処理をするよりも上の行に書いておく。
ここまでで、コメントを空で送信した時にフラッシュメッセージを表示することができる。

しかし問題は、次にコメントを正しく投稿した後もこのflashメッセージが残ってしまうということだ。
これを解決するにはcreate.js.erbで
$('#comment-error-explanation').remove();
を記述することだ。（id属性はflashメッセージの部分に付与しておく）

以上の手順で実装完了。今回はたったこれだけに50分近く戸惑った。
おそらくこの記事はわかりづらいと思うので、コードの部分をコピペしてそのまま検索エンジンにかけてくれれば
他の誰かがもっとわかりやすく解説している記事に当たると思うのでその方法をお勧めする。
ではまた！
Azure AD とは

## 勉強前イメージ

azureってマイクロソフトだっけ・・・
で、マイクロソフトのADと組み合わせて・・・？
オンプレとクラウド的な話？

## 調査

### Azure AD とは

Microsoftのクラウド型のActive Directory(AD)になります。
オンプレADの詳細は [こちら](https://qiita.com/miyuki_samitani/items/29704cf19bc834b42369) を御覧ください
ADはオンプレで利用するのが一般的だったようですが、クラウドサービスが普及され登場したのが AzureADになります。
クラウドサービスのアカウントを一元管理し、ユーザ認証を行う機能になります。
オンプレのように自社でシステムやサーバを構築する必要がなく、
クラウド上でセキュリティの高い認証サーバが構築できます。

### Azure ADの機能

- ID管理

ユーザの基本情報や組織情報など、ユーザに関わるものが設定されています。
人事異動などの権限付与も一括で行うことが出来ます。

- アクセス制限

グループ、ユーザ単位でのアプリケーションの設定ができ、それぞれ権限の付与が出来ます。
部署によってアプリケーションの使用可否などで権限を付与します。

- シングルサインオン

[SaaS](https://qiita.com/miyuki_samitani/items/79f8e848204968314103#saas) のアプリケーションなど使う際にログインの必要がある場合があります。
そのアプリケーションのアカウントの情報とAzureADの情報を紐付けることで、
認証を1回で済ませることができます。

- デバイス管理

Microsoft Intune というサービスとの併用でモバイルデバイスの管理も行えます。

- オンプレADとの連携

オンプレADとAzureADは別なので両方の利用になると管理が増え、大変になります。
オンプレADの情報とAzureADの情報を同期することで同じアカウントで利用することができ、
煩雑な管理をしなくてよくなります。
ちなみに同期は基本的にはオンプレAD → AzureDAになります。

### オンプレとAzureのADの違い

オンプレのADとAzureADは全く別物で、
どちらも同様にアカウントを作成して管理を行います。

- 使用目的が違う

そもそも使用目的が違い、その違いは以下になります。
オンプレAD → オンプレのアカウントや社内リソースの認証を行う
AzureAD → クラウドサービスのアカウント、認証管理

- 認証プロトコルの違い

オンプレAD → 基本社内ネットワークなのでKerberosプロトコルでの認証で、ディレクトリへのアクセスはLDAPを使用
AzureAD → 様々な認証方式に対応していてSAML認証やOAuthなどが使え、ディレクトリへのアクセスはRESTベースのAPIを使用

- デバイスの管理方法

オンプレAD → ポリシーを適応し、まとめて管理
AzureD → Intuneというツールを併用し、両方に登録したデバイスにルールを適応し管理

- 機能追加

オンプレAD → 新機能の際は新たに専用サーバを構築(独自で構築)
AzureAD → 基本クラウド上に存在するサービスを利用するので、AzureADの管理ポータルで機能を有効化

## 勉強後イメージ

今までActiveDirectoryって勉強したのはオンプレだったのか・・・
そして、違いはオンプレかクラウドかの違いでやることは同じだと思ってたけど、そもそも機能とか目的が違うのね。
色々勉強になりました。

## 参考

- [Azure ADとは？主な機能・オンプレミスActive Directoryとの違いをご紹介](https://www.lanscope.jp/tips/12671/)
- [Azure AD（Azure Active Directory）とは？オンプレADとの違いや機能、エディションをわかりやすく解説](https://www.rworks.jp/cloud/azure/azure-column/azure-entry/21653/)
traefikで共通のmiddlewaresを使う

いちいちdocker-composeで一つ一つ指定するのがめんどうなので、どうにかならないかなーと思ってたんだが、すげーわかんなかった。

# traefik middlewares

参考になったサイト
https://github.com/realtarget/traefik2-docker-stack

他のやり方はわからなかったけど、とりあえず`provider:`にファイルとして呼び出す方法でなんとかなった！
設定の共有化できる！！！

### うちの設定

```/etc/traefik/traefik.yml
providers:
  file:
    filename: /etc/traefik/provider_file.yml
```
このファイルを用意して、中身を書く。

```/etc/traefik/provider_file.yml
http:
  middlewares:
    nextcloud-redirectregex:
      redirectRegex:
        regex: "/.well-known/(card|cal)dav"
        replacement: "/remote.php/dav"
        permanent: true

    stsHeader:
      headers:
        stsSeconds: 315360000
        stsIncludeSubdomains: true
        stsPreload: true
        forceSTSHeader: true
        contentTypeNosniff: true
        browserXSSFilter: true

    jpsonic-dsub:
      plugin:
        subfilter:
          filters:
            - regex: subsonic
              replacement: madsonic
          lastModified: true
```
こんな感じ。
もうgithub見ればいいみたいな感じになるけど……まあいいか。
とりあえずミドルウェアは別ファイルでいいかな。
`traefik.yml`に書くにはどうしたらいいかは……わからない。
`docker-compose.yml`には

```docker-compose.yml
label:
  traefik.http.routers.nextcloud.middlewares: stsHeader@file, nextcloud-redirectregex@file
```
みたいに書けばよい。ウィ！
Wordpressの「エディターで予期しないエラーが発生しました」を解決する

#はじめに
Wordpressでは，以下のエラーがよく出るみたいです．
私の場合は，固定ページを設定において，ページ属性の設定項目を開こうとすると
以下のように「エディターで予期しないエラーが発生しました」とエラーが出ます．
![wordpress_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262828/3353d274-f8e9-9c85-1960-6a33a603ba3a.png)
「復旧を試みる」をクリックしても，なにも反応しませんでした．

調べてみると，固定ページにおいて，「公開」もしくは「更新」をすると，
このエラーに陥ることもあるみたいです．
代表的な解決方法としては，ブラウザのキャッシュの消去をすると治るみたいですが，
キャッシュをリフレッシュしても，同じところでコケたので，備忘録として解決方法を残します．

###環境
・Ubuntu : 18.04
・Wordpress : 5.8.1
・php : 7.3.30
・nginx : 1.14.0

#解決方法
/etc/nginx/nginx.conf に以下の3行を追加することによって，
エラーが出なくなりました．

```/etc/nginx/nginx.conf
server{
　　　　　　　　#〜省略〜
　　　　　　　　location ~ ^/wp-json/ {
　　　　　　　　　　   rewrite ^/wp-json/(.*?)$ /?rest_route=/$1 last;
　　　　　　　　}
}
```

追記したら，nginxの再起動を忘れずに．
```sudo /etc/init.d/nginx restart```

####参考
https://github.com/WordPress/gutenberg/issues/19346
awk 実践例集


# 概要

Qiita に投稿した awk の実践例集.

「日本語を使う」「ハッシュ配列」といった処理が必要な場合は、
Python, Ruby などの LL に頼り、awk でクソ粘りすることはしないし、できない.

|コンテンツ|一言|
|:--|:--|
|[【一行野郎】コロン「:」区切りによる最短一致と最長一致の取り出し](https://qiita.com/robozushi10/items/1e56eece082643fb58da)|ワンライナー|
|[/etc/inittabの内容をレベル毎にソートして表示する](https://qiita.com/robozushi10/items/e113510429579fc6b7c0)|中規模プログラム.|
|[ps -ef の結果からユーザ単位でプロセス個数を表示するプログラム](https://qiita.com/robozushi10/items/ff188ffb3c2d0748136a)|中規模プログラム.<br/>個人的には awk で頑張る限界に近い規模である.|
cesiumで「みちびき」の軌道をプロットした。その2

#概要

cesiumで「みちびき」の軌道をプロットした。

#参考にしたページ

https://qiita.com/Ushinji/items/aab1a4380da1c8662ecc

#サンプルコード

```
const viewer = new Cesium.Viewer('cesiumContainer', {
	imageryProvider: new Cesium.TileMapServiceImageryProvider({
		url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"),
	}),
	baseLayerPicker: false, 
	geocoder: false, 
	homeButton: false, 
	infoBox: false,
	navigationHelpButton: false, 
	sceneModePicker: false
});
viewer.scene.globe.enableLighting = true;
const tle = {
   "name": 'mitibiki',
    "first_line": "1 37158U 10045A   11015.18584668 -.00000050  00000-0  10000-3 0   607",
    "second_line": "2 37158 040.9221 193.2641 0749201 270.0188 212.6145 01.00271298  1281"
}
const now = new Date();    
for (var i = 0; i < 24; i++)
{
  now.setHours(now.getHours() + 1);
	var satrec = satellite.twoline2satrec(tle.first_line, tle.second_line);
  var positionAndVelocity = satellite.propagate(satrec, now);
  var gmst = satellite.gstime(now);
  var position = satellite.eciToGeodetic(positionAndVelocity.position, gmst);
  viewer.entities.add({
    position: Cesium.Cartesian3.fromRadians(position.longitude, position.latitude, position.height * 1000),
	  point: { 
	    pixelSize: 5, 
	    color: Cesium.Color.RED 
	  }    
  });    
}
viewer.zoomTo(viewer.entities);




```

# 成果物

https://embed.plnkr.co/plunk/1ckzllYLypmoKd8Qfmlg


以上。
ディジタルデータの表し方　[マルチメディアデータ]

#マルチメディアデータの表現

文字を表現するときにコンピュータは数値を割り当てて表現するが、

<font color="red">画像や音楽はディジタルデータへ変換し、数値化して表現する</font>

####画像データの表現

代表的な表し方は<font color="red">ビットマップ方式</font>で
細かいドットの集まりで表現すること

１ドットにつき１ビットの情報量が必要

画像が６４０×４８０　ドットなら　３０７,２００ドットでできているということ

**さらに**
    ドット１つは何色なのかという情報も必要

白黒は１ドット２（２の１乗）色　　
　　　→つまり１ビット必要

<font color="red">フルカラー</font>は１ドット１６,７７７、２１６（２の２４乗）色　　　
　　　→つまり２４ビット必要

<font color="red">フルカラー</font>の場合の必要データサイズは

![スクリーンショット 2021-09-08 1.06.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/d95eb11b-91fc-757b-830f-fc03df063dc0.png)
である

####音楽データの表現

波形のデータを時間ごとに区切り、周期的に波形データのレベルを
測るため抽出する

![スクリーンショット 2021-09-09 21.58.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/12eae6bd-84da-7bc1-0b65-6a91e43f5d06.png)



要は<font color="red">サンプリング周期ごとに標本を抽出</font>し、それを<font color="red">量子化データによって数値化し
ビットで表す</font>

サンプリング周期が短く、量子化ビット数が多くなると原音に近くなる



ちなみにCDは
サンプリング周波数　　４４.１ kHz
　　　　→４４１００Hzであり、１秒間に４４,１００回標本を得る
量子化ビット数　１６ビット　　　である



>参考書籍
>>きたみりゅうじ　『キタミ式　イラストIT塾　基本情報技術者　令和０３年』 技術評論社 2020年
rails6で、Stripe Connectでプラットフォームでオンライン決済の導入方法

###今回初めて投稿することになったきっかけ
stripeに日本語の情報が少なかったので、少しでも誰かの役に立てばと思いシェアさせていただきます。
間違っている箇所・改良点などあれば教えていただければ幸いです。

###Stripeとは
<details><summary>オンライン決済（今回はクレカ）を提供しているグローバル企業</summary>
インターネット向け決済インフラ
スタートアップから大規模企業まで、あらゆる規模の多数の企業が Stripe ソフトウェアと API を使用して支払いを受け付け、入金し、オンラインでビジネスを管理しています。
Stripe はサンフランシスコとダブリンに本社を置き、ロンドン、パリ、シンガポール、東京などにオフィスを開設しています。
 [Stripe公式サイト（日本語）](https://stripe.com/jp)
</details>

####サポート
日本語のサポートは、メール（24ｈ以内の返信）のみ。現在電話サポートはなし
英語でならチャットサポートがある
※[Stripe公式API](https://stripe.com/docs/api)(英語のみ)

####開発環境
ruby:  2.6.5
rails: 6.0.0
mysql: 5.7
gem: stripe

stripe connectのアカウントタイプ： Express
API通信のため、https環境（thin, ngrokなど)


###Stripe Connectでプラットフォームをつくると何ができるか
アマゾンのように、出店している会社とユーザーとの取引から、簡単にオンライン決済でマージンを取ることができる
（destination_chargeという方法）



####構想
プラットフォーム型のサービス（例：amazon, メルカリ, 楽天, etc...）
イメージは、以下のレンタカーのポータルサイトのような感じ


https://www.expedia.co.jp/Car-Rentals-In-Portal.d55910.Travel-Guide-Cars
プラットフォーム（がいて、各出店者がそこに登録して商品を展開している


####API keyの設定（テスト環境と本番環境で）


####stripe上でのステータス遷移

```ruby:some_model.rb

      # stripe connectアカウント作成(email,nameで)
      stripe_account = Stripe::Account.create({
        type: 'express',
        country: 'JP',
        email: params[:email],
        capabilities: {
          card_payments: {requested: true},
          jcb_payments: {requested: true},
          transfers: {requested: true},
        },
        business_profile: {
          name: params[:stripe_name], # Stripeでの表示名(法人名がわかりやすいか)
        },
      })

      # カード情報をトークンに(stripeが用意しているtestカード情報)
      Stripe::Token.create({
        card: {
        number: '4242424242424242',
        exp_month: 3,
        exp_year: 2022,
        cvc: '314',
        },
      })

      # customer作成
      customer = Stripe::Customer.create({ object: "customer", name: reservation.name })

      # customerにカード情報追加
      Stripe::Customer.create_source(
        customer.id,
        {source: card_token.id },
      )

      # 更新したcustomerを再代入
      customer = Stripe::Customer.retrieve(customer.id)

      # 仮払い作成
      payment_intent = Stripe::PaymentIntent.create({
        payment_method_types: ['card'],
        amount: 1000,
        currency: 'jpy',
        application_fee_amount: 123, # 洗家の手数料
        customer: customer.id,
        payment_method: customer.default_source # card_id
        transfer_data: {
          destination: company.stripe_id,
        },
      })

      # この段階で、paymentIntent.status = requires_confirmation
      Stripe::PaymentIntent.confirm(
        payment_intent.id,
      )

      # この段階で、paymentIntent.status = requires_capture
      Stripe::PaymentIntent.capture(
        payment_intent.id,
      )
```

[github_stripe/stripe-ruby](https://github.com/stripe/stripe-ruby)
【一行野郎】コロン「:」区切りによる最短一致と最長一致の取り出し


## 概要

コマンドラインやシェルスクリプトで稀に必要になる最短マッチと最長マッチ.
特に最短マッチについては使う度に苦戦しているので書き出しておく.
実践例は、sed, awk, cutコマンド, perl である.

なお、私には正規表現を正確に覚える力が無いので、パターンの意味については別途調べてほしい.

### 最短一致

文字列「1A:2B:3C:4D」をコロン「:」区切りにする.
このときの最短一致である「1A」を取り出す場合.

#### sed 

```bash
$ echo "1A:2B:3C:4D" | sed -n -r 's/([^:]+):(.+)/\1/p'
```

#### awk

```bash
$ echo '1A:2B:3C:4DF' | \
    awk '{ $0 = gensub(/[(.+):](.+)+/, "\\\\2", "G", $0); print $0 }'
```

#### cut コマンド

```bash
$ echo '1A:2B:3C:4D' | cut -f1 -d':'
```

#### perl

```bash
$ echo '1A:2B:3C:4D' | perl -pe 's/([^:]+):(.+)/\1/'
```

----


### 最長一致

文字列「1A:2B:3C:4D」をコロン「:」区切りにする.
このときの最長一致である「1A:2B:3C」を取り出す場合.

#### sed 

```bash
$ echo "1A:2B:3C:4D" | sed -n -r 's/(.+):(.+)/\1/p'
```

#### awk

```bash
$ echo '1A:2B:3C:4DF' | \
    awk '{ $0 = gensub(/(.+):(.+)+/, "\\\\1", "G", $0); print $0 }'
```

#### cut コマンド

```bash
$ echo '1A:2B:3C:4D' | cut -f1-3 -d':'
```

#### perl

```bash
$ echo '1A:2B:3C:4D' | perl -pe 's/(.+):(.+)/\1/'
```

以上.
製造業で使われるIT技術の一例(設備トラブル)

#はじめに
私は半導体製造工場出身で長年勤め、IT技術の必要さに気づきIT業界に足を踏み入れました。この記事では、実際に抱える製造業の課題に対してどのような技術があれば改善する事が出来るのか、自分の中の小さな世界で書きたいと思います。

#設備トラブル
生産を日々行っていく中で設備のトラベルは生産性を大きく損ないます。 一度設備が止まることで、生産が止まり、復旧に人の工数がかかり、大きな話では出荷に間に合わない状況になりお客様に迷惑をかけたり、大量な不良品を作り続けたりする事になります。

そのような状況にならないように予防保全として定期点検を行い、消耗しやすい部品の交換を行ったり、稼働時間や加工回数など状態を示すパラメータを取得ししたりします。また、取得したパラメータの値をQC7つ道具で管理したり、解析ソフトを使っていつもと違う状況になっていないかの確認を行います。

- 1、パラメータの取得を自動化する
 - ・設備からすでにアナログ出力されている端子がある場合<br>
    AD変換機を使いアナログ情報をデジタル情報に変換しPCなどに取り込みます。PCに取り込まれたデジタル値をテキストファイルやDBへ保存します。<br><br>

 - 設備からのアナログ出力が無いが、PLCで値を保持している場合<br>
   PLC機器と通信出来るミドルウェアを使いPLCのデータメモリを取得しテキストファイルやDBへ保存します。<br><br>

 - データを1から取得する必要がある場合<br>
   センサーを取り付けテキストファイルやDBへ保存します。 センサーの種類によって構成は変わりますが、センサー自体からアナログ出力されている場合は必要に応じて増幅器を経由しAD変換機へ入力させたり、設備メーカーさんの方でデータをPLCに入れてもらいその情報を取得したりします。 センサーによってはPCからデータを取得するようのライブラリが公開されている物もあります。<br><br>
(必要となるIT技術)<br>
1、プログラミング技術<br>
AD変換機はアナログ側が設備の出力端子、デジタル側がPCに接続されますがPCからデジタル値を取得する技術が必要となります。この部分ソフトウェアとして販売されていたりもしますが汎用性はやはり低いです。個人で開発するためにAD変換機を外部から操作するためのミドルウェアやコンポーネントが無償で提供されていますのでそれを使い開発します。そのため`C#`や`VB.net`などのプログラミングの技術が必要となります。基本的には `コンソールアプリケーション` `Windows Forms` `WPF` `UWP`での開発になると思います。 ※勿論Linuxやラズパイなどを使っても開発可能です。<br><br>
2、GUI開発技術<br>
データの取得が出来ても人が見れなければ意味がありません。人が見やすいように表示するためのGUIの開発技術が必要となります。 この部分は特にどのようなグラフで表示されるか、人が行うチェックをどれだけ簡単にさせるかなど考えると切りが無いですが、システムを使う側の視点からすると一番重要な部分です。基本的には`Windows Forms` `WPF` `UWP` を使ったり、ブラウザで見たい場合は`Asp.net core` `Blazor`などになります。 Webシステムとなると一気に範囲が広ますので一部しか記載しません。個人的な意見としては`Blazor`が一番最適だと考えています。(まだまだ少数派だと思います。) <br><br>
3、データベース技術<br>
取得したデータをテキストファイルに保存する形でも運用によっては良いと思いますが、やはり複数の設備のデータを収集して1か所にまとめ管理したい場合はなどはデータベースの技術は必須です。`SQLServer`や`Oracle`、完全無料としては`Postgres`等があります。<br><br>
4、PLCとの通信技術<br>
PLCのメモリデータを取得するためにPLCとも通信出来る必要があります。 各メーカーでライブラリが販売されていますのでそれを使い通信するのが効率が良いです。(三菱社であればMXコンポーネントなど)　また、PLCメーカー毎にライブラリが異なるのは効率が悪いので各社対応しているライブラリも半版されています。 私はまだ使ったことが無いのですが、これを使った開発を行ってみたいです。(参考: https://www.roboticsware.com/jp/)

- 2、データ取得自体を自動化する
常にデータ取得を行う状態でも良いですが、mS単位でデータを取得する項目が数十項目ある場合とてもすべてのデータの保存は難しいです。そこで必要なデータのみ取得したい場合があります。　そのタイミングを取得するためにPLCと通信し、`とある信号がONの時だけ`や、`とある信号が〇〇以上/以下`の時だけと制御させます。 もし、MESが充実していて設備の稼働状況が分かる環境であればそのデータを使い制御させます。 既存であるものを有効に使うためにどうしても、`自分が知らない分野の知識`が必要となる事も非常に多いと思います。<br><br>
- 3、取得データを解析する
データを取得し、可視化するだけでも新たな気づきが見え改善案が浮かんだりするためとても有効ですが、やはり統計的にも解析する事は大事です。 例えば`多変量解析 MD値管理`はいつもと違う状態になっているかを管理出来ます。<br>
多変量解析のイメージとしてはドリルで穴をあける設備を例にすると個人的には分かりやすいです、管理項目として「押し込み強さ」「回転数」「回転のトルク力」「押し込み速度」「摩耗度」ext.などがありそれぞれ管理値を設け管理されいるとします。 とある日、`全ての項目が正常(管理値内)なのに不良が多発した`という事が発生したとします。 よく見ると、全ての項目が微量ですが上昇していました。 このような`いつもと違う` 状態を検知できるのが`多変量解析 MD値管理`です。<br>
他にも`機械学習`や`深層学習`など様々な解析手法は沢山存在します。<br>
- 4、解析結果をもとに設備を停止させる
リアルタイムでデータを収集しリアルタイムでデータを解析している状況を作ったとしても、異常が発生した際に即時に設備を停止する事が出来なければ不良は発生してしまいます。 この部分は勿論、現場の実情により設備の停止させるタイミングは異なりますが、例えば加工機であれば即時に停止させたい場合が多いと思います。 設備を止めるにはPLCとの通信を行えば可能となりますが、`設備の仕様も十分に熟知している必要`があります。



疲れたので次の記事で続きを記載します。(おそらくはMESだったりERPの部分の記事になります。)色々な技術は必要ですが、勿論全てを一人で行う必要はありません。そのために小さい範囲ではチームがあったり、大きい範囲ではいろんな会社が存在しているのだと思います。
firebase Cloud Functions のコールドスタートを cloud schedule (cron実行) で回避してみる

# 概要

自分が firebase(web) 上に作ったサイトのアクセス数が少なすぎるため、初回アクセスに10秒以上経過し、エラーが表示されてしまうため、一定間隔でサイトを訪問する cron を仕込んだはなし(効果は不明)

# コールドスタートとは

Cloud Functions が実行環境をゼロから構築してアプリケーションを立ち上げること

- [ヒントとアドバイス  |  Firebase](https://firebase.google.com/docs/functions/tips?hl=ja)
- [Cloud Functions for Firebaseのコールドスタート対策を実施した](https://qiita.com/takehilo/items/9ab4a25a02b8328a6d5e)

# 対応策

基本は、チュートリアルの内容を忠実にこなしていくべきで、自分のやり方は対処療法と考えてください

## Cloud Scheduler

もともとは、Heroku の cron、AWS の　EventBridge あたりを漁っていたけど、どれも煩雑な感じがしたので諦めかけていたところ、GCP にはあるのかなと思って探ってみたらやはりありました。

https://cloud.google.com/scheduler

## 設定

かなり簡単に UI 上から構築できます

- Frequency は日本時間の7時から23時の設定例です
- Timezone を日本と同じ UTC+9 のものを選びました
- Target type を HTTP とします
- URL にアクセスしたいサイトのトップページを指定
- HTTP method は GET としました

![console.cloud.google.com_cloudscheduler_jobs_new_folder=&organizationId=&project=test03-20201213.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38174/ca366507-3d35-8ba8-2111-64e78e162459.png)

### 作成すると一覧に表示される

![スクリーンショット 2021-09-18 13.08.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38174/c4c01e88-118f-a20f-ecc4-907703601a66.png)

## Log の View で動作を確認する

こんな感じで実行結果も確認できます

![スクリーンショット 2021-09-18 13.10.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38174/3087b651-febb-ab73-87aa-8b3bd6b65484.png)
スキルマップの見た目をよくしたくなった

GithubのプロフィールやREADMEでちょくちょく見かけるアレを
やってみたくなりました。

### アレってなに？

[shields.io](https://shields.io/)

SVG形式でバッジの作成、取得が可能なサービス。
これでスキルマップとか作るのがどうやら定番のひとつらしいです。

### ではためしに
作ってみました。
↓↓↓↓↓↓
<img src="https://img.shields.io/badge/MacOS-10.15.7-999999.svg?logo=apple&style=flat-square"> <img src="https://img.shields.io/badge/Python-3.8.2-3776AB.svg?logo=python&style=flat-square"> <img src="https://img.shields.io/badge/Django-3.1-092E20.svg?logo=django&style=flat-square"> <img src="https://img.shields.io/badge/Ubuntu-18.04-E95420.svg?logo=ubuntu&style=flat-square"> <img src="https://img.shields.io/badge/VScode-1.60.1-007ACC.svg?logo=visualstudiocode&style=flat-square">

参考：
[shields.ioを使って技術系アイコンを量産した](https://qiita.com/s-yoshiki/items/436bbe1f7160b610b05c)

上記の著者の方によるshields.io用アイコンジェネレーターもあるようです。
[shields.io用アイコンジェネレータを作ってみた](https://tech-blog.s-yoshiki.com/entry/151?referer=https://tech-blog.s-yoshiki.com/entry/150)