OmniAICreator/Qiita-1.07M huggingface dataset:
【Googleタスク】GASでToDoリストを操作してみた

## 概要
いまさらGoogleのToDoリスト（Googleタスク）を利用するようになったので、GASから操作できるのかな？と試してみたら、意外と出来ることが限られていたり、バグ？仕様？のようなものにブチ当たったってお話。

## 参考
[GASリファレンスのTasksAPIの記述](https://developers.google.com/apps-script/advanced/tasks)
[TasksAPIのリファレンスドキュメント](https://developers.google.com/tasks/reference/rest)

## 準備
エディタのサービスの追加でTasks APIを有効にしておく。

## リストの取得
リストを取得するメソッドがこちら
`Tasks.Tasklists.list()`

リストとその情報がJSONで次のように取得できる。

```
{items=[
        {id=リストのID, 
         etag=リソースのETag,
         selfLink=リストのURL, 
         title=タスクのタイトル,
         kind=tasks#taskList,
         updated=最終更新日時}
       ],
 etag=リソースのETag,
 kind=tasks#taskLists}
```

itemsの中の波括弧が一つのリストの情報で、リストが複数あれば波括弧のセットがリストの個数分並ぶ。なので、一つ目のリストのタイトルとIDを取得しようと思ったらこんな感じ。

```javascript
function getList() {
  var taskLists = Tasks.Tasklists.list();
  Logger.log(taskLists.items[0].title);
  Logger.log(taskLists.items[0].id);
}
```

## タスクの取得
リストを取得するメソッドがこちら
`Tasks.Tasks.list(リストのID)`

タスクとその情報がリストの時と同じ感じで取得できる。

リストと比べて情報量が多いので、詳細は上記参考にも書いた[TasksAPIのリファレンスドキュメント](https://developers.google.com/tasks/reference/rest)のREST resource→tasks→Overviewをご参照。

例えば、一つ目のタスクのタイトル、説明、期日を取得しようとするならこんな感じ。

```javascript
function getTask() {
  var tasks = Tasks.Tasks.list('リストのID');
  Logger.log(tasks.items[0].title);
  Logger.log(tasks.items[0].notes);
  Logger.log(tasks.items[0].due);
}
```

期日のタイムスタンプが破棄されるようで、日付しか取得できないのが残念。

## タスクの追加
タスクを追加するメソッドがこちら
`Tasks.Tasks.insert(オプション, リストのID);`

オプションでタイトルや説明を指定できる。
タイトル、説明、期日を指定してタスクを作成するならこんな感じ。

```javascript
function addTask() {
  var task = {
              title: 'タイトル',
              notes: '説明文',
              due: '2022-12-31T00:00:00.000Z'
             }
  var taskListId = 'リストのID';
  task = Tasks.Tasks.insert(task, taskListId);
}
```

取得の時と同様タイムスタンプは破棄されるので、期日は日付のみ指定可能。

## 検討
GASなので他のGoogleサービスと連携させやすい。
特定のメールがあったら、メールの件名をタスクのタイトル、メールへのリンクを説明文にしてタスクを作成するスクリプトを作り、トリガーで毎日作動。とか？

外部のサービスなら、ChatworkやLINEと絡めた使い方も考えられそう。

## バグ？仕様？
有料版Google Workspaceで使えるGoogleチャットの「スペース」に、スペース内で作ったタスクをメンバーに振り分ける機能がある。
この機能で振り分けられたタスクがリスト内にあると、タスクを取得する際にエラーになってしまうみたい。2022年4月現在

スペースから割り振られるリストと、GASで操作するリストは別にしておく必要がありそう。

### おしまい
【C# / Windows】令和対応版のシリアル通信プログラムのヒント集

# 目的

シリアル通信は古くから存在しているため、それを実装するプログラムのサンプルも相応に古い。
10年以上前のコードが引用されていることもしょっちゅうだ。

でもいい加減、（比較的）新しい書き方をしたサンプルがあってもいいと思う。
ヒント集として、自分の断片的な知識をまとめてみた。

対象環境は製造業でよく遭遇する、Windows系+C#とする。

# ヒント集

## とにかくLINQを使おう

例えば入出力をログ出力したい時、チェックサムを計算するために全バイトにXORをとる時、文字列の16進数をバイト列に直したいとき。
各バイトに対して全く同じ処理を行う場合はLINQの使いどきだ。
以下イメージ。

```cs

    public static class ByteArrayExtension
    {
        public static string ToHexFormattedString(this IEnumerable<byte> source)
            => string.Join(" ", source.Select(x => x.ToString("X2")));

        public static byte XorAll(this IEnumerable<byte> source)
            => (byte)source.Aggregate(0, (nextItem, xorResult) => nextItem ^ xorResult);
    }

```

「1バイトを```ToString("X2")```して結果をスペースで区切る」とか、「とにかく全部でXORを取る」とかの「何をするか」のみが書かれていて、
ループ用の変数などの処理には直接は関わらないものが上記コードには含まれないため、意図がわかりやすいはずだ。

このクラスをインポートした上で、例えば```(new byte{1,2,3}).ToHexFormattedString()```のように記述すれば、
```01 02 03```の文字列が帰ってくる。
ついでだから[拡張メソッド](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/extension-methods)を利用して、何をソースにしているかをわかりやすくしておいた。

また、List<byte>やbyte[]を引数に指定しないのは別にこの時点では型を気にする必要がないことと、yieldを使いたいからである。

## バイト列の加工にはyieldを使う

特にデータを送信する場合、例えば「STX(0x02)で始まりETX(0x03)で終わるデータを送信データとしたいため、
ETXが送信データに入ってしまった場合はそのバイトだけ反転してほしい」といった特殊処理が必要になることがたまにある。
その場合、旧来のプログラムの書き方の影響が強い場合、データを送る前に配列をループして確認することが多い。
だがちょっとまってほしい。そのルールは「送信用のバイト列の作成」に合流させられないだろうか。

例えばこのように。

```cs
        private static IEnumerable<byte> CreateSendFrame(IEnumerable<byte> rawDataBytes)
        {
            yield return 0x02;
            byte checkSum = 0x02;
            foreach (var item in rawDataBytes)
            {
                byte next = item != 0x03 ? item : (byte)(item ^ 0xFF);
                checkSum ^= next;
                yield return next;
            }
            yield return checkSum;
            yield return 0x03;
        }
```

配列に対しての操作で対応する場合、その配列自体が読みづらさが増す原因となりやすい。
少しでも考えることを減らそうとしたらこのような関数にいきついた。

また、このような配列にしておけばエスケープバイトの追加などのバイト列の増減への対応も楽になるはずだ。

## 文字列を扱うときもバイト列で受信する選択肢を考える

例えば上記のような特殊な処理が文字列内にも入っている場合や、
メモリのデータを直接読み取ることによって発生する、2バイト単位でバイトが入れ替わっている文字列データなど、
受信したあとに一工夫が必要な文字列をしていることがよくある。
それを[SeralPort.ReadLineメソッド](https://docs.microsoft.com/ja-jp/dotnet/api/system.io.ports.serialport.readline?view=dotnet-plat-ext-6.0)などで読み込んだ場合、エンコーディングできない文字列は[EncoderFallBack](https://docs.microsoft.com/ja-jp/dotnet/api/system.text.encoderfallback?view=net-6.0)の設定により?に置換されてしまう。
このフォールバックの発生は抑えられないため、エンコーディングに適さないバイト列は文字列型にはどうやっても押し込めることができないことに気をつけよう。

自分の周囲ではこれに引っかかっている人が意外に多かった。
（?にたいして変換しようとして失敗している人をよく見かけた）
Error の cause オプションによってエラーの再 throw 時にスタックトレースが失われるのを防ぐ【ES2022】


「エラーをキャッチして再度エラーを投げる」をやる場合、以下のように書くと元のエラー情報が失われてしまうためデバッグしづらいコードになります。

```js
try {
    const user = await fetch(userApiUrl);
} catch (error) {
    throw new Error("ユーザー情報取得APIでエラー");
}
```

メッセージに `error.message` や `error.trace` を連結して入れるのも手ですが、メッセージとしては読みづらく使いづらいです。

よってこれまでは、コード全体のエントリポイントなどでまとめてエラーをキャッチしスタックトレースが失われない形で処理するなどしていたかと思います。



# Error の cause オプション

ES2022 で入った機能で、このように `Error` の第二引数にオプションで `cause` を渡せるようになりました。

```js
throw new Error("エラー", {
    // ここに前のエラーを渡せる
    cause: previousError,
});
```

実際に Chrome DevTools で以下を実行してみると、

```js
try {
    try {
        throw new Error("エラーA");
    } catch (error) {
        throw new Error("エラーB", { cause: error });
    }
} catch (error) {
    console.dir(error);
}
```

エラー B の `cause` にエラー A が入っており、 `stack` も確認できます。
![cause1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/1e63ce10-ba26-ac56-1361-9ca9863ce61b.png)

もちろん、2 個以上の連鎖も可能です。

```js
try {
    try {
        try {
            throw new Error("エラーA");
        } catch (error) {
            throw new Error("エラーB", { cause: error });
        }
    } catch (error) {
        throw new Error("エラーC", { cause: error });
    }
} catch (error) {
    console.dir(error);
}
```
![cause2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/aee39730-408a-445d-c1cf-579c60a77e5b.png)

なお、 `cause` 以外のプロパティ名で渡しても何も渡されません。



## ブラウザの対応状況

この機能は [Chrome 93, Firefox 91 で対応](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error#browser_compatibility) されており、去年の 8 月あたりから使えるようになっています。
Node.js は 16.9.0、 Deno は 1.13 からですね。

また [can-i-use](https://caniuse.com/?search=error%20cause) を見ると、2022/4/24 現在はユーザー全体の 81% は対応したブラウザを使っているようです。
![can-i-use.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54810/b4c305f4-1a2e-bb47-3647-306f12033142.png)

[プロポーザル](https://github.com/tc39/proposal-error-cause)にも記載されているように [Polyfill](https://www.npmjs.com/package/error-cause) もすでにあり、また core-js も [こちらの PR](https://github.com/zloirock/core-js/pull/993) で対応済みです。



# なにが嬉しいか

エラーの再 throw 時にスタックトレースが失われないため、コードの小さい単位でエラーをキャッチしてより詳細なメッセージを投げれるようになり、デバッグなどがやりやすくなるかと思います。

途中で別物の例外に変えることにはなるので、そのまま上位のコードにハンドリングを任せたほうがいい場合もあると思いますが、エラーのハンドリングに関して JS の標準機能で取れる選択肢が増えたということで設計の幅も広がりそうです。



# 余談

少し話は変わりますが、Promise のエラーハンドリングで [await-to-js](https://github.com/scopsy/await-to-js) というのが便利で、Go 言語ライクにエラーハンドリングができます。

このように通信の処理を書くとすると

```js
try {
    const user = await fetchUser();
} catch (error) {
    throw new Error("ユーザー情報取得APIでエラー", { cause: error });
}
```

await-to-js を使うと、エラーを処理する前提で書けるようになります。

```js
const [error, user] = await to(fetchUser());
if (error) {
    throw new Error("ユーザー情報取得APIでエラー", { cause: error });
}
```

通信周りのエラーハンドリングを毎回その場で処理するようになった場合は、ハンドリング処理を書き忘れづらくなるので便利です。
TypeScript にも対応してます。



# さいごに

PHP などを触られている方は Exception にエラー情報を渡せるのですでに馴染みがあるかもしれません。
JS でも同様のことができるようになり、エラーハンドリング周りの設計でまた別の選択肢が取れるようになりました。

Polyfill も用意されているので使ってみてはいかがでしょうか。
minitestでE2Eテストをする

# はじめに

rspecの実装例はたくさんあるのですが、minitestがなかったので備忘録。

# 前提条件

- rails7でrails newした直後の状態を想定
- docker-composeを利用
- capybara + selenium-webdriverの組み合わせ

# Goal

- bin/rails test:systemがエラーなく動作する
- テスト中のブラウザの動きを確認することができる

# 修正箇所

## 1. Gemfileの修正

下記のように `selenium-webdriver` を追加してbundle installしてください。

```ruby:Gemfile
group :test do
  # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
 gem "capybara"
+  gem "selenium-webdriver"
end
```

## 2. application_system_test_case.rbの修正

optionsを追加

```diff:test/ruby:application_system_test_case.rb
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
+  driven_by :selenium, using: :chrome, screen_size: [1400, 1400], options: {
+    browser: :remote,
+    url: ENV['SELENIUM_REMOTE_URL']
  }
end
```

## 3. test_helper.rbの修正

Capybara.server_host 及び Capybara.app_host を追加。
なお、環境変数 `HOSTNAME` はbashの環境変数で特別なことをしていない限りこのままでよいです。

```diff:test/test_helper.rb
ENV["RAILS_ENV"] ||= "test"
require_relative "../config/environment"
require "rails/test_help"
+ Capybara.server_host = "0.0.0.0"
+ Capybara.app_host = "http://#{ENV.fetch("HOSTNAME")}:#{Capybara.server_port}"

class ActiveSupport::TestCase

...
```

### 4. docker-compose.ymlの修正

webコンテナには環境変数 `SELENIUM_REMOTE_URL` をセットします。
また、webdriver_chromeコンテナを追加して、`7900` ポート(VNC用)を開放しておきます。

```diff
version: '3'
services:
  db:
...

  web:
...

+    environment:
+      SELENIUM_REMOTE_URL: http://webdriver_chrome:4444/wd/hub
    ports:
      - "3000:3000"
    depends_on:
      - db
+      - webdriver_chrome
...

+  webdriver_chrome:
+    image: selenium/standalone-chrome
+    ports:
+       - "7900:7900"
...
```

# 実行結果


```bash:
bash-5.1# bin/rails test:system
yarn install v1.22.17
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.19s.
yarn run v1.22.17
$ esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds

  app/assets/builds/application.js      188.1kb
  app/assets/builds/application.js.map  322.4kb

Done in 0.23s.
yarn install v1.22.17
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.18s.
yarn run v1.22.17
$ sass ./app/assets/stylesheets/application.sass.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules
Done in 0.65s.
Running 4 tests in a single process (parallelization threshold is 50)
Run options: --seed 42974

# Running:

Capybara starting Puma...
* Version 5.6.4 , codename: Birdie's Version
* Min threads: 0, max threads: 4
* Listening on http://0.0.0.0:42743
....

Finished in 6.288535s, 0.6361 runs/s, 1.7492 assertions/s.
4 runs, 11 assertions, 0 failures, 0 errors, 0 skips
```

問題ないですね。

動作している途中も確認してみます。

テストが始まる前に `http://localhost:7900` にアクセスすると下記の画面がひょじされますので、接続をクリックしてパスワードに `secret` と入力して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/50d35835-7ac2-746a-fa9d-923dd9116952.png)

下記の画面になれば準備Okです。この状態で `bin/rails test:system` を動かせば確認できると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/42afe272-791d-10b9-3d42-2f095e170d71.png)

なお、余談ですがテストに失敗した結果はデフォルトでは `tmp/screenshots` に出力されます。
STM32G031のI2CスレーブモードでGP2Y0A21YK(赤外線距離センサー)の値をマスターで受信しI2Cに送信


目的
I2Cで距離を測る

![o_con348.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7cdae97b-ff19-df5b-0f89-22cda14c9a4f.jpeg)





https://qiita.com/caa45040/items/105c943b470d230d2cf7



https://qiita.com/caa45040/items/5032e6905c9425f41495








```c++



//I2C_ir_length_0X80_031_1

#include <Arduino.h>
#include <Wire.h>

//STM32G031J6M6 i2cピンの定義
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5

//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)

//初期化
void setup()
{

  //i2cの初期化
  Wire.begin(sdaPin,sclPin); //STM32G031J6M6

} //setup


#define WB Wire.beginTransmission
#define WE Wire.endTransmission

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

  int l;
  unsigned char b = 200;

  //読み込み
  Wire.requestFrom( 8 , 1);
  
  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    b = Wire.read();       // 1バイトを受信
  }//while
  delay(1);

  //レンジ圧縮で140でレンジ切り替え
  if( b <= 139 ) {
    l = b + 60;
  } else {
    l = ((int)(b - 140 + 20)) * 10;
  }  

  // I2Cの0x40(8bit 0x80)に送信
  int o,p,q;  
  o = '0'+ (l - (DIV10(l)*10) ); //   <- l % 10
  l = DIV10(l);                  // l <- l / 10
  p = '0'+ (l - (DIV10(l)*10) ); //   <- l % 10
  q = '0'+DIV10(l);              //   <- l / 10
  if(b>=40) {WB(0x40);Wire.write(q);WE();}
  WB(0x40);Wire.write(p);WE();
  WB(0x40);Wire.write(o);WE();
  WB(0x40);Wire.write('\r');WE();
  WB(0x40);Wire.write('\n');WE();

  //1/100秒の待ち
  delay(10);

} //loop




```
lambdaでEventBridgeなどからJSONで渡された中身をチェックする


下記をセットして、ログ出力されたJSONを見ながら実装する感じ

```python
import logging
import json

logger = logging.getLogger()
logger.setLevel(logging.INFO)


def lambda_handler(event, context):
    logger.info(json.dumps(event))
    return
```
【Anaconda Powershell Prompt】PowerShellのバージョンを変更

## 環境
+ Microsoft Windows 10.0.22000.613（21H2）
+ Windows Terminal 1.12.10983.0
+ PowerShell 7.2.2
+ conda 4.12.0

## はじめに
https://qiita.com/probabilityhill/items/f56c9b2882936c296c0e

PowerShell を「Windows PowerShell 5 -> PowerShell 7」にアップデートしたため、Anaconda Powershell Prompt のリンクを変更する。

## 手順
Anaconda Powershell Prompt を右クリック →「プロパティ」→「ショートカット」のタブを開く →「リンク先」に書かれているものをコピー。

```
%windir%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -NoExit -Command "& 'C:\Users\username\.pyenv\pyenv-win\versions\Anaconda3\shell\condabin\conda-hook.ps1' ; conda activate 'C:\Users\username\.pyenv\pyenv-win\versions\Anaconda3' "
```

`%windir%\System32\WindowsPowerShell\v1.0\powershell.exe` の部分を PowerShell 7 へのパス `"C:\Program Files\PowerShell\7\pwsh.exe"`
 に置き換える。（パスにスペースが含まれているため `""` をつける）

## 確認
Anaconda Powershell Prompt を開き `$PSVersionTable` を実行するとバージョンが確認できる。
【Python + OpenCV】簡易寸法測定(画像に寸法描写)

## はじめに
画像を用いた寸法測定ツール作成は、カメラからの遠近によるサイズミスマッチや精度の問題があって敬遠しておりました。

https://qiita.com/okm_6880/items/0f964484d570208d715d

しかし先日、面白そうな記事を見つけました。

https://protopedia.net/prototype/2928

https://github.com/esc122/opencv_draw_binarize

## ちょっとした改良
2か月前に 1 commitされているのみで、開発が進んでいるのか止まっているのかわかりません。ひとまずfork / git clone し自分でも使ってみて、必要に思った機能を追加しました。詳しい操作方法などはREADME.mdをご覧ください。二値化して面積求めたりする機能もあるようですが、私には必要なさそうなので説明を省略しています(元リポジトリには一切の説明がありません)。

https://github.com/youichi-io/opencv_draw_binarize

#### メイン画面
webcamの画面をスクショして測定するツールらしいです。
![pic1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/99ab7282-513f-8a48-ed32-934203f015d4.jpeg)

#### 実スケール入力(追加した機能)
いわゆるキャリブレーション。基準となる長さが 10 mmのみでは不便に感じ、変更できるようにしました。
![pic2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/710c1f52-06c1-b497-923a-96602a56b90f.jpeg)

#### 簡易測定結果
基準となる長さを適当に取りすぎた(定規から離れているし、斜めになっている)のと、定規より消しゴムの方がカメラに近いため、寸法が多少異なっています。
実寸すると縦横 22x53 mmでした。 
![pic3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/66290faf-3c25-b1a2-cd57-be46f6e623d5.jpeg)
三次元物体を測定するのは避けた方がいいかもしれませんね。きっちり測りたいなら市販されているツールを購入して利用するのが確実です。
ただし、例えば測定する対象をローカルで読み込んだCAD画像にすると、カメラからの遠近によるサイズミスマッチなどの問題は気にする必要がなくなります。また、線分長さの総和を算出できるようにすると応用の幅が広がるかもしれません。

## おわりに
簡易寸法測定ツールの改良についてまとめました。開発中とのことで完成を気長に待ちたいと思います。

## 追伸
protopedia.net の記事を引用しております。参考元の作者様にコメントでコンタクトを取ろうと思って新規登録しようとしましたが、受信確認用のメールが届きません...。ライセンスの関係でまずいことになりそうであれば記事を非公開にします。
Ruby 変数のスコープ レキシカルスコープ

## はじめに
RubyとJavaScriptの違いに手間取ったので備忘録

**JavaScriptのコード**
```js
let sample = "tee"

const hello = () => {
  if(sample === "tee") {
    return "teeです"
  } else {
    return "該当しません"
  }
}

console.log(hello()) //出力結果 "teeです"
```

**Rubyのコード**
```rb
sample = "tee"

def hello
  if sample == "tee"
    return "teeです"
  else
    return "該当しません"
  end
end

puts(hello())

# 出力結果
# undefined local variable or method `sample'
```

`JavaScript`では関数の外側(レキシカルスコープ)の変数を参照可能です。
`Ruby`ではできない。これちょっとひっかりました・・・
初めて学習した言語がJavaScriptだったので、JS基準で考えてしまいます。

## 追記
@kagilinn 様からコメントいただきましたありがとうございます。

```md
先頭が小文字: ローカル変数. 代入されたメソッドの, 代入された場所以降
先頭が大文字: 定数. 代入されて以降, そのクラスに所属して広範囲で読み取れるが, 代入しなおすことができない
先頭が @: インスタンス変数. 実行されたオブジェクトに所属する.
先頭が @@: クラス変数. 実行されたクラスに所属する.
先頭が $: グローバル変数. 代入されて以降どこでも読み書き可能. 但し理由がない限り使わないほうが良い.
```
こうして文字にするとわかりやすいですね。
```js:js
const sample = "hogehoge"

const sampleDef = () => {
  //　関数
}
```
```rb:rb
sample = "hogehoge"

def sample_def
 # 関数（メソッド）
end
```

このように同じ場所(`JavaScript`でいうところのグローバルコンテキスト)で変数を定義したとしても
`JS`はグローバル変数として
`Ruby`はローカル変数として
定義される違いがあるのですね。

勉強になりました!!
Verilogl-HDL選書

# はじめに

Verilog-HDLを記述する時に大変役に立った参考書を挙げる。
この4冊あれば大抵の実装には困らないと思う。

+ [改訂新版　ディジタル回路とVerilog HDL](http://gihyo.jp/book/2008/978-4-7741-3357-7)

基本的にデジタル回路に関して全くの初心者向に記述されている。
前半は論理回路の基礎だが後半には動作周波数限界の説明、n進同期カウンタやゲーティドクロックが駄目な理由とか、他の入門書には無い解説もある。

+ [改訂新版 わかるVerilog HDL入門](http://www.cqpub.co.jp/hanbai/books/37/37561.htm) 

これも基本入門書なのだが、論理回路は知っている人向け。
あと、特記事項としては他の解説本(特に入門書)では殆ど解説されていないtask文の解説がある。
ステートマシンの実装にも触れており、後半はXILINX社のCPLD(XC95108)でTVゲーム(テニスゲーム)の実装を解説している。

+ [Verilog‐HDLによる論理合成の基礎合成に向いたコーディングを考える](http://www.amazon.co.jp/Verilog%E2%80%90HDL%E3%81%AB%E3%82%88%E3%82%8B%E8%AB%96%E7%90%86%E5%90%88%E6%88%90%E3%81%AE%E5%9F%BA%E7%A4%8E%E2%80%95%E5%90%88%E6%88%90%E3%81%AB%E5%90%91%E3%81%84%E3%81%9F%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%92%E8%80%83%E3%81%88%E3%82%8B-%E6%9E%9D-%E5%9D%87/dp/4924998591)
 
実践向の本。回路合成に適した記述方法の解説本。
トップレヴェルモジュールですべきこと、ゲーティドクロックが駄目な理由、クロックやリセットの記述などを通じて最適化や高速に動かすため実装方法が解説されている。

+  [DESIGN WAVE MAGAZINE 2002年11月号](http://www.cqpub.co.jp/dwm/contents/dwm0060i.htm)

書籍ではなく雑誌なのだが「特集1 Verilog HDLによるASIC/FPGA設計テクニック」にてASIC/FPGAにて多用される双方向バスやMPX(マルチプレクサ)、アドレスデコーダの具体的な実装方法など非常に詳しく解説されている。
cppのunordered_mapのkeyにpairを使う方法

## 概要

cppのunordered_mapのkeyはhashメソッドが内包されている必要がある。

pairにはhashが定義されていないので、独自のhashメソッドを作成して利用する必要がある。

簡易実装として、文字列に変換してstd::hashに用意されているstring methodを使用した。

`      string res = to_string(p.first) + "^^^" + to_string(p.second);
`については、uniqueを保証する必要があるため適当な文字列を入れている。

```
struct HashPair {
    //注意 constがいる
    template<class T1, class T2>
    size_t operator()(const pair<T1, T2> &p) const {
      string res = to_string(p.first) + "^^^" + to_string(p.second);
      return hash<string>()(res);
    }
};
```
Bigqueryで一時テーブルを作って分析するTips

Bigqueryで大きなデータを扱って分析をする時、何度もクエリを打つとお金がかかってしまうので一時テーブルを作って置きたくなることがよくあります。
しかし、一時テーブルを作るクエリを別で書くと、クエリの視認性が悪くなります。
また、一時テーブルは不要になったら削除したい。

そんな時使えるクエリです。

`CREATE TABLE IF NOT EXISTS` をつかってすでに作成済みの場合はスキャンしないようにします。
`CREATE TABLE`は`AS`を利用すると直接クエリの中身をINSERTできます。
`expiration_timestamp`を活用してテーブルの有効期限を設定します。

``` SQL
CREATE TABLE IF NOT EXISTS
toaru-data.tmp_id_401to420
OPTIONS(
   expiration_timestamp=TIMESTAMP(DATE_ADD(CURRENT_DATE(), INTERVAL 2 WEEK))
)
AS
    SELECT
    i.app_user_id,
    FROM `koukoku_log.ad_log` a
    LEFT JOIN `koudou.user_view` i ON a.user_id = i.user_id
    WHERE partition_datetime BETWEEN '2022-04-01' AND '2022-04-20'
    AND koukoku_log.ad_id='hoge'

;

SELECT * FROM `toaru-data.tmp_id_401to420`
```
[Rails] 謎のundefined methodの原因はvalidateの単複ミスだった

```ruby
class User < ApplicationRecord
  validates :validate_method

  def self.testmethod(url)
    User.find_by("url like ?", "%#{URI.parse(url).host}%").present?
  end

  private
    def validate_method
      略
    end
end
```

定義したはずのtestmethodが呼び出せない。

```
irb(main):002:0> User.testmethod('http://test.com')
Traceback (most recent call last):
        2: from (irb):2
        1: from (irb):2:in `rescue in irb_binding'
NoMethodError (undefined method `testmethod' for User (call 'User.connection' to establish a connection):Class)
```

試しにメソッドを単純化してみたところ、エラーが変わり、原因が特定できた。
```ruby
  def self.testmethod
    true
  end
```

```
irb(main):001:0> User.testmethod
Traceback (most recent call last):
        3: from (irb):1
        2: from app/models/user.rb:1:in `<top (required)>'
        1: from app/models/user.rb:4:in `<class:User>'
ArgumentError (You need to supply at least one validation)
```

一つだけバリデーションメソッドを入れているところが、validateではなくvalidatesになっていることによる不具合だった。
下記の修正でself.testmethod(url)も呼び出せた。

誤
```ruby
  validates :validate_method
```

正
```ruby
  validate :validate_method
```

Railsは単数/複数の調整をいい感じにやってくれる分、設定ミスを起こすとエラーになりがちですね。
goのgenericsチュートリアルを試してみる

## 使用環境

- Macbook Pro 16inch (Intel)
- Goland IDE

## 準備

1. go 1.18.1を[こちらから](https://go.dev/doc/install)インストール
1. Goland IDEのプロジェクトの言語バージョンを1.18に設定（GOROOTとGOPATH両方を設定しました、正しいかはわかりません）
1. go.modも1.18のものを生成する

Goland IDEを2022バージョンにしないと赤い波線のエラー表示が出ますが、コードは普通に動きます。

## 実際のコード

こちらは[tutorial](https://go.dev/doc/tutorial/generics)ページから取得したものです。

```main.go
package main

import "fmt"

func SumInts(m map[string]int64) int64 {
	var s int64
	for _, v := range m {
		s += v
	}
	return s
}

func SumFloats(m map[string]float64) float64 {
	var s float64
	for _, v := range m {
		s += v
	}
	return s
}

func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
	var s V
	for _, v := range m {
		s += v
	}
	return s
}

func main() {
	ints := map[string]int64{
		"first": 34,
		"second": 12,
	}
	floats := map[string]float64{
		"first": 35.98,
		"second": 12.11,
	}

	fmt.Printf("Non-generic sums %v and %v\n", SumInts(ints), SumFloats(floats))
	fmt.Printf("Generic sums: %v and %v\n", SumIntsOrFloats[string, int64](ints), SumIntsOrFloats[string, float64](floats))
}

```

`go.mod`も1.18に向くように設定しています。

```go.mod
module example/generics

go 1.18

```


## Runした結果

```
Non-generic sums 46 and 48.089999999999996
Generic sums: 46 and 48.089999999999996
```
【AWS】CloudShell環境にアップロードしたファイルを見たらアクセス拒否されて焦った件を綴る

## 背景
AWSのマネジメントコンソール内にあるCloudShell環境でシェルスクリプトとその設定ファイルを動作確認したかったので、アップロードしました。
アップロードは成功したのですが、設定ファイルを編集とcatをしてみたらアクセス拒否された。

## 原因をいくつか上げてみた
事象が発生したときは焦ったので原因をいくつか上げてみた。
・ログインしているIAMユーザにCloudShell操作権限が入っていないか
　→AdministratorAccess権限ついているので問題ない
・ファイルにアクセス権限が含まれていないか
　→同時にアップロードしたファイルの権限に差異はなかったので問題ないと思った

## 結論を書いてみた
アップロードしたファイルのサイズが０バイトでした。
どうやら、空のファイルをアップロードすると、書き込まれるみたい（AWS内部で動作してるAPIが影響しているのでは？）
なので、普通に書き込まれたテキストは削除ができたし、シェルスクリプトも実行できた。

## 参考
```
[cloudshell-user@ip-10-0-73-113 ~]$ cat RestoreEc2.conf 
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>R8HHD1CJACXJ84Q4</RequestId><HostId>5ozsosgQzReHNkh1W2IixVl8a+PdDum4H9XKqBHjDNNtBqVOKtJArxyhYwOTIHzuNckESvNBZ6w=</HostId></Error>[cloudshell-user@ip-10-0-73-113 ~]$ 
```
ubuntuでシェルスクリプトを使って.gitが存在するディレクトリのリポジトリURLを取得する

ubuntuでシェルスクリプトを使って.gitが存在するディレクトリのリポジトリURLを取得する

以下でOKのはず

```sh:test.sh
#!/bin/bash                                                                                                                                          

GIT_DIRECTORY=`find . -name .git`
RESULT_ARR=()
for dir in ${GIT_DIRECTORY}
do
    echo "--- directory"
    echo ${dir}
    echo "--- "
    pushd ${dir}
    REPOSITORY_URL=`git remote -v | grep fetch | cut -f2 | cut -d' ' -f1`
    popd
    STR="${dir}@${REPOSITORY_URL}"    # 区切り文字を仮で@にしている事に注意                                                                          
    RESULT_ARR+=("${STR}")
done

echo "--- result"
for i in ${RESULT_ARR[@]}
do
    echo ${i}
done
```

テスト

```sh
$ bash test.sh
./http/icecream/.git@https://github.com/seigot/icecream
# 区切り文字を仮で@にしている事に注意                                   
```
Bootable USB macOS Installer

macOSシステムをセットアップするためのオフラインインストーラーがあると便利な場合があるので、macOSインストーラーで起動可能なUSBメモリを用意したいだ。[Apple Support](https://support.apple.com/en-us/HT201372)に詳しく記載されているが、参考の為にこのブログにも手順をメモする。

###  準備

まず、macOS Monterey 12.3.1の場合、少なくとも16 GBの容量であるUSBメモリを挿入します。次にアップルストアからmacOSの適切なバージョン（Monterey、Big Surなど）をダウンロードして、インストーラーは/Applicationsに保存される。

### USBメディアの作成

ターミナルアプリを起動して、挿入されたUSBメモリを対象として、インストーラのcreateinstallmediaというツールを実行する。

```user@mac-mini ~ % sudo /Applications/Install\ macOS\ Monterey.app/Contents/Resources/createinstallmedia --volume /Volumes/macOS\ Installer
Password:
Ready to start.
To continue we need to erase the volume at /Volumes/macOS Installer.
If you wish to continue type (Y) then press return: Y
Erasing disk: 0%... 10%... 20%... 30%... 100%
Making disk bootable...
Copying to disk: 0%... 10%... 20%... 30%... 40%... 50%... 60%... 70%... 80%... 90%... 100%
Install media now available at "/Volumes/Install macOS Monterey"
```
作成が完了したら"Install macOS Monterey"と言うボリュームになる。

### インストールする

システムを再起動して、ブート選択画面が出るまで「Option＋ ⌥」キーを押し続き、選択画面で"Install macOS Monterey"と言うボリュームを選択する。
"要素をシャッフル"を検証する

# はじめに
勉強のためであっても, シャッフル関数のようなSTLや標準ライブラリにありそうな関数を自作する場合, テスト・検証もセットで行うことをお勧めします.

# 自作シャッフル
次の方法はわずかながらに偏ることが知られています.

```cpp
void myshuffle(std::array<int32_t, 5>& items)
{
    std::random_device device;
    std::mt19937 engine(device());
    for(size_t i=0; i<items.size(); ++i){
        size_t r = engine()%items.size();
        std::swap(items[i], items[r]);
    }
}
```

# テスト
パターンのカウントが無理矢理ですが, これで検証できるかと思います.

```cpp
#include <random>
#include <cstdint>
#include <array>
#include <functional>
#include <unordered_map>
#include <algorithm>
#include <utility>
#include <iostream>

void myshuffle(std::array<int32_t, 5>& items)
{
    std::random_device device;
    std::mt19937 engine(device());
    for(size_t i=0; i<items.size(); ++i){
        size_t r = engine()%items.size();
        std::swap(items[i], items[r]);
    }
}
void stdshuffle(std::array<int32_t, 5>& items)
{
    std::random_device device;
    std::mt19937 engine(device());
    std::shuffle(items.begin(), items.end(), engine);
}

size_t pattern(std::array<int32_t, 5>& items)
{
    size_t result = 0;
    size_t rank=1;
    for(size_t i=0; i<items.size(); ++i,rank*=10){
        result += rank*items[i];
    }
    return result;
}

void test(const char* name, std::function<void(std::array<int32_t, 5>&)> func)
{
    static constexpr size_t Num = 10000000;
    using count_map = std::unordered_map<size_t, int32_t>;
    count_map count;
    for(size_t i=0; i<Num; ++i){
        std::array<int32_t, 5> items = {0, 1, 2, 3, 4};
        func(items);
        size_t p = pattern(items);
        auto itr = count.find(p);
        if(count.end() != itr){
            itr->second += 1;
        }else{
            count[p] = 0;
        }
    }
    std::cout << name << std::endl;
    std::for_each(count.begin(), count.end(), [](count_map::value_type p){ std::cout << p.second << std::endl;});
}

int main(void)
{
    test("myshuffle", myshuffle);
    test("std::shuffle", stdshuffle);
    return 0;
}
```

# まとめ
STLがない環境やC++のバージョンが古いなど, どうしても自作することもあると思います.
Ciscoルータのポート転送メモ

# はじめに

Ciscoルータ(C1812)でポート転送をする時に色々と実験した時のメモ。
他の人がやっているかも知れないので重複する話があるかと思うけど御愛嬌。

# 前提条件 
検証機器 CISCO1812-J/K9
IOS Version 15.1(4)M12a
基本的なnatの設定は済んでいるものとする。

## 1.無条件で全転送
インターフェースyyyから入って来たパケットを無条件にxx.xx.xx.xxに送る。
```
ip nat inside source static xx.xx.xx.xx interface yyy
```
## 2.特定サーバへポート転送
インターフェースyyyの80番ポートから入って来たパケットをアドレスxx.xx.xx.xxの80番ポートに送る。
```
ip nat inside source static tcp xx.xx.xx.xx 80 interface yyy 80
```

## 3.特定サーバへポート転送し且つICMPを転送先のサーバまで通す。
tracerouteをサーバまで通したい時などで使うかと思う。
```
ip nat inside source static tcp xx.xx.xx.xx 80 interface yyy 80
ip nat inside source static xxx interface yyy
```
ここで重要なのは2行目。
これを設定しないとcisco側のインターフェースyyyでicmpが返されてしまう。(転送先までICMPが行かない)
2行目を設定すると1行目が無効になりそうだけど、どうやら優先順位的には
```
ip nat inside source static tcp xx.xx.xx.xx 80 interface yyy 80
```
が優先されるらしい。(正直よくわからん)
cisco機器には特定のサーバを指定してicmpを通過させる方法が用意されて無いっぽい。
NECのIXシリーズではできるので需要が全く無いわけでは無いと思うんだけどな。

Linux、macos、BSD、ciscoではtracerouteにUDPのポート33434〜33499を使うのでアクセス制御を設定した場合、以下のようにudpを許可しておく。
```
permit udp any any range 33434 33499
```

もし、間違いがあったら教えていただきたい。
AWS Client VPN でセルフサービスポータルを有効化する

# 初めに

この記事は AWS SSO のカスタム SAML 2.0 アプリケーションを用いて、AWS Client VPN でセルフサービスポータルを有効化する手順を書きます。Client VPN の認証は統合認証を使用します。

# AWS SSO の環境構築

AWS SSO のアプリケーションを 2 つ作成します。用途は以下の通りです。

- Client VPN の認証用
- セルフサービスポータル用

Client VPN の認証用の SSO のアプリケーションの構築手順、IAM ID プロバイダの設定方法は以下の記事の「AWS SSO の環境構築」、「IAM ID プロバイダの作成」にそれぞれ記載しています。

https://qiita.com/quryu/items/e2f16cb87c8b83d09e62

続いてセルフサービスポータル用のアプリケーションとその IAM ID プロバイダを作成します。作成方法は Client VPN と 1 点を除いて同様です。異なる点は「アプリケーション ACS URL」に入力する URL です。この URL には以下を入力します。

`https://self-service.clientvpn.amazonaws.com/api/auth/sso/saml`

![53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/f5c5aad7-1edb-2fb6-3acd-d12ed3bbdde2.png)

# クライアント VPN エンドポイントの作成

この手順は以下の記事の「クライアント VPN エンドポイントの作成」と 2 点異なります。

https://qiita.com/quryu/items/e2f16cb87c8b83d09e62

異なる点は以下になります。

- セルフサービス SAML プロバイダー ARN
- 「セルフサービスポータルを有効化する」にチェックを入れる

まず、セルフサービス SAML プロバイダー ARN ですが、セルフサービスポータル用の IAM ID プロバイダを選択します。SAML プロバイダーには Client VPN の認証用の IAM ID プロバイダを選択します。

![54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/97c3e5f7-1e23-19a3-25b1-a625a4224122.png)

「その他のオプションパラメータ」のセクションで、「セルフサービスポータルを有効化する」にチェックを入れます。

![55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/7092464b-f1d9-3cb1-c8fb-99ed460961d6.png)

クライアント VPN エンドポイントを作成後、以下の「セルフサービスポータル URL」をコピーします。

![56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/c9939ee1-88cf-c32a-1a71-2b887f4ce20c.png)

この URL をブラウザで開き、「Download client configuration」をクリックします。

![57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/122fb01f-d754-3ab6-8549-42029f2e00c8.png)

ダウンロードしたクライアント設定ファイルを AWS VPN Client で読み込んで VPN エンドポイントに接続することができます。

# 参考記事

https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/client-authentication.html#federated-authentication

https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-self-service-portal.html
bit全探索動画　コード全文

<iframe width="560" height="315" src="https://www.youtube.com/embed/umfbbrElhaM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

```python:
# 入力の受け取り
N=input()

# Nの桁数
d=len(N)

# 答え
ans=100

# num=(000...0)~(111...1)
for num in range(1<<d):
    # 桁を消して作れる数字
    N_tmp=""
    # 消した個数
    ans_tmp=0
    
    # shift=0~(d-1)
    for shift in range(d):
        # 1 & (numをshift個右シフト)=1ならば
        if 1 & num>>shift == 1:
            # その桁を使う
            N_tmp=N_tmp+N[shift]

        # 1 & (numをshift個右シフト)=0ならば
        else:
            # 桁を消した個数をカウント
            ans_tmp+=1

    # N_tmpが空なら
    # ⇔num=(000...0)の場合
    if N_tmp=="":
        # 次のnumへ
        continue

    # 整数にして3で割り切れる場合
    if int(N_tmp)%3==0:
        # ansよりans_tmpが小さければ更新
        ans=min(ans,ans_tmp)

# 答えが更新されていなければ
if ans==100:
    # 「-1」を出力⇔3の倍数は作れない
    print(-1)
# 答えが更新されていれば
else:
    # 答えを出力
    print(ans)
```
cscの作法 その142

# 概要
cscの作法、調べてみた。
opencvやってみた。
blurやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/80c897db-f994-bb4a-cef9-bbd04970985f.png)

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using OpenCvSharp;

namespace cv
{
	public class Form1 : Form {
		public Button button1;
		public Form1() {
			Text = "blur";
			button1 = new Button();
			button1.Location = new System.Drawing.Point(50, 50);
			button1.Size = new System.Drawing.Size(100, 30);
			button1.Text = "show";
			Controls.Add(button1);
			button1.Click += new EventHandler(button1_Click);
		}
		private void button1_Click(object sender, EventArgs e) {
			Mat src = new Mat("cv.png", ImreadModes.Color);
			Mat dst = new Mat();
			Cv2.Blur(src, dst, new OpenCvSharp.Size(5, 5), new OpenCvSharp.Point(-1,-1), 0);
			Cv2.ImShow("src", src);
			Cv2.ImShow("dst", dst);
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}

```


以上。
Spyder起動エラーの時の初動(Python内での実行によるエラーログ確認)

# Python内でのSpyder実行方法
Python用統合開発環境Spyderが起動しない原因を
突き止めるためのヒントを探る方法の一つとして、
Python内でSpyderをコールすることで、
起動時のエラーログを確認することができる。

起動方法は、以下の2行を実行するだけ。

```python:run_spyder.py
from spyder.app import start
start.main()
```

# エラーログの例
仮想環境にpipでspyderを入れたのだが、spyder.exeを叩いても
起動時のロゴは表示されたと思ったが、その後、サイレントに落ちてしまう状況。
上記のPythonからの実行してみた結果が以下。

```python
(venv2) C:\Users\thash\OneDrive\デスクトップ\test_flask>ipython
Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.32.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from spyder.app import start
   ...: start.main()
fromIccProfile: failed minimal tag size sanity
Could not find QtWebEngineProcess.exe
```

こうして、
「fromIccProfile: failed minimal tag size sanity」
「Could not find QtWebEngineProcess.exe」
の2つのヒントが得られた。
これらを検索にかける等で、解決の手がかりを探していくことができる。
（とはいえ、2022年4月現在、筆者はまだこのエラーを解決できてはいない。。。）

以上
cscの作法 その141

# 概要
cscの作法、調べてみた。
opencvやってみた。
flipやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ff131515-d36f-ddb9-830a-ebcf41bb62cc.png)

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using OpenCvSharp;

namespace cv
{
	public class Form1 : Form {
		public Button button1;
		public Form1() {
			Text = "flip";
			button1 = new Button();
			button1.Location = new System.Drawing.Point(50, 50);
			button1.Size = new System.Drawing.Size(100, 30);
			button1.Text = "show";
			Controls.Add(button1);
			button1.Click += new EventHandler(button1_Click);
		}
		private void button1_Click(object sender, EventArgs e) {
			Mat src = new Mat("cv.png", ImreadModes.Color);
			Mat dst = new Mat();
			Cv2.Flip(src, dst, FlipMode.X);
			Cv2.ImShow("src", src);
			Cv2.ImShow("dst", dst);
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}


```


以上。
【Windows Terminal】バージョン確認

## 環境
+ Microsoft Windows 10.0.22000.613（21H2）
+ PowerShell 7.2.2
+ Windows Terminal 1.12.10983.0

## 目次
+ [1. コマンドから](#1-コマンドから)
+ [2. メニューから](#2-メニューから)

## 1. コマンドから
```posh:PowerShell
wt -v
```

![バージョン情報](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/729e6460-937b-26ac-8f3e-5e23add946ce.png)

## 2. メニューから
ドロップダウンメニューを開き「バージョン情報」をクリック
![ドロップダウンメニュー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/99f90f97-af99-48d2-0952-98e3223f5ca0.png)
![バージョン情報](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/d4cbac07-47b6-fa16-2f5a-78d13fb1e03f.png)

## 参考
https://github.com/microsoft/terminal/issues/5494
cscの作法 その140

# 概要
cscの作法、調べてみた。
opencvやってみた。
cannyやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e0cce602-8457-bac7-c3ee-2a612dd908cc.png)

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using OpenCvSharp;

namespace cv
{
	public class Form1 : Form {
		public Button button1;
		public Form1() {
			Text = "canny";
			button1 = new Button();
			button1.Location = new System.Drawing.Point(50, 50);
			button1.Size = new System.Drawing.Size(100, 30);
			button1.Text = "show";
			Controls.Add(button1);
			button1.Click += new EventHandler(button1_Click);
		}
		private void button1_Click(object sender, EventArgs e) {
			Mat src = new Mat("cv.png", ImreadModes.Color);
			Mat dst = new Mat();
			Cv2.CvtColor(src, src, ColorConversionCodes.RGB2GRAY, 0);
			Cv2.Threshold(src, dst, 0, 255, ThresholdTypes.Otsu);
			Cv2.Canny(dst, dst, 50, 200, 3, true);
			Cv2.ImShow("src", src);
			Cv2.ImShow("dst", dst);
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}


```
以上。
「PythonのSympyを使って中国剰余定理(CRT)を解く」を参考にWolframAlphaとSageMathCell でやってみたい。

オリジナル

https://qiita.com/masa0599/items/2c93189dcc6beee5d8c5

# WolframAlphaで

### 例題 1．

https://www.wolframalpha.com/input?i=ChineseRemainder%5B%7B5%2C2%7D%2C+%7B7%2C11%7D%5D

Result
68

つづく



# SageMathCell で

https://sagecell.sagemath.org/


### 例題 1．

x = crt([5,2],[7,11]); x

68







# 参考

https://qiita.com/mrrclb48z/items/ff978d6cd87e05aa486a
cscの作法 その139

# 概要
cscの作法、調べてみた。
opencvやってみた。
リサイズやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b4f94267-a0e2-5ce6-6386-eaeffe834321.png)

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using OpenCvSharp;

namespace cv
{
	public class Form1 : Form {
		public Button button1;
		public Form1() {
			Text = "resize";
			button1 = new Button();
			button1.Location = new System.Drawing.Point(50, 50);
			button1.Size = new System.Drawing.Size(100, 30);
			button1.Text = "show";
			Controls.Add(button1);
			button1.Click += new EventHandler(button1_Click);
		}
		private void button1_Click(object sender, EventArgs e) {
			Mat src = new Mat("cv.png", ImreadModes.Color);
			Mat dst = new Mat();
			Cv2.Resize(src, dst, new OpenCvSharp.Size(300, 300), 0, 0, InterpolationFlags.Cubic);
			//Cv2.Resize(src, dst, OpenCvSharp.Size.Zero, 1, 0.5, InterpolationFlags.Cubic);
			Cv2.ImShow("src", src);
			Cv2.ImShow("dst", dst);
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}

```

以上。
STM32G031でS-5851温度センサーの値をI2C0x40(8bit 0x80)に送信する。


目的
I2Cのテスト


![o_con347.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/bd81b3ab-bd74-beda-6548-4472046ce824.jpeg)



I2C-USART-USBコンバータ


https://qiita.com/caa45040/items/5032e6905c9425f41495



いろいろ
1か月ぐらい掛けてI2C-USART-USBコンバータを作ったかいがあつたよ!!





```c++



//I2C_5851_0X80_031_1

#include <Arduino.h>
#include <Wire.h>

//STM32G031J6M6 i2cピンの定義
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5

#define S5851A 0x48

//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)

//初期化
void setup()
{

  //i2cの初期化
  Wire.begin(sdaPin,sclPin); //STM32G031J6M6

} //setup


#define WB Wire.beginTransmission
#define WE Wire.endTransmission

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

  //センサーからの読み込み
  int s; //センサーの値

  //0番目のレジスター
  Wire.beginTransmission(S5851A);
  Wire.write(0);
  Wire.endTransmission();
  delay(1);

  //温度の読み込み
  s = 99;
  Wire.requestFrom(S5851A, 1);
  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    s = (int)Wire.read();       // 1バイトを受信
  }//while
  delay(1);
  //s = 123; debug

  // I2Cの0x40(8bit 0x80)に送信
  int o,p,q;  
  o = '0'+ (s - (DIV10(s)*10) );
  s = DIV10(s);
  p = '0'+ (s - (DIV10(s)*10) );
  q = '0'+DIV10(s);
  WB(0x40);Wire.write(q);WE();
  WB(0x40);Wire.write(p);WE();
  WB(0x40);Wire.write(o);WE();
  WB(0x40);Wire.write('\r');WE();
  WB(0x40);Wire.write('\n');WE();

  //1秒の待ち
  delay(1000);

} //loop




```
cscの作法 その138

# 概要
cscの作法、調べてみた。
opencvやってみた。
Thresholdやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/191fc4f3-d5c4-4984-f227-67a355088eb9.png)

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using OpenCvSharp;

namespace cv
{
	public class Form1 : Form {
		public Button button1;
		public Form1() {
			Text = "Threshold";
			button1 = new Button();
			button1.Location = new System.Drawing.Point(50, 50);
			button1.Size = new System.Drawing.Size(100, 30);
			button1.Text = "show";
			Controls.Add(button1);
			button1.Click += new EventHandler(button1_Click);
		}
		private void button1_Click(object sender, EventArgs e) {
			Mat src = new Mat("cv.png", ImreadModes.Color);
			Mat dst = new Mat();
			Cv2.CvtColor(src, src, ColorConversionCodes.RGB2GRAY, 0);
			Cv2.Threshold(src, dst, 0, 255, ThresholdTypes.Otsu);
			Cv2.ImShow("src", src);
			Cv2.ImShow("dst", dst);
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}


```

以上。
cscの作法 その137

# 概要
cscの作法、調べてみた。
opencvやってみた。
グレースケールやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/69ec4d5c-9e9a-a4cc-0cdd-c0654f5f79c7.png)


# サンプルコード

```

using System;
using System.Windows.Forms;
using System.Drawing;
using OpenCvSharp;

namespace cv
{
	public class Form1 : Form {
		public Button button1;
		public Form1() {
			Text = "gray";
			button1 = new Button();
			button1.Location = new System.Drawing.Point(50, 50);
			button1.Size = new System.Drawing.Size(100, 30);
			button1.Text = "show";
			Controls.Add(button1);
			button1.Click += new EventHandler(button1_Click);
		}
		private void button1_Click(object sender, EventArgs e) {
			Mat src = new Mat("cv.png", ImreadModes.Color);
			Mat dst = new Mat();
			Cv2.CvtColor(src, dst, ColorConversionCodes.RGB2GRAY, 0);
			Cv2.ImShow("src", src);
			Cv2.ImShow("dst", dst);
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}


```


以上。
gcloudでインスタンスを作ってすぐに削除する【Google Compute Engine】

```bash
gcloud compute instances create hoge-vm --zone=us-west1-b --scopes=compute-rw --metadata startup-script='#!/bin/bash
NAME=$(curl metadata.google.internal/computeMetadata/v1/instance/name -H "Metadata-Flavor: Google")
ZONE=$(curl metadata.google.internal/computeMetadata/v1/instance/zone -H "Metadata-Flavor: Google" | cut -d/ -f4)
gcloud compute instances delete $NAME --zone=$ZONE --quiet'
```

インスタンスを作成して即削除できます。他に実行したい処理があれば、startup-scriptに書いてください

### `--scopes=compute-rw`がないと権限ないと怒られる
```bash
hoge-vm login: Apr 24 01:23:07 hoge-vm google_metadata_script_runner[481]: startup-script: ERROR: (gcloud.compute.instances.delete) Could not fetch resource:
Apr 24 01:23:07 hoge-vm google_metadata_script_runner[481]: startup-script:  - Request had insufficient authentication scopes.
Apr 24 01:23:07 hoge-vm google_metadata_script_runner[481]: startup-script:
Apr 24 01:23:07 hoge-vm google_metadata_script_runner[481]: startup-script exit status 1
Apr 24 01:23:07 hoge-vm google_metadata_script_runner[481]: Finished running startup scripts.
```

# 参考

https://medium.com/google-cloud/how-to-make-a-self-destructing-vm-on-google-cloud-platform-b99883745b62

https://cloud.google.com/community/tutorials/create-a-self-deleting-virtual-machine
[ARKit]ARSessionを理解をざっくり理解してみる!

# ARSessionとは

ARのシーンがどのように描写されるプロセス(要はライフサイクル）を管理している。
AppleのARSessionは```Visual Inertial Odometry（VIO）```を技術が使用されていて、モーションセンサーで周囲の変化を検知して得たデータとカメラ（```ARCamera```)から取得した動画、画像をコンピュータビジョン解析した結果を組み合わせて実現している。（らしい）

```ARSession```を開始した場合はデータを取るのに時間がかかるので```ARCoachingOverlayView```を表示したりする。(前回の記事を参照）
また、```Delegate```メソッドでセッション状態遷移を検知できる

### ARセッションの主な役割

* デバイスのモーションセンサーから情報を読み込む
* デバイスに内蔵されたカメラを制御する
* ARシーンを生成するためにカメラから得たリアルタイムの映像を分析、処理する
* 実世界にARオブジェクトを実際に配置して描画する



### ライフサイクルの種類

```NotAvaiable```
カメラーやセンサーから情報を収集する前

```Limted(初期化）```
デバイスの位置は認識できているがARKitの機能は使えない状態
Normalに状態が遷移する間に通る

```Limited(機能不十分）```
カメラが塞がれたり、何も映っていない状態になった時にもこうなる。

```Limited(リローカライズ）```
一度セッションが中断された状態から再度Normalの状態に戻る時、中断前のセンサー情報を元に正確にARオブジェクトを表示しようとする処理が走る

```Normal```
ARKitの機能が使える状態


![スクリーンショット 2022-04-23 21.40.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474285/f5a6e5c9-58b5-8a59-d520-907fc484f13a.png)


### 状態を検知するためのDelegateメソッド

```ARSessionDelegate(ARSessionObserverを継承している）```
サブスレッドで呼ばれる

```swift
func session(ARSession, didAdd: [ARAnchor])
// 1つ以上のアンカーがセッションに追加されたことをデリゲートに通知します。
func session(ARSession, didUpdate: [ARAnchor])
// セッションが1つ以上のアンカーのプロパティを調整したことをデリゲートに通知します。
func session(ARSession, didRemove: [ARAnchor])
// 1つ以上のアンカーがセッションから削除されたことをデリゲート
```

```ARSessionObserver```
```ARSessionObserver```はARSessionDelegateが継承しているだけではなく他のProtocolでも継承されている。
全て自動でメインスレッドで呼ばれる。

```swift
トラッキングのクオリティの状態変化周りのDelegateメソッド

func session(ARSession, cameraDidChangeTrackingState: ARCamera)
// カメラでのトラッキングのクオリティの変更を通知
func session(ARSession, didChange: ARGeoTrackingStatus)
// ジオトラッキングの状態変化の通知

セッションの中断周りのメソッド

func sessionWasInterrupted(ARSession)
// セッション中断時
func sessionInterruptionEnded(ARSession)
// セッション再開時
func sessionShouldAttemptRelocalization(ARSession) -> Bool
// セッションが中断されてしまった時に自動でリローカライズするかどうかを判断する

エラー処理
func session(ARSession, didFailWithError: Error)
// ARKit側でセッションエラーが起きた時に呼ばれるメソッド。AlertControllerを呼び出しとけばOK

```




基本的にARKit側でセッションをよしなに管理してくれているが、もし自分で```ARSession```を管理したい場合は下記のプロパティを```false```にする必要がある
(デフォルトは```true```)

``` swift
 var automaticallyConfigureSession: Bool { get set }
```

参考

https://developer.apple.com/jp/documentation/arkit/managing_session_lifecycle_and_tracking_quality/#see-also
cscの作法 その136

# 
概要
cscの作法、調べてみた。
opencvやってみた。
sin波、書いてみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e32537cf-4c3c-347e-5dc2-06829852b94b.png)


# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using OpenCvSharp;

namespace cv
{
	public class Form1 : Form {
		public Button button1;
		public Form1() {
			Text = "sin波";
			button1 = new Button();
			button1.Location = new System.Drawing.Point(50, 50);
			button1.Size = new System.Drawing.Size(100, 30);
			button1.Text = "show";
			Controls.Add(button1);
			button1.Click += new EventHandler(button1_Click);
		}
		private void button1_Click(object sender, EventArgs e) {
			Mat src = new Mat(240, 320, MatType.CV_8UC3, new Scalar(0, 0, 255));
			Mat dst = src.Clone();
			int i;
			int j;
			double angle;
			double d = 0.4;
			for (j = 0; j < 320; j++)
			{
				angle = ((double) j) / 360 * 2 * Math.PI / d;
				i = (int)(100 * Math.Sin(angle) + 120);
				Cv2.Line(dst, new OpenCvSharp.Point(j, i), new OpenCvSharp.Point(j, i + 1), new OpenCvSharp.Scalar(0, 255, 0), 3, 0, 0);
			}
			Cv2.ImShow("src", src);
			Cv2.ImShow("dst", dst);
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}


```

以上。
Flutterの`flutter_test`でwidget testする時に頻出するマッチャーの紹介

## 概要

Flutterの`flutter_test`でwidget testする時に頻出するマッチャーの紹介です。

* 使うシーン
* 使い方
* リファレンス


https://api.flutter.dev/flutter/flutter_test/CommonFinders-class.html

### 1. `find.text()`

#### 使うシーン

表示しているwidgetの中に引数で指定した文字列が存在することを検証する

#### 使い方

```dart
expect(find.text('Back'), findsOneWidget);
```

#### リファレンス

https://api.flutter.dev/flutter/flutter_test/CommonFinders/text.html

### 2. `find.byWidget()`

#### 使うシーン

表示しているwidgetの中に引数で指定したwidgetが存在することを検証する。
例えば`child`を受け取るwidgetを作成した場合に、描画されているwidgetに引数`child`で指定したwidgetが存在することを確認する。

#### 使い方

```dart
const testTarget = Text('test')

await tester.pumpWidget(
  TestParentWidget(
    child: testTarget,
  )
);

expect(find.byWidget(testTarget), findsOneWidget);
```

#### リファレンス

https://api.flutter.dev/flutter/flutter_test/CommonFinders/byWidget.html

### 3. `find.byIcon()`
#### 使うシーン
表示しているwidgetの中に引数で指定した`Icon`widgetが存在することを検証する。

#### 使い方

```dart
await tester.pumpWidget(
  TestWidget()
);

expect(find.byIcon(Icons.mode_edit), findsOneWidget);
```

#### リファレンス

https://api.flutter.dev/flutter/flutter_test/CommonFinders/byIcon.html

### 4. `byType()`
#### 使うシーン
表示しているwidgetの中に引数で指定したtype(class)のwidgetが存在することを検証する。

#### 使い方

```dart
await tester.pumpWidget(
  TestWidget()
);

expect(find.byType(IconButton), findsOneWidget);
```

#### リファレンス

https://api.flutter.dev/flutter/flutter_test/CommonFinders/byType.html

## 環境

* Flutter 2.10.4
* Dart SDK version: 2.16.2
cscの作法 その135

# 概要
cscの作法、調べてみた。
opencvやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ba6ef71a-366b-d981-4a40-eec454ecb821.png)


# コンパイル手順

- opencvsharp3-anycpu.4.0.0.20181129.nupackをダウンロード。
- 拡張子をzipにして解凍。
- OpenCvSharpExtern.dllをコピペ。
- OpenCvSharp.dllをコピペ。
- コンパイル

```
>csc cv1.cs  /reference:OpenCvSharp.dll

```

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using OpenCvSharp;

namespace cv
{
	public class Form1 : Form {
		public Button button1;
		public Form1() {
			Text = "mat";
			button1 = new Button();
			button1.Location = new System.Drawing.Point(50, 50);
			button1.Size = new System.Drawing.Size(100, 30);
			button1.Text = "show";
			Controls.Add(button1);
			button1.Click += new EventHandler(button1_Click);
		}
		private void button1_Click(object sender, EventArgs e) {
			Mat src = new Mat(240, 320, MatType.CV_8UC3, new Scalar(0, 0, 255));
			Cv2.ImShow("src", src);
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
MacでWebRTC開発していて画面共有ができない

<b>Q.何が起きているか</b>
<b>A.画面全体およびWidowの共有ができない</b>
※しかし、Chromeのタブの共有はできる・・・。

<h3>対応内容</h3>
以下のエラーがでている模様。

```
Unable to getDisplayMedia: NotAllowedError: Permission denied by system
```

んー。Chromeのパーミッション付与したけどな・・・。って思ってあまりピンと来ませんでしたが以下の設定が必要でした。

![スクリーンショット 2022-04-24 9.39.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552825/09e56ccd-4757-14d0-491c-411fd71825e4.png)

よくよく考えたら、開発環境にもパーミッションが必要ですね。。。
しょうもないところで時間を浪費してしまったので備忘。
Gitの構造

・Gitの構造

●Gitを構成する3つのエリア
①ワークツリー
=>ファイルを作成、変更するエリア
②ステージ
=>コミットする変更を準備するエリア
③(ローカル、リモート)リポジトリ
=>スナップショット（データ）を記録するエリア

●スナップショットを記録する流れ
①「Git init」でローカルリポジトリを作成
②保存するファイルの作成
③「Git add」コマンドでリポジトリに圧縮ファイル、ステージにインデックスを保存
④「Git commit」コマンドでリポジトリにツリーとコミットを保存
⑤「git remote add origin リモートリポジトリのURL」コマンドでリモートリポジトリを新規作成
⑥「git push (-u) origin master」コマンドでリモートリポジトリへプッシュ
　※初めてプッシュするときは「-u」オプションを付ける