OmniAICreator/Qiita-1.07M huggingface dataset:
2022/12/31主にITとかセキュリティの記事

NEWS pickup＆digest（2022/11/10～12/8）
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/041800011/121900062/

最新LANスイッチの便利機能(12/30)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/122000152/122000001/

年末年始を狙うハッカーに注意　サイバー記事まとめ読み(12/30)
https://www.nikkei.com/article/DGXZQOUC2772F0X21C22A2000000/

SNSのアカウント、乗っ取られないように気をつけること(12/30)
https://ascii.jp/elem/000/004/118/4118718/

複数デバイス間でテキストやファイルを暗号化して安全に送受信できる「CryptBoard.io」を使ってみた(12/30)
https://gigazine.net/news/20221230-cryptboard/

第205回：英国の製造業におけるサイバーセキュリティ対策の実態(12/27)
https://www.risktaisaku.com/articles/-/75512

ECサイトで購入した商品が正規品かどうかを確認する5つの方法(12/30)
https://news.mynavi.jp/techplus/article/20221230-2549690/

2023年のセキュリティ動向、メールを介した攻撃が激化の恐れ(12/29)
https://news.mynavi.jp/techplus/article/20221229-2546755/

みずほや三菱UFJなど銀行を模倣し、日本市場狙う「BlueNoroff」に注意(12/29)
https://news.mynavi.jp/techplus/article/20221229-2548650/

フランス当局、MicrosoftにCookie拒否巡り6000万ユーロの制裁金を科す(12/27)
https://news.mynavi.jp/techplus/article/20221227-2546632/
MACアドレスで打刻システムを作ってみた！

# 目次
* なぜこのシステムを作ったのか
* 使用するツール・環境
* MACアドレスについて
* ソースコード
* Raspberry pi のプログラム自動実行設定
* 使用してみた結果
* 最後に


# 1. なぜこのシステムを作ったのか
出社時の打刻ってめんどくさくないですか？が発端でした。
打刻忘れなどによる、訂正など、とても時間がかかり、非生産的です。


:::note info
**それらの問題を解決するべく、Wifiによる打刻システムを簡易的に作成しました。**
:::





毎時5分起きに、プログラムが作動し、社員さんが持つスマホやPCがWifiに繋がったデバイスを検知し、出勤記録をエクセルに記入します。あらかじめ、社員さんのMACアドレスは控えておくことが必要条件です。








# 2. 使用するツール・環境
今回はRaspberry pi を使って実装しました。
理由として、小型コンピュータで、常に動作させられ、プログラムの自動実行等、汎用性が高いからです。
言語はpythonで、仮想環境を用いて行いました。



# 3. MACアドレスについて
社員のデバイスのMACアドレスを入手しておく必要がありますが、もし、iphoneのMACアドレスを取得する場合、注意する点があります。iOS14からデフォルトでオンになった「MACアドレスのランダム化」により、使うWifiによってMACアドレスが変わってしまいます。そのため、社内で繋がるように設定しているWifiのMACアドレスを取得するようにしましょう。

# 4. ソースコードの解説等

```python
import requests
import subprocess
import sys
import openpyxl
import datetime

employee_1_a = 'a1:47:74:3e:6e:6a'
employee_1_b = 'da:67:66:7b:23:d7'
employee_2_a = '69:93:c6:28:78:ff'
employee_2_b = '6b:a4:eb:2b:8b:15'

#LINE Notifyの送信部分
def send_line_notify(notification_message):
    line_notify_token = ''
    line_notify_api = 'https://notify-api.line.me/api/notify'
    headers = {'Authorization': f'Bearer {line_notify_token}'}
    data = {'message': f'message: {notification_message}'}
    requests.post(line_notify_api, headers = headers, data = data)

#MACアドレスの取得
def check_mac():
    res = subprocess.run(["arp", "-a"], stdout=subprocess.PIPE)
    sys.stdout.buffer.write(res.stdout)
    return res


def main():
    dt_now = datetime.datetime.now()
    mac_address = str(check_mac())
    book = openpyxl.load_workbook('qiita/出勤簿.xlsx')
    sheet = book['出勤簿']
    
    #従業員1のチェック
    if employee_1_a or employee_1_b in mac_address:
        send_line_notify('社員1の出勤を記録しました。')
        sheet.cell(row=dt_now.day + 1, column = 1).value = str(dt_now) + '  出勤'
        book.save('qiita/出勤簿.xlsx')

    #従業員2のチェック
    if employee_2_a or employee_2_b in mac_address:
        send_line_notify('社員2の出勤を記録しました。')
        sheet.cell(row=dt_now.day + 1, column = 2).value = str(dt_now) + '  出勤'
        book.save('qiita/出勤簿.xlsx')

if __name__ == "__main__":
    main()


```


# 5. Raspberry pi のプログラム自動実行設定・方法
上記のプログラムを定期実行してくれるように設定行います。

```shell
$ sudo crontab -e
```
上記のようにcrontabを開きます。

```
*/5 * * * * /usr/bin/python3 /home/qiita/times_tamping.py
```
この記述で、5分置きに定期実行をすることができます。


# 6. 使用してみた結果
実際に半月ほど稼働させてみました。


![スクリーンショット 2022-12-25 23.06.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936739/8566bdfd-b98c-dfa8-5ccf-474abf813b52.png)

上記は、MACアドレスを検知し、社員2の出勤が記録されている様子です。

![スクリーンショット 2022-12-25 23.26.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936739/a995b461-8451-9c55-706f-647b2e635619.png)

上記は、実際にシステムが出勤を9時に検知し、エクセルに記録している様子です。
想像以上に、検知の感度が良く、正しく記録できていました。

# 7. 最後に
記事を読んでくださり、ありがとうございました。
DBに接続したり、フロントに反映させたりすると、もっと面白くなると思いました！
いいなと思ったら、いいねをお願いします！
Google Cloud Certified Professional Cloud Architect 合格体験記

# はじめに
クラウド関連資格で初めて上位資格にあたるものを取得したのでその記録を残します。

# Google Cloud Certified Professional Cloud Architectとは
https://cloud.google.com/certification/guides/professional-cloud-architect?hl=ja

Google Cloudを活用したソリューション、アーキテクチャを設計する能力を認定する資格です。
数多くあるProfessional試験の中では、最も一般的な知識を問われる試験になっています。

# 個人的バックグラウンド
- GCP
  - 2年ほど実務で使用
  - Cloud Digital Leader取得
- その他
    - AWS/Azure/OCIの入門資格保持


# 学習方法
- [Qwiklabs](https://googlecloud.qwiklabs.com/)のコース
    - 会社で提供されていたため受講。平日3時間x5日+休日5時間x3日、正味30時間ほどを費やしました。
- [Udemyの問題集](https://www.udemy.com/course/google-cloud-professional-cloud-architect-i/)
    - 試験対策として受講。各問題セットを5週ずつくらい。

# 試験
- テストセンターにて受検。Pearson VUEではなく場所も別でしたが、身分証の確認等大筋の流れは変わらず。

# 結果&所感
30分ほどで終了。終了後に合格の表示が画面で確認でき、確定のメールは3日ほど後に届きました。
各所で紹介されているように、2022年12月現在では、Udemyの問題集と同一の問題が体感8割を占めていて、問題集を完璧にするだけで合格できてしまいそうでした。
ただ、一部の問題は異なるのは当然のこと、また、本来の目的である、Google Cloudに関する知識を身に着けその認定を受けることを考えると、ハンズオンも含めた学習を踏むことは必要であると個人的には思います。

# 今後
Google Cloudの知識を引き続き深めるためにACEを受けるか、会社でやや推奨されているAWS SAAを受けるか迷っています。
Google Driveに保存した画像を取得する


flutterでUI作成している時につまづいたのでメモ。

## やろうとしたこと

1. GoogleDriveに画像保存
![スクリーンショット 2022-12-31 1.56.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703883/6b1e8a62-87d3-fb9a-c032-992053a9d52a.png)

2. **リンクをコピー**を押してurlを取得
![スクリーンショット 2022-12-31 1.57.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703883/add34022-1e79-8f3a-f554-2b9291e49edd.png)

3. ImageWidgetで取得したリンクの画像を表示

```dart
Image.network({'取得したリンクのurl'})
```

## 発生したエラー

- 画像は表示されず。

![スクリーンショット 2022-12-31 2.07.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703883/c9c03f07-9e5e-a373-65f8-f74c6ee59f6d.png)

- 画像取得時にエラーが出ているよう

```
E/FlutterJNI( 2168): Failed to decode image
E/FlutterJNI( 2168): android.graphics.ImageDecoder$DecodeException: Failed to create image decoder with message 'unimplemented'Input contained an error.
E/FlutterJNI( 2168): 	at android.graphics.ImageDecoder.nCreate(Native Method)
E/FlutterJNI( 2168): 	at android.graphics.ImageDecoder.access$200(ImageDecoder.java:172)
E/FlutterJNI( 2168): 	at android.graphics.ImageDecoder$ByteBufferSource.createImageDecoder(ImageDecoder.java:242)
E/FlutterJNI( 2168): 	at android.graphics.ImageDecoder.decodeBitmapImpl(ImageDecoder.java:1870)
E/FlutterJNI( 2168): 	at android.graphics.ImageDecoder.decodeBitmap(ImageDecoder.java:1863)
E/FlutterJNI( 2168): 	at io.flutter.embedding.engine.FlutterJNI.decodeImage(FlutterJNI.java:524)
```

## 対処方法

上記で取得していたリンクは、あくまで**画像をプレビューするためのURL**らしく、画像自体を取得するには別途URLが必要らしい

以下手順

1. リンクのアクセス権を変更

![スクリーンショット 2022-12-31 2.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703883/24363fb5-82b3-4cb7-c0e1-5844779784fc.png)

2\. URLを以下のように変更する

* before
`https://drive.google.com/file/d/{id}/view?usp=share_link`

* after
`https://drive.google.com/uc?id={id}`

（上記の{id}は共通です）


## 結果

エラーが解消され、画像が表示できました

![スクリーンショット 2022-12-31 2.27.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703883/b40efdb6-2c31-1fd9-06fe-11bb58f15d81.png)
【Snowflake】時間がかかっている実行中クエリを特定してCANCEL文を生成するSQLを作ってみた

## はじめに
トラブルシューティングでSQLを特定して、処理は止めたい場合等はよくあると思います。
こういう時に事前にSQLを事前に準備しておくと便利です。
SQLを作成したので共有します。
そのままでも使えると思いますがお好みにカスタマイズしてご利用ください。

## 特定＆処理停止方法
結論から書きますと、ACCOUNTADMINなどを持つ管理者ユーザで以下のSQLを実行して実行中のSQLを確認し、結果の最後の列「CANCEL_QUERY_TEXT」に表示されるSQLを実行すれば停止できます。

```sql
select SESSION_ID,
       EXECUTION_STATUS,
       USER_NAME,
       ROLE_NAME,
       WAREHOUSE_NAME, 
       WAREHOUSE_SIZE, 
       START_TIME, -- 処理開始時間
       to_char(datediff(hour, START_TIME,current_timestamp)) || ':' ||
           to_char(datediff(minute, START_TIME,current_timestamp) % 60, '00') || ':' ||
           to_char(datediff(second, START_TIME,current_timestamp) % 60, '00')
         as elapsed_time, -- 実行されてからの経過時間
       BYTES_SCANNED,
       DATABASE_NAME AS usage_database,
       SCHEMA_NAME AS usage_schema,
       QUERY_TEXT, -- 実行中のクエリ
       'SELECT SYSTEM$CANCEL_QUERY(''' || QUERY_ID || ''');' as cancel_query_text
from table(INFORMATION_SCHEMA.QUERY_HISTORY()) t
where END_TIME < START_TIME 
      -- 完了前のSESSIONはEND_TIMESTAMPにはUNIX エポックタイムスタンプ
      -- （1970-01-01 00：00：00）が入るためこれで識別する
  and session_id <> current_session() -- 自sessionを除く
order by t.start_time;
```

上記のSQLを実行すると以下のように実行中のクエリ情報が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/19b925c6-808f-feae-0e52-beb98648720e.png)
まずは実行ユーザや実行時間、SQLなどを確認し、停止対象であることを確認しまず。
上の例ではFUKA_USERさんのSQLがMサイズのウェアハウスを18分以上ぶん回していることが確認できます。

最後の列「CANCEL_QUERY_TEXT」に処理停止用のQueryを出力しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/350ca9f7-cb78-86e7-2243-4966774b829b.png)

上記で出力されたキャンセル用クエリをコピペして実行することで処理が停止されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/14311884-64e3-51a5-2e48-93a70de8776e.png)

## 少しだけ解説
実行中のクエリの特定は```INFORMATION_SCHEMA.QUERY_HISTORY()```を使用します。
ソート順は処理開始時間の昇順にしていますので止めるべきものは一番上に出てきます。
SELECT句で表示する項目を絞ってますが、必要に応じてカスタマイズしてください。

参考：
https://docs.snowflake.com/ja/sql-reference/functions/query_history.html

実行中のSQLをCANCELするのは以下です。これを確認用SQLの中で一緒に生成しています。
```sql
SELECT SYSTEM$CANCEL_QUERY('<クエリID>');
```

参考：
https://docs.snowflake.com/ja/sql-reference/functions/system_cancel_query.html
Rust から WebAssembly の memory.init 命令を使いたかった話

（2023-06-28追記: 本記事の[解決編](https://qiita.com/_53a/items/337ec5d61b353b525e0f)を書きました）

## TL;DR
- WebAssembly(Wasm)フォーマットは文字列リテラルなどのデータを保持するために、 `data` セクションという領域を持つことができる
- `data` セクションのうち、 `passive` モードのものはプログラム実行時に `memory.init` 命令でメモリにロードできる
- Rust [^rustc] には LLVM の任意の命令を関数として使用する機能 [^llvm] がある
- LLVM の `wasm` 系バックエンドには、 Wasm の  `memory`  系の命令にそのまま変換される命令がある
- Wasm の `memory.init` にそのまま変換される `llvm.wasm.memory.init` という命令が LLVM IR に存在したが、[こっそり消されてしまった](https://reviews.llvm.org/rG16d83c395a1f8660fc583a66e1927a5c433fbbe1)
- 現状 Rust から `memory.init` 命令を直接叩く手段はないっぽい？

[^llvm]: https://github.com/rust-lang/rust/issues/29602
[^rustc]: 厳密にはRustのデファクトスタンダード実装のrustc

## 背景

Wasmファイルの `data` セクション内のデータを後から書き換えたいようなケースを考えます。

Rust で生成したWasmファイルの場合[^rustc-wasm]、`active` モードの `data` セクションが一つ以上あり、それが実行前にロードされるようになっています。そのため、この `data` セクションを書き換えてやればいいのではと考えますが、これはうまくいきません。

[^rustc-wasm]: Rust に限らず、LLVM の wasm 系ターゲットを使用している処理系ならすべて同じだと思います

なぜなら、この `data` セクションがメモリにロードされたすぐ後ろの領域を LLVM がリンクした関数[^malloc]が使用しており、この `data` セクションの長さが変わってしまうと、この後ろの領域に触ってしまい、実行時に Wasm ファイルがエラー終了するようになってしまうからです。

[^malloc]: 具体的にはメモリ確保系の関数が使用しているようです

## 解決方法

そこで、あらかじめ Wasm ファイルに `passive` モードの `data` セクションを追加しておき、実行中にこの `data` セクションをメモリにロードするようにします。

`passive` モードの `data` セクションをメモリにロードするためには、 
スタックにロード先のメモリアドレス、ロードするデータの `data` セクションでの開始位置、データ長をスタックに積んだ後、 `memory.init` 命令を実行する必要があります。

Rust で Wasm をターゲットにする場合、Wasm 固有の命令の多くは `core::arch::wasm32` 内の関数を通じて使えるようになっていますが、 `memory.init` 命令はこの中に含まれません。

そこで、Rustにある[^nightly] `link_llvm_intrinsics` という feature を使用することを考えます。この feature は、LLVM IR の命令を Rust から関数として呼び出せるようになるものです[^feature]。

[^nightly]: おそらく stable にはありません。もしかしたら nightly 限定かも
[^feature]: `core::arch::wasm32` の各関数も、実装上はこの仕組みを使用しているようです

## 新たな問題

ネットを検索すると、LLVM IR には Wasm の `memory.init` 命令に変換される、  `llvm.wasm.memory.init` という命令があるらしいという資料が[見つかりました](https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/builtins-wasm.c#L31)。

そこで、上記 `link_llvm_intrinsics` を使用して、Rust コード上にこの `llvm.wasm.memory.init` 命令を直接記述することを試みましたが、なぜかうまくいきませんでした。

さらに調査した結果、[このようなコミット](https://reviews.llvm.org/rG16d83c395a1f8660fc583a66e1927a5c433fbbe1) を発見しました。その説明に曰く、

> Also removes unused init/drop intrinsics rather than trying to make them work for 64-bit.

どうやら LLVM の Wasm64 対応時に、使用されていないし対応が面倒だからと、命令ごと消されてしまったようです[^commit]。

[^commit]: コミットメッセージに "Added 64-bit memory.grow/size/copy/fill" としか書いてないのに、別の命令をしれっと削除してるのはなんでなんですかね…

## 終わりに

どうやら Rust （などの Wasm 生成のバックエンドとして LLVM を使用している処理系）から `memory.init` 命令を叩くことはできないようです。

この回避策としては、`memory.init` 命令を使用したい箇所をダミー関数として括りだしておき、後からこのダミー関数に正しい中身を直接注入するのが手っ取り早そうです。
TypeScript で TCP/IP の socket 送信

# はじめに
TypeScriptでsocketを送信するためのコードサンプル。
WebSocketネタは多いけど、こっちのネタがなかったためかき残しメモ。
バッチ処理として動作確認コードとなっているが、バックエンド処理とかに組み込んだら、普通に使えるハズ。

## 実行環境
こちらを参照（追加でパッケージは入れていない）

https://qiita.com/naozo-se/items/0b1f7b0a32d27deec052



※受信側については、pythonのコンテナ環境で確認（以下を参照）

https://qiita.com/naozo-se/items/c1ba06c8c442ef037a78


## コード
```typescript:client.ts
import * as net from "net";

// ネットワーク設定（事前にコンテナ同士のネットワークグループ設定は必要）
const HOST: string = "python-socket_app_1";
const PORT: number = 50000;
// 送信内容
const SEND_DATA = "send message";

// インスタンス生成
const client = new net.Socket();

// 接続処理
client.connect(PORT, HOST, () => {
  console.log("connected: " + HOST + ":" + PORT);
  // メッセージ送信
  client.write(SEND_DATA);
});
// 相手から通信が帰ってきたとき
client.on("data", (data: Buffer) => {
  console.log("Recieve Data: " + data);
  // 接続破棄
  client.destroy();
});
// 破棄したときの処理
client.on("close", () => {
  console.log("Connection closed");
});
// エラー処理
client.on("error", (err: Error) => {
  console.log("Error:", err);
});
```

## 実行
```shell
./node_modules/.bin/ts-node client.ts
```

## おわりに
onってちょっとjQueryな時代を思い出してしまう、、
呼び出すときは、Promiseを使った方がなお良し。
autorun.inf(オートラン機能) とは

## 勉強前イメージ

初めて聞いたし、オートランも初対面

## 調査

### autorun.inf とは

windowsでソフトウェアのDVDやCDをドライブに入れると自動的にインストーラーのプログラムが起動するようになっており
それがインストールを実行するという手順になっていました。
その「自動的にインストーラーが立ち上がってインストールをする」というのがautorun.infによるものです。
これはCDやDVDだけでなく、USBメモリも同様です。

このautorun.infを使って、USBメモリを指すと自動的にウイルスが実行されるようになるというものです。

### autorun.infでの感染の流れ

autorun.infで感染する流れが以下になります。

1. ウイルスに感染しているパソコンにUSBメモリを指す
2. ウイルスがUSBメモリにコピーを作って、同時に自動実行を行うようにする
3. 違うパソコンがUSBメモリをさす
4. autorun.infが起動し、ウイルスが実行されこのパソコンもウイルスに感染

## 勉強後イメージ

よくある、会社のパソコンは大体USBメモリ使えない件はautorun.infがあるからってことなのかな・・・？
それだったら納得。
確かに、CDとか入れたら勝手に起動するよね。。。
初めて知ったわ。

## 参考

- [Windowsの自動実行機能（AutoRun）について](https://www.iestudy.work/entry/2020/08/20/105543)
- [autorun.infとは？感染チェックと駆除方法。デバイスから自動起動させない方法は？](https://cybersecurity-jp.com/security-measures/27258)
docker run hello-world の 'Hello from Docker' を再度表示させたいと思ったあなたへ

dockerのどの参考書にも書いてあるであろう、dockerをインストールしたあとに打つ最初のコマンドとして、

```bash.sh
docker run hello-world
```
がある。

>"hello-world" コンテナは、Docker のチュートリアルとして用意されたサンプルコンテナです。このコンテナは、Docker のインストールや使い方を確認するためのものであり、特に意味のあるアプリケーションを実行しているわけではありません。
by chatGPT

ということで、ここに書く内容は特に意味のあるものではないが、初学者にとっては、「へぇ」ボタンがあれば押したくなる?内容になっていると思われるので、暇があれば読んでみてほしい。


## 1.docker run hello-worldの内容
hello-worldというイメージがローカルになければ、Docker-Hubからダウンロードして、そのイメージからコンテナを作成して、起動している。
そのイメージには、
「Hello from Docker！」
と表示したら、コンテナを停止させるコマンドが入っている。

:::note info
参考書によっては、docker container run hello-world　と書いてあるものあるが、docker run コマンドはその省略形であり、どちらでも使える。startも同様。
バージョンが変わって新たにコマンド編成されたので、省略形のほうが古い。サブコマンドを使って書くようにしたほうがよいだろう。

docker はDockerシステム全体を管理するコマンド、docker container　は、Dockerコンテナを管理するコマンド。
ex)docker image ls
ex)docker container ls
ex)docker container run
docker ls は無い。-> docker ps
 
:::


## 2.Hello form Docker! をもう１度表示したい
最初に実行すると、長い文字が出てきて、なんだかわからないので、もう１回表示したいと思った。

現状、hello-worldコンテナは停止しているので、起動させればいいと思って
```bash
docker start [コンテナ名]
```
と打ってみるが、
コンテナ名が表示されただけで、[Hello form Docker!]は表示されない。

一応
```bash.sh
docker container ls -a
```
で停止しているコンテナも含めて表示するが、Exitedで停止している。

COMMANDという列を発見、このコマンドを打てばいいのか？

調べてみると、このCOMMAND列は、コンテナが実行されるときに実行されるコマンドで、hello-worldのコンテナでは、/hello が実行されている。

```bash.sh
docker container exec [コマンド]
```
を使えば、そのコンテナに対して新たにコマンドを実行することも可能とのこと。

例えば、コンテナ名かIDで指定して、
```bash.sh
docker container exec [コンテナID] ls -la
```
など。

では、もう１度表示するにはどうするか？

結局は、もう１度同じコマンドを打つ。

```bash.sh
docker container run hello-world
```

こうすることで、再度、「Hello from Docker!」が表示された。
しかし、コンテナを確認すると、新たにhello-worldのイメージから作成されたコンテナができている。こちらも停止している。
NAME列に関しては、指定しない限り自動で名前が付けられる。

同じコンテナいらないんだけどな。。。

>Dockerは、指定したイメージがローカルにキャッシュされていない場合は、Docker-Hubからイメージをダウンロードして、ローカルにキャッシュします。
そのため、同じコマンドを再度実行すると、前回実行したときに作成されたhello-worldコンテナを再利用せず、新しいhello-worldコンテナを作成します。

by chatGPT

普段ならコンテナを docker start で再起動させればすむ話だが、hello-worldコンテナはすぐに停止してしまうので、再度表示させたい場合は、同じコマンドを実行するしかない。

## 3.イメージはあるからコンテナ作成から実行したい

docker run は上に書いたように、Docker-Hubからイメージダウンロード、イメージからコンテナ作成、コンテナ起動を行っているので、
最初のイメージダウンロードを省略する方法で行う。

docker runなら１行なので、こちらの方が手っ取り早いが、
参考サイトにあるように、

```bash.sh
docker create --name [コンテナ名] [イメージ名]

docker start -a [コンテナ名]
```

で、「Hello from Docker！」を表示させることができる。

## 4.コンテナを削除する

何度もコマンドを実行していると、同じイメージから複数のコンテナが作成されるので、コンテナを削除する。
イメージを削除する前にコンテナを削除しないとエラーとなる。

```bash.sh
#コンテナを削除
docker container rm [コンテナ名]

#もしくは停止後にコンテナを削除する場合は
docker container run --rm hello-world

#イメージを削除
docker image rm hello-world
```

以上、こんなことを考える人はまれだと思うが、気になった点をまとめました。

>参考
https://zenn.dev/longbridge/articles/2379d09bd4c373
サイバーレジリエンス とは

## 勉強前イメージ

セキュリティのことってことはわかるけど・・・
レジリエンスなに？

## 調査

### サイバーレジリエンス とは

レジリエンスは日本語で回復力などを意味する単語で、
サイバーレジリエンスは、阻止式や企業がサイバー攻撃の脅威にさらされていたり、被害にあっていたりしたとしても
適切な対応を取れること、また被害を最小限にして早急に元の状態に戻す能力を指しています。

基本的には既存のセキュリティ対策としてはサイバー攻撃を検知・隔離・排除が目的です。
しかしサイバーレジリエンスは事業継続性を重視していて、セキュリティを事業継続の脅威として対策を行う考え方になります。
サイバー攻撃を排除することが目的ではなく、事業を継続することを目的としています。

### サイバーレジリエンスを向上させるために

サイバーレジリエンスを向上させるためには以下になります。

- 現状の見直し

現状のサービスや組織のサイバーレジリエンスの状況を確認します。
また、それぞれリスク評価を行って今の状況を整理します。

- 現状のレジリエンスの確認

実際にサイバー攻撃を受けたとして現状のレジリエンスを確認します。
それは攻撃側・防御側に分かれてそれぞれ意見を出し合って今のレジリエンスに関する課題を出します。

- 新しい技術の採用

サイバー攻撃は日々進化を行っています。
対抗する方も旧型の技術ではなく、積極的に新しい技術を取り入れてサイバー攻撃を防ぐ必要があります。

- 新たな対策を練り

現状のレジリエンスを確認し、何を対策しないといけないのか
積極的に脅威を探しに行って、感染をしないようにする対策を進めます。

## 勉強後イメージ

今まで確かにセキュリティオンリーって感じはしたけど
目的は事業を進められること。

## 参考

- [サイバーレジリエンス (Cyber Resilience)](https://www.nec-solutioninnovators.co.jp/ss/insider/security-words/62.html)
- [サイバーレジリエンスとは？先手の対策で攻撃に強い組織を作る](https://cybersecurity-jp.com/security-measures/28322)
- []()
- []()
- []()
- []()
セーフブラウジング とは

## 勉強前イメージ

シークレットモード的な？

## 調査

### セーフブラウジング とは

安全ではないサイトにアクセスしようとする際にブラウザに出る警告になります。
一般的なブラウザだとフィッシングサイトなどをアクセスする際には警告は出してくれますが
セーフブラウジングはgoogleが提供するサービスを指すことが多いです。

### セーフブラウジングの対象

セーフブラウジングの対象としては大きく以下の2つがあります。

- 不正なソフトウェアをインストールさせようとする
- 正規のwebサイトになりすますフィッシングサイト

## 勉強後イメージ

全然シークレットモードじゃなかったwww
確かに警告出るときもあるかも・・・？
知らない間に守ってくれてる。

## 参考

- [セーフブラウジングとは？Chrome・Safari・Firefoxの設定方法から注意点まで徹底解説](https://cybersecurity-jp.com/security-measures/33331)
水飲み場型攻撃 とは

## 勉強前イメージ

陥れるとかそんなやつ？

## 調査

### 水飲み場型攻撃 とは

英語ではWatering Hole Attackと言われています。
水飲み場型攻撃とは、ターゲットを決めてそのターゲットがいつもアクセスするwebページを改ざんし
アクセスするとマルウェアに感染させて情報を取得する方法になります。
ターゲットになるのは企業などの組織に属しているターゲットで、会社の情報を攻撃者は必要としています。

水飲み場型攻撃の特徴は、不正なメールを開くなどのターゲットが不安になるようなことは感じさせないように実行します。
あくまでいつも見ているサイトなのにいつの間にかマルウェアに感染している という状況になります。
また、攻撃者はターゲットがアクセスされたかをIPアドレスなどで判別し攻撃するので
別のユーザがwebページにアクセスしても何も怒らないため、発見しづらい傾向にあります。

### 水飲み場攻撃の方法

- ターゲットの特定・観察

まずターゲットを決めて、ターゲットが普段閲覧してそうなサイトを割り出します。
割り出すだけではなく、実際に侵入してアクセスログ等みてアクセスが多いかどうかも確認します。
いくつかサイトを出して、不正アクセスができるかも確認します。

- 不正プログラムの埋め込み

不正アクセスができそうなサイトを決定し、不正プログラムを埋め込みます。
自動で不正なダウンロードがされてしまう [ドライブバイダウンロード](https://qiita.com/miyuki_samitani/items/212faa45ad6cbc3ffc4d) など罠を仕掛けます。

- 内部の情報の取得

罠にひっかかったターゲットから内部情報の取得を行います。

### ドライブバイダウンロードとの違い

webページを改ざんしてアクセスしただけでマルウェアに感染する
ドライブバイダウンロードも同様になります。
しかし違いとしては以下になります。

- ドライブバイダウンロード : 無差別に感染させる
- 水飲み場型攻撃 : ターゲットを特定する

基本的には要するにターゲットが誰でもいいのか、絞られてるかの違いになります。

## 勉強後イメージ

ターゲットを決めて攻撃するのなんかほかにもあったなぁ・・・
SNSをチェックしたりとか。。

## 参考

- [【初心者向け】水飲み場型攻撃とは？手口や被害事例・対策をかんたん解説！](https://office110.jp/security/knowledge/cyber-attack/watering-hole-attack)
- [水飲み場型攻撃とは？事例や対策方法を徹底解説](https://cybersecurity-jp.com/security-measures/23279)
Stable diffusion 2.0 depth2img のメモ

Stable diffusion 2.0 depth2img しゅごいね...

https://huggingface.co/stabilityai/stable-diffusion-2-depth

中身としては MiDaS で画像からデプス推定して https://github.com/isl-org/MiDaS いい感じにやるっぽい.

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ふえぇ... Stable Diffusion 2.0 depth2image でアーニャ変換(?)すごぽよ... 😳 <a href="https://t.co/KqCuoPEH3G">pic.twitter.com/KqCuoPEH3G</a></p>&mdash; syoyo.eth 🌸 レイトラ ® 🐯 4 周年 🎉 (@syoyo) <a href="https://twitter.com/syoyo/status/1608855992917463040?ref_src=twsrc%5Etfw">December 30, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Voila! :tada:

## 注意点

実行は特に問題なくサンプルコードぺろっとやればいけます.
現状(2022/12/30) では, `transformers` パッケージは pip で入るのは使えず git のを使う必要があります(pip 版 transformers 使っているとエラーメッセージ出してくれます).

MiDaS の問題なのか, stable diffusion の input tensor size の問題なのか(たぶん後者), 64 の倍数でない画像サイズを与えると

```
RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 64 but got size 65 for tensor ...
```

というエラーがでます!

https://github.com/CompVis/stable-diffusion/issues/301#issuecomment-1251629833

imagemagik なり cv2 で, 画像サイズを 64 の倍数にしておく必要があります.
また, 画像サイズ大きくなると GPU メモリ消費も増えますので(2K 画像入れたら 3090 でもだめだった), ご自身の GPU で走るようにターゲットの画像サイズをうまく調整してみてください.


## ポートレート特化したい...

MiDaS は汎用の depth 推定なので, 人物ポートレート特化の場合は人物用の depth 推定使うとより高品位なものが作れそうな気がします(後処理で合成したいときとかにも!)

https://blog.tensorflow.org/2022/05/portrait-depth-api-turning-single-image.html

https://github.com/khan9048/Facial_depth_estimation

あたりか, iPhone であれば LiDAR デプス使うとかですかね.

また, portrait matting (最近だと P3M https://github.com/JizhiziLi/P3M がよさそうかしら) と組みあわせるとさらによさそうですネ
[pandas] Series, DataFrameの統計量を得る

Series, DataFrameの統計量の求め方をまとめてみた。


# 公式のdocumentation
- [User Guide -- pandas 1.4.4 documentation](https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html)

# 目次
- 動作環境
- 今回扱うDataFrameについて
- 平均
- 分散
- 標準偏差
- 最大値、最小値
- 要約統計量の表示
- DataFrameでの処理

# 動作環境
|種類             |バージョン       |
|:---------------|:--------------|
|MacBook Air     |Ventura13.0.1  |
|python          |3.9.6          |
|jupyter notebook|6.5.2          |
|pandas          |1.5.2          |

まずはパッケージのインポートから
```python:
import pandas as pd
```
pandasを扱うときはpdが慣例だそう。

# 今回扱うDataFrameについて
[[python]pandas read_csvの備忘録](https://qiita.com/yossy_stu/items/a43cd624640f4de5daea)
にて作成したDataFrameで説明している。
```python:
print(df_SN.head(10))
#      year   num  std  spot  certenty
# 0  1700.5   8.3 -1.0    -1         1
# 1  1701.5  18.3 -1.0    -1         1
# 2  1702.5  26.7 -1.0    -1         1
# 3  1703.5  38.3 -1.0    -1         1
# 4  1704.5  60.0 -1.0    -1         1
# 5  1705.5  96.7 -1.0    -1         1
# 6  1706.5  48.3 -1.0    -1         1
# 7  1707.5  33.3 -1.0    -1         1
# 8  1708.5  16.7 -1.0    -1         1
# 9  1709.5  13.3 -1.0    -1         1

```
順に、
year:観測年、num:黒点数、std:標準偏差、obs spot:観測地点数、certainty:確定or未確定
以前の記事のヘッダーから英語にしているとこだけご注意。
また、以降の操作では一貫して"num"の項(全球黒点数)をSeriesの形で用いているが、DataFrameでも同様の処理が可能(後述)


# 平均
Seriesの平均(mean)は、Seriesの末尾に.mean()をつける。

```python:
print(df_SN['num'].mean())
# 78.36521739130436
```
# 分散
Seriesの分散(variation)は、Seriesの末尾に.var()をつける。

```python:
print(df_SN['num'].var())
# 3850.7780387376397
```
# 標準偏差
Seriesの標準偏差(standard deviation)は、Seriesの末尾に.std()をつける。

```python:
print(df_SN['num'].std())
# 62.054637528049746
```
# 最大値、最小値
Seriesの最大値(maximum)、最小値(minimum)は、Seriesの末尾に.max()、.min()をつける。

```python:
print(df_SN['num'].max())
print(df_SN['num'].min())
# 269.3
#   0.0
```
# 要約統計量の表示
末尾に.describe()を付けると、統計量をまとめて表示できる。

```python:
print(df_SN['num'].describe())
# count    322.000000
# mean      78.365217
# std       62.054638
# min        0.000000
# 25%       24.325000
# 50%       65.150000
# 75%      115.075000
# max      269.300000
# Name: num, dtype: float64
```
上から、count:要素数、mean:平均数、std:標準偏差、min:最小値、25%:1/4分位数、50%:中央値、75%:3/4分位数、max:最大値となっている。

# DataFrameでの処理
DataFrameに同様の処理をすると以下のようになる。

```python:
print(df_SN.describe())
#               year         num         std      obs spot  certainty
# count   322.000000  322.000000  322.000000    322.000000      322.0
# mean   1861.000000   78.365217    4.633540   1113.546584        1.0
# std      93.097619   62.054638    5.274608   2574.732653        0.0
# min    1700.500000    0.000000   -1.000000     -1.000000        1.0
# 25%    1780.750000   24.325000   -1.000000     -1.000000        1.0
# 50%    1861.000000   65.150000    4.150000    365.000000        1.0
# 75%    1941.250000  115.075000    8.850000    365.000000        1.0
# max    2021.500000  269.300000   19.100000  15233.000000        1.0
```
見た通り、各column毎に統計量を表示してくれる。
describeメソッドの詳しい使い方については...また後日...

# 参考にしたURL
- [【Python】PandasでDataFrameの各種統計量を算出する方法を紹介！](https://py-memo.com/python/pandas-statistics/)
- [pandasのdescribeで各列の要約統計量（平均、標準偏差など）を取得](https://note.nkmk.me/python-pandas-describe/)
【車輪の再発明】Enumの関数一覧を出力して今後のネタを作る

どこまで実施するかは未定ですが、ネタとして
Enumの関数一覧を出力したいと思います

気が向いたら【車輪の再発明】をしていきたいと考えてます

では、Enumで使える関数一覧を出力してみましょう

```Elixir
Enum.__info__(:functions) 
|> Enum.each(&IO.inspect/1)
```

```Elixir:一覧
{:all?, 1}
{:all?, 2}
{:any?, 1}
{:any?, 2}
{:at, 2}
{:at, 3}
{:chunk, 2}
{:chunk, 3}
{:chunk, 4}
{:chunk_by, 2}
{:chunk_every, 2}
{:chunk_every, 3}
{:chunk_every, 4}
{:chunk_while, 4}
{:concat, 1}
{:concat, 2}
{:count, 1}
{:count, 2}
{:count_until, 2}
{:count_until, 3}
{:dedup, 1}
{:dedup_by, 2}
{:drop, 2}
{:drop_every, 2}
{:drop_while, 2}
{:each, 2}
{:empty?, 1}
{:fetch, 2}
{:fetch!, 2}
{:filter, 2}
{:filter_map, 3}
{:find, 2}
{:find, 3}
{:find_index, 2}
{:find_value, 2}
{:find_value, 3}
{:flat_map, 2}
{:flat_map_reduce, 3}
{:frequencies, 1}
{:frequencies_by, 2}
{:group_by, 2}
{:group_by, 3}
{:intersperse, 2}
{:into, 2}
{:into, 3}
{:join, 1}
{:join, 2}
{:map, 2}
{:map_every, 3}
{:map_intersperse, 3}
{:map_join, 2}
{:map_join, 3}
{:map_reduce, 3}
{:max, 1}
{:max, 2}
{:max, 3}
{:max_by, 2}
{:max_by, 3}
{:max_by, 4}
{:member?, 2}
{:min, 1}
{:min, 2}
{:min, 3}
{:min_by, 2}
{:min_by, 3}
{:min_by, 4}
{:min_max, 1}
{:min_max, 2}
{:min_max_by, 2}
{:min_max_by, 3}
{:min_max_by, 4}
{:partition, 2}
{:product, 1}
{:random, 1}
{:reduce, 2}
{:reduce, 3}
{:reduce_while, 3}
{:reject, 2}
{:reverse, 1}
{:reverse, 2}
{:reverse_slice, 3}
{:scan, 2}
{:scan, 3}
{:shuffle, 1}
{:slice, 2}
{:slice, 3}
{:slide, 3}
{:sort, 1}
{:sort, 2}
{:sort_by, 2}
{:sort_by, 3}
{:split, 2}
{:split_while, 2}
{:split_with, 2}
{:sum, 1}
{:take, 2}
{:take_every, 2}
{:take_random, 2}
{:take_while, 2}
{:to_list, 1}
{:uniq, 1}
{:uniq, 2}
{:uniq_by, 2}
{:unzip, 1}
{:with_index, 1}
{:with_index, 2}
{:zip, 1}
{:zip, 2}
{:zip_reduce, 3}
{:zip_reduce, 4}
{:zip_with, 2}
{:zip_with, 3}
```

# どのくらい数あるの？

```Elixir
Enum.__info__(:functions) 
|> Enum.count()       
````
  
アリティの組み合わせも含めて112パターンありました


```Elixir
Enum.__info__(:functions) 
|> Enum.map(fn {x, _} -> x end) 
|> Enum.uniq() 
|> Enum.count()
```
関数の数では74

ネタには困らない…　が気力が続いたらね
vuexでuser情報をグローバルに使用するためのメモ

vueでコンポーネント間のデータ使用で、propsやemitを使いますが、
vuexを使って、どこでもデータを呼び出すことができます。
user情報の保持はよく使うので、忘れないようにメモ。

## user情報を保存するための関数
src/store/index.js
```vuejs
 mutations: {
    user: (state, data) => (state.user = data),
  },
  actions: {
    setUserData: ({ commit }, data) => {
      commit('user', data)
    },
  },
```

## ユーザー情報を保存
```
// ユーザー情報をVuexに保存する
  store.dispatch('setUserData', response.data)
```

## ユーザー情報を呼び出す
```
this.user = this.$store.state.user
```
SearchViewでソフトキーボードを非表示にする

AndroidアプリでActionBarにSearchViewを実装する際のソフトキーボードを非表示にする方法は、以下の通りです。<br>
今回は、Fragmentに

## レイアウトファイル
```menu/search.xml
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/search"
        android:title="@string/search"
        android:icon="@drawable/ic_baseline_search_white_24"
        android:orderInCategory="100"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="android.widget.SearchView"/>
</menu>
```

## Fragment
```HogeFragment.java
public class HogeFragment extends Fragment
    private SearchView searchView;
    ...
    @Override
    public void onCreate(Bundle saveInterface) {
        super.onCreate(saveInterface);
        // FragmentでMenuを表示する為に必要
        setHasOptionsMenu(true);
    }
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
        searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        // 虫眼鏡アイコンの表示設定
        this.searchView.setIconifiedByDefault(false);
        // リスナーの設定
        searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean hasFocus) {
                if(!hasFocus){
                    hideIMM(view.findFocus());
                }
            }
    });
    private void hideIMM(View view) {
        InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(searchView.getWindowToken(),0);
        }
    };
```
## 困ったところ
setOnFocusChangeListener()だと思っていたら、setOnQueryTextFocusChangeListener()だったでござる。

## 参考
[StackOverFlow -Android SearchView OnFocusChangeListener: onFocusChange is not called at all-](https://stackoverflow.com/questions/27944238/android-searchview-onfocuschangelistener-onfocuschange-is-not-called-at-all)
[SearchView Androidデベロッパー Android開発者](https://developer.android.com/reference/android/widget/SearchView)]
GoとGraphQLでサーバー実装 【環境構築編(Docker)】

# DockerでGoとPostgreSQLの環境構築

:::note warn
間違っている部分、エラーが発生する部分、わかりにくい部分などがございましたら、是非ご指摘をお願い致します。
:::

## この記事の内容
この記事はGo,GraphQL,PostgreSQLと使用してサーバの実装の**Part1**になります。
今回はDockerを用いてGoとPostgreSQLの環境構築を行います。

## Github Repo
この記事で紹介するコードはGithubに置いています。

https://github.com/shion0625/gqlgen-todos/tree/part1

## dockerファイルの作成

### 今回のディレクトリ構成

```
gqlgen-todos
├── docker
│   └── go
│       └── Dockerfile
└── docker-compose.yaml
```

#### Dockerfile
Goのイメージには軽量なalpineを使用しています。

- **git:** go getが内部的に呼び出しているらいしい! alpineにはgitが入っていないのでインストール
- **alpine-sdk:** build-essentialのようなもの。開発に必須のビルドツールみたい。

```Dockerfile:docker/go/Dockerfile
# goバージョン
FROM golang:1.19.1-alpine

# アップデートとgit、alpine-sdkのインストール
RUN apk update && apk add git && apk add alpine-sdk

# 環境変数の設定
ENV APP_ROOT /app

# ディレクトリの作成
RUN mkdir $APP_ROOT

# ワーキングディレクトリの設定
WORKDIR $APP_ROOT

# Goの詳細設定
ENV CGO_ENABLED=1 \
  GOOS=linux \
  GOARCH=amd64 \
  GO111MODULE=on

# ルートディレクトリを作業ディレクトリにコピー
COPY . $APP_ROOT

EXPOSE 8080

```

#### docker-compose.yml
GoとDBのコンテナを立てるため、docker-compose.yamlを作成

```yml:docker-compose.yml
version: '3.9'

services:
  server:  #サービス名
    build:
      context: ./docker/go  #ビルドに使用するDockerfileの場所
      dockerfile: Dockerfile
    container_name: gqlgen-todos  #コンテナの名前
    tty: true  #コンテナの永続化
    ports:
      - '8080:8080'
    depends_on:  #依存関係
      - db
    volumes:  #マウントディレクトリ
      - .:/app
      - go-data:/go

  db:  #サービス名
    image: postgres:latest  #ビルドに使用するimageファイル
    container_name: postgres  #コンテナの名前
    environment:
      POSTGRES_DB: 'todo'  #データベース名
      POSTGRES_PASSWORD: 'password'  #データベースパスワード
      POSTGRES_USER: 'postgres'  #データベースユーザ名
      TimeZone: Asia/Tokyo  #タイムゾーン
    ports:
      - '5432:5432'
    volumes:  #マウントディレクトリ
      - /var/lib/postgres/data

volumes:
  go-data:

```

### コンテナの作成・実行
下記コマンドを実行し、コンテナを作成し実行します。
```
$ docker-compose 
Successfully built ....

$ docker-compose up -d
Creating postgres ... done
Creating gqlgen-todos ... done
```

###コンテナの中にアクセスする


### コンテナを停止
```
$ docker-compose stop 
Stopping gqlgen-todos ... done
Stopping postgres     ... done
```

## まとめ
GoとPostgreSQLの環境構築を行いました。
次回からは、gqlgenを使用してGo、Graphql、PostgreSQLを使用したTodoアプリの作成を行っていきます。

次回(Part2)の投稿

https://qiita.com/shion0625/items/be454f94a99cac461d5e
SteamDeckでmidiを扱う。

SteamDeckのprotonの動きが素晴らしく、古いWindowsアプリもなんとなく動いてしまいます。
んが、コンパイルのディスクステーション等2000年ごろのmidi対応のものが多く、そのままでは動かないので
いろいろ試した結果うごいたのでまとめておきます。

サウンドフォントはいろいろあるので好きな物に置き換えればいいと思います。

## 対象
SteamDeckでmidiを鳴らしたい人。

1.SteamOSが起動しましたら、Desktopモードに切り替えます。

2.konsoleを起動し、以下のコマンドを実施します。
```
sudo steamos-readonly disable
sudo pacman -S fluidsynth
sudo pacman -S soundfont-fluid
sudo steamos-readonly enable
```
3.続いて以下のコマンドを実施、/etc/conf.d/fluidsynthを書き換えます。
```
sudo vim /etc/conf.d/fluidsynth
```
内容
```
# Mandatory parameters (uncomment and edit)
SOUND_FONT=/usr/share/soundfonts/FluidR3_GM.sf2

# Additional optional parameters (may be useful, see 'man fluidsynth' for further info)
OTHER_OPTS='-a pulseaudio -m alsa_seq -r 48000'
```
--alsaではなくpulseaudioになっていることを確認。

4.続いて以下のコマンドでデーモンとして登録、自動起動および起動していることを確認する
```
systemctl --user start fluidsynth
systemctl --user enable fluidsynth
systemctl --user status fluidsynth
```
5.以下のコマンドを実施し、FLUID Synthがいることを確認する。
```
aconnect -o
```
結果
```
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 128: 'FLUID Synth (1078)' [type=user,pid=1078]
    0 'Synth input port (1078:0)'
```
6.steamに非steamソフトを登録しmidiがなることを確認する。
【Ruby】オブジェクトが空か確認する方法

<table id="tablepress-169" class="tablepress tablepress-id-169 tablepress-responsive">
<thead>
<tr class="row-1 odd">
	<th class="column-1">メソッド</th><th class="column-2">説明</th>
</tr>
</thead>
<tbody class="row-hover">
<tr class="row-2 even">
	<td class="column-1">nil?</td><td class="column-2">変数の値がnilまたは値なしの場合に真</td>
</tr>
<tr class="row-3 odd">
	<td class="column-1">empty?</td><td class="column-2">変数の値が空文字や値が空白の場合に真</td>
</tr>
<tr class="row-4 even">
	<td class="column-1">blank?</td><td class="column-2">nil?やempty?が真となる場合に真</td>
</tr>
<tr class="row-5 odd">
	<td class="column-1">present?</td><td class="column-2">blank?の逆。値がある場合に真</td>
</tr>
</tbody>
</table>
クエリパラメータに日本語を渡したら困った話

## 概要
- [Cloudflare Pagesの Functions機能](https://developers.cloudflare.com/pages/platform/functions/)をつかって検索結果を返すAPIを作成していた
- /api/search?q=検索キーワード　のようなURLにリクエストを投げたらmicroCMSのAPIをたたいた検索結果が返ってくるようにしていた
- 検索キーワードに**日本語を含む文字列**を指定した

:::note warn
日本語を含むというところがポイントですが、それ以前に文字列をそのまま連結してURLを作っていたという問題点もありました。
:::

このようなシチュエーションで、APIをたたいた時、

- `wrangler pages dev`で起動している**ローカル環境ではほしいデータが返ってくる**
- **本番環境では空のデータが返ってくる**

となって少し詰まったので記事として残します。

過去同じようなことがあった気がしたので試しに英単語で検索したら本番でもローカルでも動いていたので、今回はエンコードか…とすぐ気づくことができました。

## 解決方法
検索キーワードの部分に渡す文字列を`URLSearchParams`で処理してから渡すだけです。
そもそもそのまま文字列連結して渡すのは危なかったですね。

### ダメな例
``` js
const q = '日本語のキーワード' // Inputなどから得た検索キーワード
fetch(`/api/search?q=${q}`)
```

### OKな例
```js
const q = '日本語のキーワード' // Inputなどから得た検索キーワード
const params = new URLSearchParams()
params.append('q', q)
fetch(`/api/search?${params.toString()}`)
```

気を付けましょう。

## 参考
- [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
- [microCMSのqパラメーター](https://document.microcms.io/content-api/get-list-contents#ha8abec0b2f)
Googleプロジェクト管理：リスク軽減戦略

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7c79c997-e4e4-7d71-3686-e01b7badaa3c.png" width="800">

# 単一障害点を管理する

リスクを特定し、ランク付けしたら、チームのプロジェクト完了能力に壊滅的な影響を及ぼす可能性のあるリスクには特に注意を払う。単一障害点とは、もしそれが現実のものとなった場合、プロジェクトに多大な支障をきたし、停止してしまう可能性のあるリスクのことです。このようなリスクは、プロジェクトの早い段階から計画しておく必要があります。

### ケーススタディ：４つのリスク軽減策

オフィスグリーンが、提供する商品の大半に南米の会社の植物の種を使用しているとしよう。この種子から生産される植物は、オフィスグリーンの顧客から高い需要があります。ところが、供給側の現地政府が、種子や農産物の輸出に新たな税金を課すと発表したのです。その結果、種子の価格が急に高くなり、オフィスグリーンに種子を供給することが難しくなり、このプロジェクトは種子を購入できなくなるリスクを抱えることになった。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/e58c74db-548d-688b-c33f-f3355431bf82.png" width="600">

#### 1.回避する

この戦略は、全体的な状況を回避することを目指すものです。

> オフィスグリーンの例では、数カ所で広く入手できる別の種を使うことを検討することで、このリスクを完全に回避することができます。

#### ２．最小化する

リスクを軽減するには、そのリスクがプロジェクトに及ぼす壊滅的な影響を最小限に抑えるようにします。リスクを最小化するための鍵は、リスクが存在することを認識することから始まります。そのため、緩和策を回避策と呼ぶのが一般的です。

> もし、オフィスグリーンチームが、元の南米のサプライヤーと近隣の国のサプライヤーの両方を使うことに決めたとしたらどうでしょう？おそらく、税制や規制の変更が両社に影響することはないでしょうし、オフィスグリーンが好んで使っていたサプライヤーを完全に排除することなく、ある程度の柔軟性を確保することができます。

#### ３．移管する

移転という戦略は、リスクを処理する責任を他の誰かに移すことです。

> オフィスグリーンは、北米で南米産の種子を使用するサプライヤーを見つけ、代わりにそこから種子を購入することができます。これにより、南米の規制リスクとコストの所有権は、そのサプライヤーに移ることになります。

#### 4.受け入れる

最後に、リスクをビジネスを行う上での通常のコストとして受け入れることができます。リスクを積極的に受け入れるということは、通常、トラブルから逃れるために余分な資金を準備することを意味します。リスクを受動的に受け入れるとは、「何もしない」アプローチである。受動的なリスク受容は、小さなリスクに対しては合理的かもしれないが、ほとんどの単一障害点リスクに対しては推奨されない。また、可能な限り積極的にリスクを軽減することが重要であり、そうすることでリスクを受け入れずに済む可能性がある。

> オフィスグリーンのシナリオでは、プロジェクトマネージャーは、南米の増税とそれがプロジェクトコストに与える影響について、プロジェクトのステークホルダーとのミーティングを予定することができます。そして、必要であれば、種子を別の業者から調達するための追加資金を用意してリスクを積極的に受け入れるか、今シーズンは種子をまったく受け取らないというリスクを消極的に受け入れるかを決定することができます。
Googleプロジェクト管理：リスクの種類

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7c79c997-e4e4-7d71-3686-e01b7badaa3c.png" width="800">

# リスクの種類

今回は、プロジェクト管理中に想定される一般的なリスクについて説明します。プロジェクトに影響を与えるリスクには様々な種類があります。

## 時間リスク

プロジェクトのタスクが完了するまでに予想以上に時間がかかる可能性のことである。時間はお金であるため、時間的なリスクを認識する必要があります。時間管理が悪いと、予算が枯渇し、遅延が発生して利害関係者を動揺させる可能性があります。

## 予算リスク

計画の不備やプロジェクト範囲の拡大により、プロジェクトの費用が増加する可能性のことである。予算はプロジェクトコスト管理の基礎となるため、予算リスクを認識する必要があります。例えば、経費を使いすぎると、サプライヤーに支払いができなくなる可能性があります。これは、会社にとって何らかの風評被害をもたらすかもしれません。

## スコープリスク

プロジェクトがプロジェクト目標に示された結果を生み出さない可能性のことである。プロジェクトの成果物がステークホルダーや顧客に受け入れられず、プロジェクト全体の目的が達成されない可能性があるため、スコープリスクには注意する必要があります。

## 外部リスク

自分ではほとんどコントロールできない社外の要因に起因するリスクを指します。例えば、あなたのプロジェクトは、大嵐のような環境リスクや、規制要件の変更のような法的リスクによって影響を受ける可能性があります。 

## 単一障害点

壊滅的な被害をもたらし、プロジェクト全体の作業を停止させる可能性のあるリスクのことです。これらのリスクは、チーム全体を停止させる力があり、問題が解決されるまで、誰も自分のタスクを進めることができないことを意味する。プロジェクトマネージャーとして、プロジェクトにおける潜在的な単一障害点を特定し、監視する必要があります。

例えば、単一障害点として、プロジェクトに関するあらゆる情報が保存されている内部データベースが停電でダウンすることが考えられます。データベースが復旧するまで、あなたのチームは仕事に必要な情報にアクセスすることができません。その結果、チームは割り当てられたタスクを完了することができなくなります。このリスクを軽減するために、プロジェクトの文書や情報をバックアップするためのクラウドサービスを別途予算化することも考えられます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c9ebe356-d15e-fa4f-b3db-354be1262da9.png" width="600">

## 依存関係

プロジェクトの2つのタスクの間の関係のことで、一方の開始や完了が他方の開始や完了に依存することです。言い換えれば、依存関係とは、あるプロジェクトタスクと別のタスクとをつなぐリンクのようなものです。依存関係は、そのタスクが完了する前、あるいは別のタスクが始まる前に対処されなければならない。依存関係は、あるプロジェクトのタスクと別のタスクをつなぐリンクであるため、しばしばプロジェクトにとって大きなリスク源となる。

依存関係には、内部依存と外部依存の2種類があります。

- **内部依存関係:** あなたとあなたのチームがコントロールできるプロジェクト内の依存関係のことです。
- **外部依存関係:** あなたとあなたのチームがコントロールできない依存関係のことです。

:::note info
プロジェクトに影響を与えるリスクは、さまざまなものがあります。しかし、リスクのないプロジェクトはないということを忘れないでください。また、事前に入念な計画を立てることで、リスクの発生を未然に防ぐことができます。
:::
Windows10/11アップデート後にWindows Server Essential コネクター が動作しない問題の解決方法

# 概要
`Windows Server 2012 R2 Essentials` や `Windows Storage Server 2012 R2 Essentials` 環境で Windows10/11 のクライアントを使用している場合、クライントのOSアップデート後に **Windows Server Essential コネクター** が動作しない場合の修正方法を記事します。

## 参照
https://sbsland.me/2022/10/03/windows-10-update-1903-und-der-essentials-connector-fix/  (ドイツ語)
https://sbsland.me/2022/10/03/fix-windows-10-update-and-small-business-essentials-connector/ (英語版)

## 注意事項
- 本記事は海外ブログで紹介されている内容をもとにしています。レジストリの変更などの操作が含まれているので、手順を実施する際は、その内容やリスクを理解した上で行ってください。
- 筆者は、Windows Storage Server 2012 R2 Essentials がインストールされたTheecusのNASで確認しています。Windows10/11 は正式にはサポートされていませんのでご注意ください。
- Windows Storage Server 2012 R2 の延長サポートに入っておりWindows10/11の対応がリリースされることはありません。
- 延長サポートは2023年10月10日に終了し、終了後はセキュリティアップデートが出なくなるのでご注意お願いします。

## 現象
Windows Server Essential コネクターが動作しないことで次のような現象が起こります。

- クライアントがオフライン状態になる
- クライアントバックアップが動作しない

## 原因
アップデートの影響で Windows Server Essential関係のサービスのレジストリキーが失われます。
そのため、これらのサービスは機能しません。

### 関連サービス
- Windows Server Essentials Client Computer Management Service
- Windows Server Essentials Client Computer Monitoring Service
- Windows Server Essentials Health Service
- Windows Server Essentials Notification Service
- Windows Server Essentials Provider Registry Service

※筆者の環境（Windows11 Pro 22H2) では、service.msc を見てもこれらのサービスは存在していなくて消えていました。

## 解決方法
こちらで公開されているZipファイルを展開するとスクリプトとレジストリキーが出現します。
https://sbsland.files.wordpress.com/2021/10/wsefix-1903v5.zip

```
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2023/01/19     22:25           2851 Fix-WSeLaunchpad-1903.ps1
-a----        2023/01/19     22:25           3894 ServiceProviderRegistry.reg
-a----        2023/01/19     22:25           4684 WseClientMgmtSvc.reg
-a----        2023/01/19     22:25           4868 WseClientMonitorSvc.reg
-a----        2023/01/19     22:25           4632 WseHealthSvc.reg
-a----        2023/01/19     22:25           4604 WseNtfSvc.reg
```

管理者権限でPowerSehllを起動して、展開先のフォルダに移動後、次のコマンドでスクリプトを実行します。

```PowerShell
Get-Content -Path .\Fix-WSeLaunchpad-1903.ps1 | PowerShell.exe -NoProfile -
```

実行後PCを再起動します。

再起動後、ダッシュボードでクライアントの状態がオンラインになっていることを確認できれば成功です。
WindowsMachineでMAUIアプリが起動しない

経緯
-
C#で記述できて、クロスプラットフォームで動くアプリを作るために.NET MAUIを選択しました。
とりあえずチュートリアルをやってみようと思ったのですが、アプリケーションの実行をしてもエラーで終了してしまう。。
そんなことがあったので、解決策の備忘のために記事を書きました。

開発環境
-
- OS
    - Windows10(22H2)
- Visual Studio 2022
    - Version 17.4.4
- デバッグ対象
    - フレームワーク(net7.0-windows10.0.19041.0)

解決策
-

1. Visual Studioでアプリをビルドする
    1. 完了後に、Windowsメニューに作成したアプリが追加される
1. Windowsメニューに表示されたアプリを管理者で実行
1. 開いたアプリを閉じる
1. 以降、Visual Studioからデバッグ実行が可能となる

感想
-
他のところではAndroidのエミュレーターでやっていたので
解決策にたどり着くまでに時間がかかってしまった。。

参考サイト
-
- チュートリアル
    - https://dotnet.microsoft.com/ja-jp/learn/maui/first-app-tutorial/run
- 同じ状況になった人の投稿
    - https://github.com/dotnet/maui/issues/12080
    - 解決策を提示している投稿
        - https://github.com/dotnet/maui/issues/12080#:~:text=What%20worked%20for,within%20Visual%20Studio.
qiitaで文字を大きくしたい時

font要素に$で囲んでLaTeXコマンドを打つとそのLaTeXが反映されます。
これを利用して文字を大きく表示させます。

# 例
```html:コード
<font>$\huge{でかい}$</font>
```

## 確認
<font>$\huge{でかい}$</font>

また、
```html
<font>$\コマンド{文字}$</font>
```
だけではなく
```html
<font>${\コマンド 文字}$</font>
```
も使えます。

```html:コード
<font>${\huge これもでかい}$</font>
```

## 確認
<font>${\huge これもでかい}$</font>

大きくするだけではなく小さくすることもできます。


```html:コード
<font>${\tiny 文字}$</font>
<font>${\scriptsize 文字}$</font>
<font>${\normalsize 文字}$</font>
<font>${\large 文字}$</font>
<font>${\Large 文字}$</font>
<font>${\LARGE 文字}$</font>
<font>${\huge 文字}$</font>
<font>${\Huge 文字}$</font>
```

## 確認
<font>${\tiny 文字}$</font>
<font>${\scriptsize 文字}$</font>
<font>${\normalsize 文字}$</font>
<font>${\large 文字}$</font>
<font>${\Large 文字}$</font>
<font>${\LARGE 文字}$</font>
<font>${\huge 文字}$</font>
<font>${\Huge 文字}$</font>


その他のコマンドは以下からどうぞ

http://www1.kiy.jp/~yoka/LaTeX/latex.html
【Android】assetsフォルダにあるテキストファイルを読み込む方法


``` Kotlin
fun readFile(fileName: String): String {
    var text = ""

    try {
        val inputStream = context.assets.open(fileName)
        text = inputStream.bufferedReader().use {
            it.readText()
        }
    } catch (e: Exception) {
        // エラー処理
    }
    return text
}
```

`val inputStream = context.assets.open(fileName)`でassetsフォルダにある`fileName`ファイルを読み込みます。
`fileName`には拡張子を含んだ名前を渡します。
`text`には読み込んだテキストファイルの中身（改行も含む）が入ります。
【JavaScript】書き方による関数の違いまとめ

# はじめに
JavaScriptでは、関数の定義方法が複数あります。
いつもなんとなくで書いていたのですが、調べてみると書き方によって少しづつ違いがあったのでまとめてみようと思います。

# 関数の定義方法4つ
関数の定義方法は以下４つです。
### 1. function命令で定義
```.js
function getTaxIncludedPrice(price, tax) {
    return price + price * tax
} 
```
### 2. Functionオブジェクトを利用して定義
```.js
const getTaxIncludedPrice = new Function('price', 'tax', 'return price + price * tax')
```
### 3. 関数リテラルで定義
```.js
const getTaxIncludedPrice = function(price, tax) => {
    return price + price * tax
}
```
### 4. 関数リテラルで定義（アロー関数）
```.js
const getTaxIncludedPrice = (price, tax) => {
    return price + price * tax
}
```

# 書き方による特徴
### 1.評価のタイミングの違い
●function命令
　コードを解析するタイミング（コードの実行よりも前）で関数を登録
●FUnctionオブジェクト、関数リテラル、アロー数
　コード実行時に評価

```.js
getTaxIncludedPrice(100, 1)

function getTaxIncludedPrice(price, tax) {
    return price + price * tax
]
```
これは正常に実行される
```.js
getTaxIncludedPrice(100, 1)

const getTaxIncludedPrice = functoin(price, tax) {
      return price + price * tax
}
```
```.js
getTaxIncludedPrice(100, 1)

const getTaxIncludedPrice = new Function('price', 'tax', 'return price + price * tax')
```
```.js
getTaxIncludedPrice(100, 1)

const getTaxIncludedPrice = (price, tax) => {
    return price + price * tax
}
```
これらは実行時未定義となるためエラー

### 2.変数のスコープの違い
●Functionオブジェクト
　グローバル変数
●functoin命令、関数リテラル、アロー関数
　ローカル変数
```.js

const hoge = 'global'
function test() {
    const hoge = 'local'

    const test1 = function() {
        console.log(hoge)
    }

    const test2 = new Function('console.log(hoge)')
    
    test1()
    test2()
}

test()
```
実行結果
![スクリーンショット 2023-01-19 22.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/831462/2a85c14a-f235-4871-4818-ed6aa2cf69c1.png)
### 3.コンストラクタを持つかどうかの違い
●コンストラクタを持つ
　function命令、関数リテラル、Functionオブジェクト
●コンストラクタを持たない
　アロー関数
```.js
function hoge(){
    console.log('インスタンス化された')
}
 new hoge()
```
```.js
const hoge = function{
    console.log('インスタンス化された')
}
 new hoge()
```
```.js
const hoge = new Function('console.log("インスタンス化された")')
new hoge()
```
これらは可能。
インスタンス化された際に関数内の処理が実行されるため、コンソールには以下が表示される。
![スクリーンショット 2023-01-19 22.42.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/831462/bada93ca-4c8f-17cd-460c-a8b8cb66b548.png)

下記リンクでコンストラクタについて分かりやすい説明がされていました。
https://note.affi-sapo-sv.com/js-constructor.php

# 4.その他 アロー関数におけるthisの固定

※執筆中
ASUS TransBook T101HAにLubuntuを入れる話 その２

# さまざまな不具合対処をして実用性を向上

さて、前回 TransbookにLubuntuをいれてから気に入って使ってるんですが、いろいろと不具合が・・・もうちょっと外に持ち出して仕事でも使えるようにいろいろ対策をしてます。


# 数分で音がとまって大きなビープ音が出る

radikoを聞いてるんですが、数分でどうしても音が止まって、突然ビープ音がでます。これ、T101HAにいろんなdistroのLinuxを入れても全然解決せず。こりゃカーネルとかのバグか？とか気づくまで相当時間がかかりました。

結論、

/etc/modprobe.d/alsa-base.conf

に

options snd_sof sof_debug=1

を１行追記して解決。


# openconnect-ssoの問題

SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled (_ssl.c:997)

みたいなことを言われますが、

/usr/lib/ssl/openssl.cnf

に

Options = UnsafeLegacyRenegotiation

を追記してこれもどうにか解決しました。





【参考文献】
https://askubuntu.com/questions/1393842/after-a-few-minutes-of-audio-video-playback-computer-starts-beeping-21-10-asu
ガロア群を計算するアプリケーション

# 初めに🎉

SageMath を使ってガロア群を計算するアプリケーションを作りました。🙌

- SageMath とは

https://www.sagemath.org/

- リポジトリはこちら

https://github.com/oiz-y/sage-lambda-container-app


# URL🌐

### https://www.galoisapp.com/

- 例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/619ae679-2bf5-745e-84dc-034c6de5659d.png)


# 開発🐲

バックエンドは AWS Lambda というサーバーレスサービスを使っています。

- AWS Lambda とは

https://aws.amazon.com/jp/lambda/

- システム構成図はこちら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/90e15cb6-0463-b15b-41c3-1d3286bc0f1b.png)

- バックエンドのリポジトリはこちら

https://github.com/oiz-y/sage-lambda-container-backend

- SageMath を Lambda で動かす方法はこちら（サンプルを作りました。カスタマイズする際に利用してみてください。）

https://github.com/oiz-y/sagemath-lambda-container-sample


# 参考記事📕

- バックエンドはこちらのイメージをカスタマイズしました

https://hub.docker.com/r/sagemath/sagemath

- 上記イメージのカスタマイズ内容・手順についての記事を書きました（まとまっていません・・・）

https://qiita.com/oiz-y/items/a004d7d54c441f96108f
qr_code_scannerを用いて普通車の車検証QR(分割QR)を読み取る（完成度３割）

[qr_code_scanner](https://pub.dev/packages/qr_code_scanner)を使用

普通車の車検証QRでは左から３つで１つ、残り２つで１つの文字列として読み取られる。つまり分割QRである。
軽自動車は読み取った文字列が１つずつ読み取れるため、分割QRではない。
軽自動車は[仕様書](https://www.miyagi-gyosei.or.jp/media/files/_u/topic/file2/1zqek172yt.pdf)があったが、普通車はなかった。

分割QRの仕様に関しては[この記事](https://zenn.dev/seya/articles/40b50f845bc136)を参照してください。

### その他参考記事
https://zenn.dev/seya/articles/6e15432cfe327d