OmniAICreator/Qiita-1.07M huggingface dataset:
venv基本操作まとめ

# 内容
- venvとは？
- 基本操作

# venvとは？
- pipによるライブラリの管理を、プロジェクトごとに独立させることができる。
- python3に標準搭載されており、シンプルで軽量

# 基本操作
まずは、好きな場所にプロジェクトディレクトリを作成しましょう。今回は~/projectとします。以下のコマンドはすべてprojectディレクトリ内で実行します。

## 仮想環境の作成
envという名前の仮想環境を作成します。実行するとproject/envディレクトリが作成されます。この中にライブラリがインストールされていきます。
```powershelll:shell
python3 -m venv env
```

## 起動
作成した環境を起動します。この作業は忘れないようにしましょう。
```powershell:shell
# Mac/Linux向け
source env/bin/activate

# Windows向け
env/Scripts/activate
```

## ライブラリのインストール
numpyをインストールする例です。
```powershell:shell
pip3 install numpy
```

## ライブラリの削除
```powershell:shell
pip3 uninstall numpy
```

## インストール済みのライブラリ一覧の表示
```powershell:shell
pip3 list
```

## requirements.txtを使った管理
現在インストールされているライブラリを出力
```powershell:shell
pip3 freeze > requirements.txt
```

requirements.txtに記述されたライブラリ一覧をまとめて新たな環境にインストールする。
```powershell:shell
pip3 install -r requirements.txt
```

## 環境の初期化
```powershell:shell
python3 -m venv --clear env
```

## 環境の削除
envフォルダを削除
VPCフローログとは??の備忘録

### AWS公式説明
VPC フローログは、VPC のネットワークインターフェイスとの間で行き来する IP トラフィックに関する情報をキャプチャできるようにする機能です。

#### 初見の個人的見解
ほ〜ん。VPCを介しているネットワークを監視して、何をしているのかを見てるのね。

#### 主な監視対象
トラフィックの送信元と送信先
通信のポートとプロトコル
パケットおよびバイト数
通信の開始および終了時刻
アクション (許可→ACCEPT, 拒否→REJECTなど)

#### 監視対象範囲
VPCフローログが監視できる範囲は、
・VPC内部
・異なるVPC間

以上となります。
ここは、違う、ここはこうじゃない？等々ございましたらご指摘いただけますと幸いです。

[VPC フローログを使用した IP トラフィックのログ記録](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/flow-logs.html)
OpsRamp Logsのアプリケーションのログ定義方法について

本記事では、OpsRamp Logsのアプリケーションのログ定義方法について説明します。

# 概要
OpsRamp Logsでは、OpsRmap Agentがアプリケーションに対するログ監視設定を定義することができます。定義された設定は、アプリケーションが検出されると自動的にOpsRamp Agentの設定に反映されます。

# 設定方法
ログ監視定義は、Infrastructure > Logs 画面左上のハンバーガーマークのLog Configurationにアクセスし、INGESTIONのページから設定可能です。
![log-configuration.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/a05ad57c-dec0-432e-7373-61a15735e726.png)
![log-ingestions.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/c4f5b433-bdef-966e-2053-e7f585129fe9.png)

「Assigned Resources」では、割り当てるリソースを選択することができます。
「LOG CONFIGURATION YAML」では、YAML形式でログ監視設定を定義します。
![log-ingestions_configuration.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/e2458000-6650-b980-a47f-b48860a7debd.png)


- 設定例
``` yaml: custom-ingestion
Custom-App: 
  type: "file" # Possible values for type [ "file", "journald", "syslog", "kubernetes_logs", "windowseventlog", "docker"]
  source: "custom-app"
  include: # Array of patterns specifying the log file paths to include
    - "/var/log/py-app/test.log"
  parser_type: "regex"
  regex: ^\s*(?P<timestamp>\w*\s*\d*\s*\d*:\d*:\d*)\s*(?P<host>[^\s]*)\s*(?P<syslog_tag>[^:]*):\s*(?P<message>.*)$
  timestamp:
    layout_type: strptime # Valid values are strptime, gotime, and epoch
    layout: '%b %e %H:%M:%S'
```


---------------------------------------
[<img width = 250 height = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/111de30a-4d33-aa33-5c7d-83d9015093e6.png">](https://www.vistanet.jp/knowledge-base/)
25の割り算　割られる数が30000ぐらいまで正しい



25の割り算　割られる数が30000ぐらいまで正しい



Arduino アルゴリズム MCP9701


参考


https://www.recfor.net/jeans/index.php?itemid=902


↑ここをクリック↑



![o_cop891.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/62bdbdbb-02d3-4d40-e261-bfd7cbcb4a64.jpeg)



目的
MCP9701の小数点を丸めて0,.25,.50,.75にするため
0から99を25で割って0,1,2,3にして、25を掛ける


オンラインコンパイラ　paiza.io



```c++


#include <stdio.h>
int main(void){
    // Your code here!

//25の割り算 0から30000までは、だいたい正しい   
#define DIV25(in) ((in*(65536/25*16+8))>>20)

    int in = 30000;
    
    printf("%d %d",in,DIV25(in));
    
    
}


```


```

30000 1200


```
VRCの映画リンク集

※今この記事は一旦quiitaで書いてますが、後々は私のブログに記事ごとお引越し予定です。
私のブログが完成したらリンクここに貼ります。

①【本編】全編VRSNS撮影サイバーパンク映画【NINE -PREQUEL OF EMETH-】
https://www.youtube.com/watch?v=eyq51UhaqjY&t=47s

②全編VRChat撮影映画！『IRREGULAR’S』- 本編映像
https://www.youtube.com/watch?v=6n3Mvr9DgjI
女性の人が本職の声優さんか！？って位声が良い

③What If Mirrors Were ILLEGAL In VRChat? (日本語字幕)
https://www.youtube.com/watch?v=e8ezh61DhnE
ブラックジョーク系ｗ
海外産の動画です、一時期ツィッターで話題になってたやつ（もう〇年以上前か。。。

④新入社員用研修ビデオ「現場に出る前に」
https://www.youtube.com/watch?v=7QeDY6otG-Q

社員研修ビデオとみせかけたギャグ動画ｗ

⑤[EN/KR-sub] ホテル・カデシュ『プロジェクト：エメス』｜本編映像PART1｜全編VRSNS撮影サイバーパンク映画
https://www.youtube.com/watch?v=Sl9FyivhOG0

サイバーパンク系

⑥【メタバース映画本編】良きVRCライフをっ！【VRChat】
https://www.youtube.com/watch?v=9ZW_kRhRBbo&t=191s
リアルなの苦悩がうつってるｗ
joinして「こんにちわー」っていってもみんな「こんにちわー」といってすぐ無視するのがめっちゃリアルｗ

⑦《本編》『ラブ・バター・ラブ ～私を見つけて～』
https://www.youtube.com/watch?v=28sg9VEYyDY&t=1s

みじかめだけどおもしろかった
Vue 基礎勉強 コンポーネント

(Vue.js 3.1.5を使用)

コンポーネントの例

ボタンとテキストボックスを表示するコンポーネント
sample-componentを作成する。

```javascript:javascript
const app = Vue.createApp({
    data: () => ({
    })
})
app.component('sample-component', {
    template: '<p><button>Button</button><input type="text"/></p>'
})
app.mount('#app')
```
template:には、UIの見た目を記述できる。

```html:html
    <div id="app">
        <sample-component></sample-component>
    </div>
```



![11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/a2e34f70-0a92-7ccf-dfd1-80dc5d7ae612.png)

コンポーネントは、何度も再利用可能。

htmlに4回記述すれば、4つ表示される。
```html:html
    <div id="app">
        <sample-component></sample-component>
        <sample-component></sample-component>
        <sample-component></sample-component>
        <sample-component></sample-component>
    </div>
```
![12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/b534f4ff-9fba-ee50-e758-e77183c9b4e0.png)
MacBookPro (M3) で Docker for Mac VS OrbStack を試してみた結果



# 結論

マシンが元々高スペックだったせいか、大きな違いは感じられなかったが、たしかに少し速かった

# ObrStackとは

Docker for Mac より速いらしい
https://orbstack.dev/


# Macのスペック

M3 MacBook Pro (メモリ36GB)

# 結果

Rspec (Railsのテストフレームワーク) を全件実行してみた
( 700 テストケースぐらい )

<img width="630" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/5bea5b9f-7a12-4c7b-a9cd-03dd02546e02">

- Docker for Mac  24秒
- OrbStack 19秒

少しだけ速くなった


# ちなみに

Docker for Mac からの移行はボタン1個ですごく簡単だった

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/f411ac49-9b1d-48e8-9697-d2540ff469a4)


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
人気商品が常に陳列できる状況を作れるか考えてみた！！

# 欲しいものが売り切れていると悲しい・・・。
　こんにちは。nakadaiです！2回目の投稿ですがよろしくお願いします。
どなたでも、自分の求めるものを買い物しに行ったところ、品切れして買えなかった経験はあるかと思います。
 今回は、少しでも品切れてる状態を改善できる取組をしてみたいと思います。

 ## 本当に品切れ、売り切れなのかな？
 　品切れの場合は、少し時間が経てば陳列される可能性も高いですが、**従業員さんへ聞く勇気**のないお客さまも多いと思います。
  販売をしていて感じることは、商品の陳列状況を把握しづらいピークタイムに,
  どのように改善が出来るか考えました。
  　ピークタイムの場合大抵は、**品切れ**ではなく、手が回っていないための**品出し**が間に合ってない可能性が高いとみており、その悩みを改善します。
  　今回は、品切れ時に、すぐショーケースへ陳列できる仕組みのをテーマとして制作します。

  **作品名は！**

  # 「お知らせ君」です。
  <details><summary>使用ツール</summary>
  
・`Node RED` 

  https://flowfuse.com/
 
・`TeachableMachine` 


https://teachablemachine.withgoogle.com/


・`LINE Notify`

https://zenn.dev/dsl_gunma/articles/f29a712f9af872

**↑この記事は、本当に分かりやすい記事でした。ありがとうございます。**
</details>

### `Node RED`の配置はこの通りです。
![スクリーンショット (36).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656986/d9321280-20fa-f833-7b9b-6a56e2c0fb54.png)


**`camera`から、`TeachableMachine` を通り、`LINE Notify`へ送信する仕組みです。**
cameraで認識したもので0個の場合は、`LINE Notify`へ送信します。

# `TeachableMachine` に画像のトレーニングをしてもらう。

 まず、画像認識、商品と個数別に写真を100枚以上とり画像認識してもらう。
 PCのディスプレイ上のカメラ`のため上手に撮影するのが難しかったです。
ですが、**認識はしていただけました。**

![スクリーンショット (38)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656986/8c1c1ae5-8f7e-57d4-67b3-94a3621defc3.jpeg)

今回の撮影では、商品をトレーの上に置き8個から0個でのバージョンで撮影しました。
8個・0個の場合は100枚程度の撮影で良いのですが、**1個から7個**の場合での認識の感度を上げるために、さまざまなパターンでの撮影となり**600枚以上**は撮影しました。

　これをもとに

# いざ、LINE Notifyへ送信！
### 実装実験
 0個の写真を撮影し
　　![スクリーンショット (39).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656986/33e7e7c8-c23c-e180-a8cf-49329d0b47d3.png)
![スクリーンショット (40).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656986/e1a0c511-0e9a-0940-6f82-480b01c9bc37.png)
と、`Node RED` で認識。その後、
![Screenshot_20240124-215731 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656986/5c773a10-d7ea-d5c3-932a-0f06dcb16ce2.png)
`LINE Notify`へ送信されます。
**動画（Node REDのみ)もあるので、是非見てみてください。少し認識に時間がかかり**

https://twitter.com/nakamori315/status/1750191785945747544

## 実際、作ってみて感じたこと
### 実験の結果
　現状、お客さまにいる時間での実装は出来ておりませんが、8個から1個づつ減らし実験したところ、残り1個で判定はされました。ですが、ブザーや何か音が鳴るものを連携させないと**気付く**事が出来ない為、意味のないものとなります。最後の返信が`LINE`に届くのなら、どの端末に落とすのがBESTかを考えていきます。
 　現状だと、`camera`が見て騒いでいるだけの物ですもんね。
  店舗にあるもの**Ipad** 、**店舗にあるパソコン** 、**店内にあるカメラ機器**
  など検証します。
  
### 一緒に働く従業員さんの声
 最初は、みなさん初めに見たときは「このようなシステムがあるといいな。」との声が多かったのですので、諦めずにやり遂げます。

  ありがとうございました！
突然 docker for Mac が重くなったので Resource 設定を変えたら何故か改善した報告

# 問題

突然Dockerの起動だけ激しく遅くなった
 Macを再起動しても直らない 

# なぜか解決

Docker For Mac のResource設定でスワップ領域を最大まで上げたら何故か元に戻った その後、スワップ領域の設定をもとに戻しても改善したままだった

<img width="1032" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/163796be-8c06-44c3-b320-2c1b49a730d0">

本当に解決策だったのかどうかは不明

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
デスクトップ版TeamsでリンクがEdgeで開いてしまう件の対応

# 現象

『規定のアプリ』で『Webブラウザー』をChromeに設定している。
でもデスクトップ版TeamsのリンクをクリックするとEdgeで開いてしまう。

# 対応

『設定』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0f88cca3-09d6-6611-967e-69de0b228971.png)

『ファイルとリンク』 → 『リンクを常に開く場所』。
『規定のブラウザー』に設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/289a7e62-c652-096d-6e3f-c8470ffcb8b8.png)

# 蛇足

Outlookにも同じような設定箇所がありました。
Outlook側の設定を変更すると、デスクトップ版Teamsも同じ設定になりました。
連動してる？

# バージョン

Microsoft Windows [Version 10.0.19045.3930]
Microsoft Teams 23320.3027.2591.1505
【高卒地方エンジニア6年生】退職&転職します

## はじめに
こんにちは、はじめまして！
高卒で6年勤めた会社を2024年3月末で退職することになり、転職活動や退職を通じて感じたことを**かなり正直に**書き留めたいと思います。
ちなみに次は4月からフルリモートで東京の会社に勤めます。

## 簡単に経歴
- 高卒（情報の専門系）
- 現在24歳 社会人6年目
- 地方出身・地方在住
- Web系のSE

## 現職について
地元では一番歴史のあるIT企業です。
中小企業ですが、地方にしては規模の大きな会社で部署によって業務も働き方も全く違います。

私は主に民間の企業のWebシステム開発を担当していて、提案から保守まで一貫してやる『なんでも屋さん』的なところにいました。

SEですが外出も多くお客様とお話することが好きなため働き方としては向いていたのだとと思います。

また、入社5年目で初めて15人月ほどのプロジェクトのPMも担当させてもらいました。

## 転職のきっかけ
結果的にはいろいろな要素で悩みましたが、最初のきっかけは端的に**給与面**です。

高卒の給与水準が低く、将来的にもあまり上がる見込みがありませんでした。
かなりショックだったのは大卒の新卒より基本給が低かったことです。

数千円とはいえ、私のモチベーションを下げるには充分でした。

（学歴で任せてもらえる仕事が違ったり、
私自身が求められている水準に達していないのであれば仕方ないと納得できるのですが）

とはいえ、最初は転職エージェントに登録してみて
いいところがあれば転職しようかな～くらいのノリでした。

ちなみに6年目現在で 基本給18万／年収320万 です。
残業単価も低いので60h残業しても手取りは22万円ほどでした。

とはいえ、終身雇用を前提とした給与体制で
退職金制度もあるので合う人には合うのだろうと思います。

## 転職活動を通して感じたこと
### モダンな開発へのスキル不足
今までは井の中の蛙だったのだと痛感しました。

入社してこれまでほとんどの開発が自社FWでオンプレ。
ギリLaravelなら案件で触ったかな程度のスキル。

ReactもVueもDockerもAWSも、使ったことがありません。

すべての企業において上記のようなスキルセットがないと通用しないわけではないことは理解していますが、エンジニアとしての自分がこのままではだめだと感じました。

### 自分がやりたいこととは何か
そもそもエンジニアを続けるのか？向いていないのでは？

頻繁に技術のキャッチアップをしているわけでもない私が
今後もエンジニアを続けられるのか、自信を喪失しました。

他業種へ進むことも視野に入れましたが、
面接でこの不安な気持ちも理解した上で採用していただける企業が見つかりました。

お叱りを受けそうな甘い考えかもしれませんが
せっかく拾っていただけることになったので精一杯努めようと思います！

## 退職について
よく、結婚より離婚のほうが大変だなんていいますが、会社に置き換えても同じだなあと実感しました。

退職の意思を上司に伝えてからしばらくは毎日のように面談がありました。

面談の中で特に印象に残っている言葉たちは
「もう少し我慢してほしい」
「考えが甘い」
「絶対に管理職になれるからもったいない」
「フルリモート勤務は病むぞ」
「明日までに内定辞退してきなさい」
などなど

正直自分でも管理職になる未来は見えていたのですが、会社の方針だったり給与体制が変わらない限りは
将来の部下に私と同じような我慢を強いることになると思い、改めて退職を決意しました。

高卒で入社したということもあり、
育ててもらったのに裏切るようで申し訳ない気持ちでいっぱいでしたが
距離の近い上司ほど最後には応援してくれてありがたかったです。

## 最後に
現職は若手も少なく、SEの友人もほとんどいませんが、
もしかしたら私と同じような状況であったり不安・悩みを抱えている方がいるのではないかと思い記事を書いてみました。

余談ですが、普段からQiitaの記事は読んでいたのですがいざ自分が書くとなるとなかなか難しく、inputするのにも意識してinputしないといけないなあと感じました。

いろいろと書きましたが、今の職場には沢山の経験を積ませて育ててくれて、尊敬する先輩方にも出会えて本当に感謝しています！

4月からはフルリモート勤務になるので、
環境面やコミュニケーション面についてレポートしたいと思います！
2024/01/21 イベントレポート ~新年あけましてハンズオン祭 2024~

2024/1/21(日)にホルトホール大分にて、ハンズオン祭2024が開催されました

https://handson-matsuri.oitan.jp/
 
私は JAWS-UG おおいた代表として登壇してきました

## 開会

ハンズオン祭は6年半ぶりの開催で、今回はreboot企画となります

![IMG_0387.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/8784b9dd-20ac-dbe5-093c-0f50494c5e00.jpeg)

9:00-17:00まで、お昼休みなしというクレイジーな日程です

（私は一つだけ欠席しました🙇🏻‍♂️）

## 自分だけのChatGPTにカスタマイズしよう！〜はじめてのGPTs〜
 
渡辺さん（HOCORU）の MyGPTs ハンズオンです
 
MyGPTs は「自分でカスタマイズしたチャットボット」を簡単に作れる機能

https://accelc.co.jp/blog/chatgpt-5/

ノーコードでチャットボットが作れる！という点が最大の魅力です

しかもPDF等のファイルも読んでくれるため、結構色んなことが実現できます
 
## MetaQuest+Unityを遊ぶ
 
渋谷さん（株式会社 Digger）のAR/VRに関するハンズオンでした

今後のメタバースの市場規模拡大や、様々なVR機器の紹介、VRアプリの開発方法について話してくれました
  
現地では Eleven Table Tennis という卓球ゲームが体感できるようになっていました

https://store.steampowered.com/app/488310/Eleven_Table_Tennis/

## AWSのAIサービスをお手軽に使ってみよう
 
私の登壇です

AWSの様々なAIサービスをブラウザから試してみるハンズオンを実施しました

以下の記事からだれでも簡単に試せます（AWSアカウントは必要=クレジットカード必須）

https://qiita.com/RyoWakabayashi/items/d8c7f57a71e83d9140d5
 
## はじめてのFlutter
 
本田さん（株式会社QoX）から、Flutter のハンズオンです

Flutter はモバイルアプリ、Web、デスクトップアプリまで開発できるフレームワークです

DartPad という環境で、簡単に Flutter を体験することができました
 
https://dartpad.dev/
 
## マイコンでお手軽IoT
 
豊住さん（ファブラボ大分）のマイコンボードと温湿度センサーを使って、IoT体験ができるハンズオンです

すみません、このハンズオンだけ欠席しました🙇🏻‍♂️

https://www.faboita.org/
 
## Pythonでベイズ推論
 
賀川さん（大分大学）による Python でのベイズ推論視覚化です

ベイズ推論はE資格の勉強で出てきました
 
徐々に推定の精度が高くなる様子が、グラフでキレイに表されました

## はじめてのDuet AI
 
山田さん（GDG Cloud Oita）の AIアシスタントハンズオンです

Google Workspace というオンライン開発環境上で、 Duet AI によるプログラミングの補助を体験しました

Duet AI は GitHub Copilot と同じような、コーディングに特化した生成AIです

GitHub Copilot とおおよそ同じようなことができ、価格帯もおおよそ同じです
 
https://cloud.google.com/duet-ai/?hl=ja
 
2月1日までは無料で試せるらしいので、気になる方は急いで試しましょう
 
## Cloudflare Pagesで自分だけのWebサイトを公開しよう！！
 
阿部さん（Cloudflare Meet-up Oita, JAWS-UG）の Cloudflare ハンズオンです

https://twitter.com/nakaji573/status/1748966347424555259

無料、しかもクレジットカード登録不要で Web ページが公開できました

GitHub リポジトリーからの CD がほぼ自動で構成されます

みなさん使ってみましょう！
 
そして 2/10(土)のイベントにも参加しましょう！

https://cfm-cts.connpass.com/event/307368/
 
## LT
 
LT = ライトニングトーク（短時間のプレゼン）も実施しました
 
### 柴尾さん
 
AWS の生成AIサービス BedRock によるチャットボットが無料で作れるサービス

PartyRock の紹介です
 
https://partyrock.aws/

### 都留さん
 
ChatVRM という、VRキャラクターにAIで喋らせるオープンソースプロジェクトを紹介してくれました

無償でここまで出来るのはすごい！
 
https://github.com/pixiv/ChatVRM
 
### 佐藤さん
 
LoRaであればアマチュア無線の免許がなくても通信できるので、是非LoRaで通信しましょう！とのこと

LoRaは低消費電力なので、先日の大地震のような災害時にも通信できる可能性が高く、災害対策にも使える

開催しているイベントや飲み会の紹介もありました

https://www.facebook.com/sdmm.suidon/?locale=ja_JP

大分でエンジニアが交流している空間を知らなかったので、これは意外でした

### 若林（本日二度目）

Livebook を紹介しました

ブラウザ上でコードができて、しかもアプリまでデプロイできる優れものです

https://qiita.com/RyoWakabayashi/items/9cd0032d1bd4ddad5d6c

## まとめ

それぞれ多種多様なハンズオンばかりで非常に面白かったです！

今後も色々なイベントに参加してみようと思います！
Outlookでメール本文のリンクがEdgeで開いてしまう件の対応

# 現象

『規定のアプリ』で『Webブラウザー』をChromeに設定している。
でもOutlookでメール本文のリンクをクリックするとEdgeで開いてしまう。

# 対応

『プロパティ』 → 『詳細設定』 → 『Outlookからハイパーリンクを開く場所』。
『規定のブラウザー』に設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/72ffd1ee-f99a-2e66-7e36-15d2ba202f61.png)

# 参考サイトさん

https://support.ntt.com/office365/faq/detail/pid2300001j0n/

# バージョン

Microsoft Windows [Version 10.0.19045.3930]
Microsoft Outlook for Microsoft 365 MSO (バージョン 2312 ビルド 16.0.17126.20132) 32 ビット
Git[Hub|Lab] の PR/MR でコードへのリンクを埋め込む方法

良く忘れがちなので自分用メモ的な感じ

# この記事は何?

通常、PR/MRでのコードレビューではコードを開いてそこにコメントを入れていくのでそれほど使う機会はないのですが、稀にコメントなどからコードを指したい時があり、その時の書き方をメモ

# GitHub では

GitHubの場合、この[公式のヘルプ](https://docs.github.com/ja/get-started/writing-on-github/working-with-advanced-formatting/creating-a-permanent-link-to-a-code-snippet)に従って permalink を取得し、それを使って markdownリンクとして書けば OK。相対リンクはうまくいかないっぽいので、やり方知っている人は教えてください。

なお、コピーした permalink 見れば一目瞭然ですが、複数行を指す場合は GitLab と違って `#L[行番号]-L[行番号]` という書き方（`L`が挟まってる）なのに注意。

# GitLab では

GitLab の場合は相対リンクで書けます

## 単一行を指す場合

`[表示テキスト](../[ブランチ名]/[ファイルへのパス]/[ファイル名]#L[行番号])`

## 複数行を指す場合

`[表示テキスト](../[ブランチ名]/[ファイルへのパス]/[ファイル名]#L[行番号]-[行番号)`

# 最後に

GitHub でも相対リンクで書ければいいんですけどねぇ...
【Oracle Analytics】直接データベース問合せの作成 

## OracleAnalyticsでSQLを書いてレポートを作成する機能を使ってみました。
以下、実施した手順を記載します。

作成＞分析　を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683119/42d7fd48-6655-cfde-f3ac-e2504f4e95fe.png)


サブジェクト領域の選択画面の下部より「直接データベース問合せの作成」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683119/956e713e-9d51-2232-8618-7cc441fd64fe.png)


以下の分析（アンサー）の基準タブの画面に遷移する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683119/10a74bac-b842-6cf6-e039-86e1d1bbaf9a.png)
上記のキャプに黄色背景で示した以下の3点について設定する
①「接続プール（接続先DB情報）」を記載する
②「SQL文（分析で実行するSQL）」を記載する
③「SQLの確認と列の取得」ボタンを押す


## ①「接続プール（接続先DB情報）」を記載する
接続プールはrdpファイルの接続プールを記載
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683119/a710a65d-9427-eabe-2817-ed5b1c46da52.png)

## ②「SQL文（分析で実行するSQL）」を記載する
SQL文には実行したいSQLを記載する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683119/6216f29d-1abc-c575-c20d-946b53f6fa14.png)
SQL文の使用可能なテーブルは物理層にインポート済みテーブル、接続プールに記載しているDBに作成済みのテーブルとなる。

## ③「SQLの確認と列の取得」ボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683119/78176f85-35c1-5710-07d5-7b986e2ef652.png)
「接続プール」、「SQL文」の内容の変更後は、必ず「SQLの確認と列の取得」のボタンをクリックする。（※変更後の内容を反映させる意図がある）
ボタンを押下後にエラーが発生する場合はエラーメッセージを参考に「接続プール」または、「SQL文」の修正を行う。



## 基準タブ　設定後の画面
SQL文のSELECT項目が結果列に表示されている（赤枠部分）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683119/ca80d275-765c-d864-4327-9347cc248c90.png)


またSELECT項目の左のアイコンを選択すると、通常の設定の「列のプロパティの設定」も可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683119/8302d48a-9fc3-c30c-e449-6f6bacfb44d4.png)
「現代数理統計学の基礎」演習問題解法メモ　第4章問19～23

第4章はこれで終わります。
問22(1)の積分範囲(青ペン記述部)がなかなか腑に落ちません。
問22(4)も難問ですね。
問23(2)もよくわからず「とけたろう」を参考にしました。準1級統計学実践ワークブックP72「多項分布の差の信頼区間」では、1行で導出していましたが、さっぱりわからず、問23(2)でこんなに大変だったとはです。![第4章問19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/184712d7-02b7-e823-c41e-087492e1f1af.jpeg)
![第4章問20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/c0c53d0d-9828-e204-6fe2-e40dd9ddc191.jpeg)
![第4章問21 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/e667b05d-b4f9-7d18-0f8a-5c3a199ab4ca.jpeg)
![第4章問21 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/efab8d45-c118-3f32-8ede-72abe4835f86.jpeg)
![第4章問21 P3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/21568bb5-3e07-7c70-8290-5f622759e659.jpeg)
![第4章問21　P4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/edbe0aeb-9d75-b975-7995-839d3d953ce7.jpeg)
![第4章問22 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/18e693c6-4594-7494-42d8-48f2e642b91e.jpeg)
![第4章問22　P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/4d7e5ef1-c91e-f656-25d7-bce0a37e5bb6.jpeg)
![第4章問22 P3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/258f2a9b-9f2c-dc31-daea-769da8ddca83.jpeg)
![第4章問22 P4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/1e72ea95-1207-b247-39e4-6bd594dfa387.jpeg)
![第4章問22　P5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/111eeb4d-fe06-e92a-c449-2022113c43bf.jpeg)
![第4章問23 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/0f777fd2-3d69-5d04-5202-f0369685cb6d.jpeg)
![第4章問23 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/b82090d0-7766-7a50-280d-971e1a8a31b2.jpeg)
DockerのMySQLで実行したSQLをログ出力させる

DockerのMySQL(mysql5.7.26)で、実行したSQLをログ出力させることに少々苦戦したので方法を共有します。
どれだけ需要があるか分からないですが一応。。

### 先に結論
`my.cnf`に以下を追加して、mysqlを再起動する。
```
[mysqld]
general_log=1
general_log_file=/var/log/mysql/myquery.log
```
自分の環境の`my.cnf`は以下のようになりました。
``` ini
# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

[mysqld]
general_log=1
general_log_file=/var/log/mysql/myquery.log
```
いくつかハマったポイントがあったので、それも記載しておきます。

### ハマりポイント1：my.cnfの場所
ネットで「mysql sqlログ出力」と検索したら`/etc/my.cnf`にログ出力するように追記すると書かれていたので
``` shell
ls -l /etc/my.cnf
```
とやったところ、そんなファイル無いと怒られました。。
なので`find`で探してみたら複数出てきたのでどれ？？となり、
``` shell
find -name my.cnf
./var/lib/dpkg/alternatives/my.cnf
./etc/alternatives/my.cnf
./etc/mysql/my.cnf
```
さらに検索したところ、以下の記事が見つかりました。
[MySQLで読み込まれる設定(my.cnf)の場所はどこ？](https://codelikes.com/mysql-cnf-file-path/)
書かれているコマンドを実行した結果がこちら。
``` shell
mysql --help | grep my.cnf
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf 
```
ということで、今回の環境だと`/etc/mysql/my.cnf`を見ていることが分かりました。

### ハマりポイント2：コンテナ内にvimがない(viもなかった)
マジか！？と思いつつインストールしたらエラーになり入れられず。。
``` shell
apt install vi
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package vi
```
これを解決するのは面倒そう＆本筋じゃないということで、ローカル環境で必要部分を追記した`my.cnf`を作成して、コンテナにコピーしました。
``` shell
docker cp ./my.cnf local-db-1:/etc/mysql/mysql.cnf
docker restart local-db-1
```
### ハマりポイント3：追記する文字列の正解が不明
ネットで検索した記事だと、ログ出力の定義を追記するグループが`[mysqld]`と`[mysql]`派が混在していたり、`general-log=1`(ハイフン)と`general_log=1`(アンダーバー)派が混在していたりで何が正しいのかがよく分からなかったです。
とりあえず一つ一つ試してみるという原始的な対応で解決しました。
途中でコンテナが再起動しなくなってしまった時があり、`docker-compose down`で落として作り直ししたり。。
この辺はDockerだと気楽ですね。
Teams Admin CenterにBotマニフェストをアップロードしたときのエラー原因確認

# 目的

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022607/29aa12b7-8c98-7da5-da41-3962b6bcb1f0.png)

Teams Admin Center（Teams管理者センター）で組織向けにAzure Botマニフェスト（zipファイル）をアップロードしたところ `Mgmt.AppCatalog.LOBApp.Upload.BadRequest.Error` とだけ表示されるエラーが表示されたので、エラーの原因を探りたい。  

# エラーの原因確認

マニフェストファイル（zip）をアップロードする前にデベロッパーツールのネットワークタブを開いてから、ファイルをアップロードする。  
おそらくリクエストのいずれかがエラーになっているので、そのリクエストのレスポンスを確認する。
レスポンスには下記が帰ってきており、 `filename` が `null` であることが原因だったとわかりました。

```json
{
    "error": {
        "code": "BadRequest",
        "message": "Value cannot be null. (Parameter 'filename')",
        "innerError": {
            "code": "UnknownTeamsAppManifestExceptionType",
            "message": "Value cannot be null. (Parameter 'filename')",
            "details": [],
            "date": "2024-01-25T00:16:44",
            "request-id": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "client-request-id": "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
        }
    }
}
```

# エラーを解消する

`filename` が `null` でないようにすればよいとわかりましたが、Microsoft Teams マニフェストスキーマを確認したところ、 `filename` というパラメータは存在していませんでした。

> [マニフェスト スキーマの参照 \- Teams \| Microsoft Learn](https://learn.microsoft.com/ja-jp/microsoftteams/platform/resources/schema/manifest-schema)

いろいろ試しましたが、 `manifest.json` のスキーマバージョン指定を `1.15` から `1.13` に変えたり、 `icons.outline` と `icons.color` の指定ができていなかったのでテンプレートで自動生成されたpngファイルを指定しておくとアップロードができました。

```json:manifest.json
{
  "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.13/MicrosoftTeams.schema.json",
  "manifestVersion": "1.13",
  <略>
  "icons": {
    "outline": "icon-outline.png",
    "color": "icon-color.png"
  },
  <略>
}
```

レスポンスのエラー内容とは関係ない部分を直してアップロードの不具合が解消しましたが、エラー内容自体ももしかしたら間違っていたのかもしれません。

# 参考

> [Debug error uploading manifest to Teams Admin portal\. \- YouTube](https://www.youtube.com/watch?v=6gm92rOvQTU)
特定の文字列を含む行のみを対象に、大文字を小文字に変換するテクニック


特定の文字列を含む行だけ、大文字を小文字にしたいとき、エディタで行うのは非効率です。
そんなとき、`sed`が便利です。macの場合にはGNU版を入れてからgsedコマンドを呼び出します。

GNU版のsedをmacにインストール

```sh
$ brew install gnu-sed
```

今回はこのような置換を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19199/8f9126a3-e398-24a9-83d4-98dac3f1e6cd.png)

上記の例は、このコマンドで書き換えた結果です。
`-i`オプションの後ろに文字列を指定すれば、バックアップファイルが作れます。

```shell
$ gsed -i '/name:/ s/[A-Z]/\L&/g' models/metering/models.yml
```

特定の文字列より後ろだけ小文字にしたい時もあります。
gsed（GNU版のsed）で行の最後で宣言される"AS"の後ろだけを小文字に置換する例は次の通りです。

![Pasted_Image_2024_01_26__14_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19199/2d309417-cd38-bae8-980c-eda708dcad32.png)

今回は、複数ファイルを対象に一括で置換しています。
```shell
# 対象のファイルを * 付きで指定しているので、複数ファイルを一括で置換できます
# -i オプションを足すとファイルを上書きできます
$ gsed -E 's/(.+)(AS )([^[:space:]]+)/\1\2\L\3/g'  models/metering/*.sql
```

なかなか便利なコマンドだったと思います。置換の作業を効率化できましたね！
【JavaScript】setTimeout(fn, 0)の遅さが分かるサイト


## 発端

https://qiita.com/mashuel/items/69b00b33961aa914f7fc

こちらの記事を読んだとき、未知との遭遇でよく分からなかったのだが、調べるとクソ重い処理をUIがフリーズしない程度にちょくちょく実行する方法として`setTimeout(fn, 0)`というものがある。ということを知った。

そして、`setTimeout(fn, 0)`は遅いらしいので他のアルゴリズムと比較したいと思った。

## 比較

1から100000までの和を求めてもらう。

![setTimeout0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/d7a3292d-1a49-f7e7-c836-cfccc20f0ccd.gif)

おわかりいただけただろうか。

https://mogamoga1024.github.io/setTimeout0like/

## 比較に使わせていただいたアルゴリズム

https://dbaron.org/log/20100309-faster-timeouts

https://qiita.com/mashuel/items/69b00b33961aa914f7fc
paizaレベルアップ問題集 標準出力メニュー【行によって長さが違う二次元配列の表示】FINAL問題 すべての行の長さと値が不定な 2 次元配列の出力 (paizaランク B 相当) 解答例

PHPで回答。コード公開可とのことなので復習も兼ねて共有します。
[問題文](https://paiza.jp/works/mondai/stdout_primer/stdout_primer__variable_array_boss "paiza.jp/works/mondai/stdout_primer/stdout_primer__variable_array_boss")
## 解答例1
```php
<?php
    [$n, $m] = explode(" " , rtrim(fgets(STDIN))); //配列の短縮記法により複数の変数に一括代入
    $array_a = explode(" " , rtrim(fgets(STDIN))); //配列A
    $array_b = explode(" " , rtrim(fgets(STDIN))); //配列B
    
    $index = 0; //配列Aから要素を1つずつ取り出すためのインデックス番号
    foreach($array_b as $b){
        for($i = 0; $i < $b; $i++){ //各要素について$b(M)回for文を回す
            echo $array_a[$index]; //変数$indexはforeachの外にあるのでリセットされない
            if($i + 1 == $b){ 
                echo "\n"; //行の終点なら、改行する
            }else{
                echo " "; //行の終点でなければ、半角スペースを出力
            }
            $index += 1; //インデックス番号を更新
        }
    }
?>
```
## 解答例2
```php
<?php
    [$n, $m] = explode(" " , rtrim(fgets(STDIN))); //一括代入
    $array_a = explode(" " , rtrim(fgets(STDIN))); //配列A
    $array_b = explode(" " , rtrim(fgets(STDIN))); //配列B
    
    $start = 0; //行の始点を設定
    for($i = 0; $i < $m; $i++){ //for文をM回（配列Bの要素数分）回す
        $end = $start + $array_b[$i] - 1; //行の終点を設定（最初は配列Bの1つ目の要素数、インデックス番号と比較するため-1）
        for($j = $start; $j <= $end; $j++){ //行の始点（最初は0）から終点まで
            echo $array_a[$j]; //配列Aから1つずつ要素を取り出し出力していく
            if($j < $end){
                echo " "; //行の終点でなければ、半角スペースを出力
            }else{
                echo "\n"; //行の終点ならば、改行する
            }
        }
        $start = $end + 1; //始点を更新
    }
?>
```
SvelteでWritable<T>のTの型を取得する

## 概要
```ts:ProviderIsOnline.svelte
  export type ContextIsOnline = Writable<boolean>
```

```svelte
<script lang="ts">
  import type { ContextIsOnline } from '...';
  export let isOnline: XXXXX // ここ
</script>
<ProviderIsOnline {isOnline}>
  <slot />
</ProviderIsOnline>
```

`XXXXX`の部分で`Writable<boolean>`ではなく`boolean`が欲しい時があります。
この例だと初期値をbooleanで受け取って、Contextで渡すのはwritable store って感じです。

### StoresValuesを使う
```svelte
<script lang="ts">
  import type { StoresValues } from 'svelte/store';
  import type { ContextIsOnline } from '...';
  export let isOnline: StoresValues<ContextIsOnline>
</script>
<ProviderIsOnline {isOnline}>
  <slot />
</ProviderIsOnline>
```

`StoresValues`という型が用意されています。

今まで遭遇しなかったのであることをしりませんでした。
自分でいちいち自分で型を作らなくても用意されているのは助かりますね。
Becoming An Electrical Engineer – Steps To Know, Career Scope And Salary

Most common, and useful devices of today’s modern life use electricity, which is a form of energy. Thanks to the electrical engineers for making our lives so comfortable and convenient. If you are interested in an engineering stream after your 10th, know of the popular electrical engineering branch among the engineering courses in Tamilnadu.

What is electrical engineering?

Electrical Engineering deals with designing and developing new electrical systems and embraces physics, and mathematics along with knowledge of electricity, electromagnetism and electronics. This understanding helps in creating, implementing, and testing systems helpful in processing and transmitting energy.

Steps to become an electrical engineer

1. Choose the right stream

Once you complete 12th, join the electrical engineering field at the top College inVillupuram.

2. Grow your skills

Apart from your academic learning, you should also focus on grooming your skills in circuit design and analysis, instrumentation and electrical measurements, Knowledge of computers and design, Circuit Knowledge and ability to solve complex problems.

3. Find work experience

After pursuing electrical engineering, you can choose either an internship via your Engineering college or you can apply for jobs and gain work experience. Most industries are offering job opportunities for freshers as apprenticeships. These job opportunities are ideal chances to develop your work experience and propel your growth towards higher roles in the industries.

Career scope and Pay scales

●      The average salary that can be expected for a Junior Electrical Engineer (for below three years of experience) is Rs.1,85,500 per annum.

●       The typical pay scale for a mid-career Electrical Engineer (4-9 years of experience) is Rs.3,66,700 per annum.

●      A Senior Electrical Engineer (10-20 years of experience) can earn up to Rs.6,32,600 per annum.

Your electrical engineering qualification empowers you to get placed in varied industries such as power and renewable energy, transport, construction and manufacturing and more. Electrical engineering specialization is assured with a global impact that allows candidates to shine across the world. They can contribute to the environment via solutions that preserve energy.

The above things indicate the demand for electrical engineering courses in the Villupuram Engineering College
Intel X520-da2のベンダーロックを解除する

## はじめに
先日，自宅のネットワーク環境を10GbEにするために，中古のX520-da2を某オークションにて購入しました。

安かったので深く調べずに落札してしまいましたが，よくよく調べてみるとベンダーロック(IntelのSFP+モジュールでしか動作しない)が掛かっているらしいのです。すでにCiscoのモジュールを購入してしまったので困りました。

## 解決策
ただ，同じIntelのチップを採用している他社(HPEとか)のNICだとベンダーロックが存在しないとの情報があり，ファームウェア的なものを書き換えればロック解除できそうと思って調べたところ，ロックを解除する方法を発見しました。ethtoolを使ってNICのEEPROMの特定のbitを書き換えることでロック解除できるようです。

丁度githubにそれ用のスクリプトがあったので使わせていただきました。

[intel_x520_patcher.py](https://gist.github.com/ixs/dbaac42730dea9bd124f26cbd439c58e?permalink_comment_id=4639253#gistcomment-4639253)

sudoで上のスクリプトを実行し再起動すればベンダーロックが解除出来き，Ciscoのモジュールも認識しました。
Google ColabでSAM(Segment Anything Model)モデルを使ってみる

## 事前準備
ColabをPython3とGPUを使うように設定します。  
編集-ノートブックの設定-ランタイムのタイプ-Python3  
編集-ノートブックの設定-ハードウェア アクセラレータ-GPU  
というふうに設定します。
データ管理をやりやすくするために、ルートディレクトリをHOME定数にします。
```shell
import os
HOME = os.getcwd()
```
## SAMと依頼をインストールする
```shell
!pip install -q 'git+https://github.com/facebookresearch/segment-anything.git'
!pip install -q jupyter_bbox_widget dataclasses-json supervision
```
## 重みをダウンロードする
```shell
!mkdir -p {HOME}/weights

!wget -q https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth -P {HOME}/weights
import os
CHECKPOINT_PATH = os.path.join(HOME, "weights", "sam_vit_h_4b8939.pth")
print(CHECKPOINT_PATH, "; exist:", os.path.isfile(CHECKPOINT_PATH))
```
## データを用意する
```shell
!mkdir -p {HOME}/data
```
**Webから画像ダウンロード**
```shell
!wget -q [webからの画像リンクhttps://xxx/xxx.jpg]
```
**ローカルから画像アップロード**
```shell
from google.colab import drive 
drive.mount('/content/drive') 
%cd /content/drive/MyDrive
```
ローカルの画像をGoogle Driveにアップロードして、`cp`コマンドで`/content/data`にコピーして、次のステップに入ります。

## SAMをロードする
```shell
import torch
DEVICE = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
MODEL_TYPE = "vit_h"

from segment_anything import sam_model_registry, SamAutomaticMaskGenerator, SamPredictor
sam = sam_model_registry[MODEL_TYPE](checkpoint=CHECKPOINT_PATH).to(device=DEVICE)
```

## 自動的マスク生成
マスク自動生成するには、SAMモデルに `SamAutomaticMaskGenerator` クラスを提供する。 
SAMチェックポイントを以下のパスにする。 
CUDAでデフォルトモデルを実行するのが推奨される。
```
mask_generator = SamAutomaticMaskGenerator(sam)

import os
IMAGE_NAME = "test3.png"
IMAGE_PATH = os.path.join(HOME, "data", IMAGE_NAME)
```

## SAMでマスクを生成する
```
import cv2
import supervision as sv
image_bgr = cv2.imread(IMAGE_PATH)
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
sam_result = mask_generator.generate(image_rgb)
```

## 出力結果を可視化する
```
mask_annotator = sv.MaskAnnotator(color_lookup=sv.ColorLookup.INDEX)
  
detections = sv.Detections.from_sam(sam_result=sam_result)
  
annotated_image = mask_annotator.annotate(scene=image_bgr.copy(), detections=detections)

sv.plot_images_grid(
    images=[image_bgr, annotated_image],
    grid_size=(1, 2),
    titles=['source image', 'segmented image']
)
```

## セグメント結果出力
```
masks = [
    mask['segmentation']
    for mask
    in sorted(sam_result, key=lambda x: x['area'], reverse=True)
]

sv.plot_images_grid(
    images=masks,
    grid_size=(8, 40),
    size=(16, 16)
)
```
Node-RED（Watchノード）におけるファイル削除を検出しないための設定手順

この手順の目的は、Node-REDでWatchノードとFunctionノードを使用して、ファイルシステムの変更を監視し、特定のイベント（例えばファイルの更新）にのみ反応させることです。Watchノードはファイルの作成、変更、削除を検出しますが、これらのイベントを区別することはできません。しかし、Functionノードを使用してJavaScriptコードを書くことで、ファイルが存在するかどうかをチェックし、存在しない場合（削除された場合）は処理を進めないようにすることができます。

### 設定の操作手順

1. **settings.jsファイルを見つける**
   - `/home/user/.node-red/`ディレクトリにある`settings.js`ファイルを探します。

2. **settings.jsファイルを編集する**
   - テキストエディタで`settings.js`ファイルを開きます。
   - `functionGlobalContext`プロパティを見つけ、以下のように`fs`モジュールを追加します。

     ```javascript
     functionGlobalContext: {
         // 既存のグローバル設定があれば、それを保持
         fs: require('fs')  // fsモジュールを追加
     },
     ```

3. **Functionノードでのfsモジュールの使用**
   - Node-REDのFunctionノード内で、以下のJavaScriptコードを使用して`fs`モジュールを活用します。

     ```javascript
     const fs = global.get('fs');

     // Watchノードからの入力メッセージを取得
     const filePath = msg.payload;

     // ファイルが存在するかチェック
     if (fs.existsSync(filePath)) {
         // ファイルが存在する場合（更新された場合）、メッセージを次のノードに送信
         return msg;
     } else {
         // ファイルが存在しない場合（削除された場合）、何もしない
         return null;
     }
     ```

この設定により、Node-REDでのファイルシステムの監視がより柔軟になり、特定のタイプのイベントにのみ反応させることが可能になります。
一歩先行くDIY！PythonとArduinoで作るカスタムLEDコントロールシステム

## はじめに

この記事では、Pythonを使用してArduinoのGPIOピンから出力を行う方法をわかりやすく説明します。

## やりたいこと

目指すのは、PythonでGUIボタンをクリックすることでArduinoボードにトリガー信号を送り、特定のピンからHighレベル（5Vまたは3.3V）の信号を出力させることです。この信号はLEDを用いて視覚的に確認します。PythonはPC上で実行し、ArduinoはUSBケーブルを通じてPCに接続されます。

## 必要なもの

1. Arduinoボード (例：Arduino Uno)
1. LED と抵抗
1. USBケーブル (ArduinoをPCに接続)
1. Arduino IDE (Arduinoプログラムを書くため)
1. Python (Pythonスクリプトを実行するため)
1. PySerialライブラリ (Pythonからシリアル通信を行うため)

## Arduino スケッチの準備
Arduino IDEを開き、新しいスケッチを作成します。

1. トリガーを受け取り、指定されたピンをHIGHに設定するコードを書きます。
1. 例えば、ピン13にLEDを接続している場合は以下のようになります。
1. スケッチをArduinoボードにアップロードします。

```cpp:
void setup() {
  pinMode(13, OUTPUT); // ピン13を出力モードに設定
  Serial.begin(9600);  // シリアル通信の開始
}

void loop() {
  if (Serial.available() > 0) { // シリアルポートでデータが利用可能かチェック
    char data = Serial.read(); // データを読み込む
    if (data == '1') {
      digitalWrite(13, HIGH); // ピン13をHIGHに設定
    } else if (data == '0') {
      digitalWrite(13, LOW); // ピン13をLOWに設定
    }
  }
}

```
## Pythonスクリプトの作成
### 1. 基本コード 

1. Pythonスクリプトを作成し、PySerialを使ってArduinoと通信します。
1. 以下はPythonスクリプトの基本的な例です。

```python
import serial
import time

# シリアルポートの設定（ポート名は環境によって異なる）
ser = serial.Serial('COM3', 9600) # Windowsの場合
# ser = serial.Serial('/dev/ttyACM0', 9600) # Linuxの場合
# ser = serial.Serial('/dev/tty.usbmodem14201', 9600) # macOSの場合

time.sleep(2) # Arduinoとの接続が安定するまで待機

# LEDを点灯
ser.write(b'1')

time.sleep(10) # 10秒間点灯

# LEDを消灯
ser.write(b'0')

ser.close() # シリアルポートを閉じる


```

**注意点**
1. シリアルポート: Arduino IDEのツールメニューで使用しているシリアルポートを確認し、Pythonスクリプトのserial.Serialで指定するポートを合わせてください。
1. 通信速度: ArduinoスケッチとPythonスクリプトの両方で同じボーレート（この例では9600）を設定してください。
1. 接続の安定化: PythonスクリプトでArduinoとの接続後、少し待機することで通信が安定します。
これで、PythonからArduinoにトリガーを送り、LEDを制御するシステムが完成します。

### 2. GUIコード 

Tkinterを使ってGUIボタンを作成し、そのボタンを押すとArduino経由でLEDが10秒間点灯するPythonスクリプトを作成します。以下はその基本的なコードです。

```python
import tkinter as tk
import serial
import time

def toggle_led():
    ser.write(b'1')  # LEDを点灯
    window.after(10000, lambda: ser.write(b'0'))  # 10秒後にLEDを消灯

# シリアルポートの設定（環境に応じて適宜変更）
ser = serial.Serial('COM3', 9600)  # Windowsの場合
# ser = serial.Serial('/dev/ttyACM0', 9600) # Linuxの場合
# ser = serial.Serial('/dev/tty.usbmodem14201', 9600) # macOSの場合

time.sleep(2)  # Arduinoとの接続が安定するまで待機

# Tkinterウィンドウの作成
window = tk.Tk()
window.title("LED Control")

# ボタンの作成
button = tk.Button(window, text="LEDを点灯", command=toggle_led)
button.pack(pady=20)

# ウィンドウのメインループ
window.mainloop()

# ウィンドウを閉じたらシリアルポートを閉じる
ser.close()
```

## 実行結果

以下の画像とGIFは、上記のスクリプトを実行した際の結果を示しています。Pythonを用いたGUIからArduinoボードへのトリガー送信により、LEDの点灯と消灯が正常に行われることが確認できます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/93883c1f-ac9b-1e99-b20a-0719ac7bd57a.png)


![ezgif-7-bd0025f62f.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/4a8fc01a-703c-b198-7032-5b4cb115e1cc.gif)
しりとり

Rubyでしりとりプログラムを作成しました。

```Ruby
# しりとりプログラム
# 名鉄でんちゃん
#  2024/1/25
# データ数を入力する
def error_msg()
  puts "正の整数を入力してください"
end

def correct(num1,num2)
  if num1 == num2 then
    puts "Yes"
  end
end

puts "正の整数を入力してください"
while true
  data1 = gets.chomp
  begin
    num = data1.to_i
    if num < 1 then
      puts "1未満の整数が入力されています"
      error_msg()
    else
      break
    end
  rescue
    error_msg()

  end
end

a_str = ""
b_str = ""
count = 1
for i in 0...num do
    puts "文字を入力してください"
    data2 = gets.chomp
    N = data2.length
    a_str = data2[0]
    #puts a_str
    if i == 0 then
        b_str = data2[N-1]
    else
        if a_str == b_str then
            #puts count
            b_str = data2[N-1]
            count += 1
        else

            output_b_str = b_str
            output_a_str = a_str
            msg = output_b_str + " " + output_a_str
            puts msg
            break
        end
    end
end

correct(num,count)
```

成功例
![paiza1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710584/11a57742-7a0e-4b60-81c1-8c3884be205f.jpeg)

失敗例
![sippai.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710584/c934bc4c-89b9-4f1e-50ca-10fc996ba46e.jpeg)
【Amazon RDS】コミュニティサポート終了期間とRDS標準サポート終了期間の違い

AWSのRelational Database Service（RDS）を利用する際、データベースのサポートポリシーを理解することは非常に重要です。
特に、コミュニティサポート終了期間とRDS標準サポート終了期間の違いを把握することは、セキュリティと運用の効率に直結します。

## コミュニティサポート終了期間（Community Support End of Life, EOL）

コミュニティサポート終了期間は、オープンソースのデータベースプロジェクト（例：MySQL、PostgreSQL）のコミュニティがそのバージョンのサポートを終了する時期を指します。
この時期が過ぎると、新機能の追加やセキュリティパッチの提供が行われなくなります。
AWS RDSはこれらのバージョンを利用しているが、直接的にはAWSの管理下にはありません。

## RDS標準サポート終了期間（RDS Standard Support End of Life, EOL）

RDS標準サポート終了期間は、AWSが特定のRDSデータベースエンジンバージョンに対して提供するサポートの期間です。この期間内、AWSはセキュリティパッチの提供、トラブルシューティング、パフォーマンス最適化などのサポートを行います。標準サポート期間が終了すると、そのバージョンに対するAWSのサポートも終了します。

## どちらが重要か？

AWS RDSを使用する上で最も重要なのは「RDS標準サポート終了期間」です。この期間内には、AWSからの継続的なサポートとセキュリティ保証があります。サポート終了が近づくと、AWSはバージョンアップグレードを推奨し、適切なアップグレード計画を立てることが重要です。一方、コミュニティサポート終了期間も無視できませんが、RDSの運用においてはAWSの標準サポートがより優先されます。
Power Automate で Outlook の添付ファイルと埋め込み画像を識別してファイルを保存する


# はじめに

Power Automate で処理を自動化する際、Outlook で受信したメールの添付ファイルを他の場所に保存したいケースがあると思います。

しかし、以下のように、添付ファイルとは別に、メール本文に画像等が埋め込まれている際、意図せず、こちらの画像も保存されてしまいます。

※意図的に画像を埋め込んでいない際以外にも、会社のロゴ等が署名に埋め込まれているようなこともあると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/cab0161e-d83d-3a44-4e26-ab85c7cd6a80.png)

なぜこのようなことが起きるかというと、実は、こういった埋め込んだ画像について、内部的には添付ファイルとして扱われているためです。

そのため、今回は、Power Automate で、この埋め込んだ画像と添付したファイルを識別して保存するアプローチについて紹介します。

# アプローチ

まず、実際にテストで上記のようなメールを送ってみて、Power Automate を実行し、比較をしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b42245bc-32b3-3f5c-f168-4d238a26eccc.png)

こちらの`[IsInline]`辺りが怪しいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/c3fdc24a-32c8-a7ee-5db9-dc3cbcc606b8.png)

調べてみたところ、こちらで判別して問題なさそうです。

https://learn.microsoft.com/ja-jp/graph/api/resources/fileattachment?view=graph-rest-1.0

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/82ec4e57-c73a-e75d-cfab-13e68c29fd04.png)

:::note warn
最初は、contentId でも識別できるかなと思っていましたが、上記の通り、Power Automate の"新しいメールが届いたとき"アクションでは、contentId については取得していなさそうでしたので、`[IsInline]`で判別することにしました。
:::


こちらを元に、以下のようにして条件分岐をして埋め込んだ画像を除外して添付ファイルを保存するようにしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/8e07619c-6be8-cfc7-e373-22824203d201.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/e4218f89-4d42-c74c-a66c-eff3df90f6cf.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/1aa8b107-e13d-f681-2099-3c650619f2eb.png)

テストしてみました。無事に添付ファイルだけ保存できたようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/97516e53-f8dc-df0f-0201-df26c8342ae0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/698b28ba-58ad-acca-5058-2e241ddbbc6c.png)

# まとめ

Power Automate で Outlook の添付ファイルと埋め込み画像を識別してファイルを保存するアプローチについて紹介しました。メールの添付ファイルを保存する際、本文に埋め込まれた画像等は保存したくないケースはあると思うので、参考になれば幸いです。
M.2 SSDとNVMeについて

### M.2 SSDとNVMeについて少し調べた
- M.2

M.2はSSDの接続端子(差し込み側)の規格だよ。
基盤が剥き出しになっているのが特徴。
M.2 SSDは転送速度の速さが特徴だが、転送速度が早いのはPCI-e(NVMe)接続を採用しているものに限る。
SATA接続を採用した製品もあり、その場合はSATA接続の2.5インチSSDと同等の転送速度しか発揮できない。

- NVMe(Non-Volatile Memory Express)

NVMeはフラッシュメモリの通信を最適化するために開発された転送プロトコルのこと。
フラッシュストレージデバイスをPCI Express（PCIe）に接続するための新しい標準規格。

従来のHDD(SATA)の転送はAHCI(Advanced Host Controller Interface)という仕組み(プロトコル)で動作しており、
技術的にはすでに頭打ちとなった。そこで論理インターフェース部(プロトコル)を
AHCIからNVMeへ入れ替えることで非常に高速な通信が可能となっている。

### コマンド・キューイング
コマンドキューイングはデータのI/O要求が1つ1つ完了するのを待つことなく、
複数の命令を並列に処理するための仕組み。
キューにコマンドを受け取り、効率のよく処理できるよう順番を入れ替えながら並列に実行する。

コマンドキューは受け取ったコマンド（I/O処理）を格納しておく待ち行列。
キュー深度（Queue Depth）はキューに格納できるコマンド数であり、
一度に処理できるコマンド数だよん。

SATAだとコマンドキューが1個、深さは32個である。
ただ、機械的な可動部がないSSDの能力を最大限使用できなかった。（もっと沢山処理できるのに〜！）
そのため、NVMeを使用することで並列に大量のI/Oを処理できるようになっているそう。

#### SATA（AHCIプロトコル）コマンドキュー
コマンドキュー数：1
キュー深度：32

#### SAS（SCSIプロトコル）コマンドキュー
コマンドキュー数：1
キュー深度：254

#### NVMeコマンドキュー
コマンドキュー数：65535
キュー深度：65535

全然違う。。。
そりゃレイテンシ（遅延時間）も減りますわね。。。

##### 参考サイト
https://atmarkit.itmedia.co.jp/ait/articles/1511/19/news054.html




https://www.ratocsystems.com/products/subpage/scsi/products.html
UnrealEngineでMediaFrameworkのリソースを動的に作成して動画を再生する

[UnrealEngineのMediaFramework](https://docs.unrealengine.com/5.3/ja/media-framework-overview-for-unreal-engine/)を利用した際に動的にリソースを作成しようとするとログでエラーはでないのに動画が表示されないというような現象が起きていました。
MediaTextureをBlueprintのConstruct Object from Classで生成するのがダメみたいでContent Browserであらかじめアセットを作成しておき利用すると問題なく動画が再生できるので悩んでいたのですが、UDNに質問するなどして対応できたので内容をメモしておきます。

# 確認した環境

UE5.3.2
Windows11

# 参考情報

以下の情報を参照して対応できました。

https://forums.unrealengine.com/t/failed-to-set-media-texture-to-a-media-texture-which-is-from-construct-object-from-class/401551/7

# 対応した内容

以下のような形でMediaFrameworkのリソースを作成しました。

![2024-01-25_09h14_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/63d5284b-aa97-2ac1-d050-66ad94239aeb.png)

UpdateMediaTextureノードを実施していないと動画は再生できません。
UpdateMediaTextureノードの中身は以下のようにして自作しています。

```cpp
void UMyUtils::UpdateMediaTexture(UMediaTexture* mediaTexture)
{
	mediaTexture->UpdateResource();
}
```

ノード中で利用しているマテリアルは以下のような単純なものです。

![2024-01-25_12h53_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/20988164-5949-717d-35cb-3b73f847fc16.png)
OCIのリソースへのアクセスを指定したIPアドレスからに制限する

# はじめに
OCIのネットワーク・ソースを活用して、指定したIPアドレスからのアクセスのみ許可する方法を確認します。

https://docs.oracle.com/ja-jp/iaas/Content/Identity/networksources/Introduction_to_Network_Sources.htm

https://docs.oracle.com/ja-jp/iaas/Content/Identity/networksources/Restricting_Access_to_Specific_IP_Addresses.htm

# 設定前の動作確認

今回はObject Storageに外部からアクセスして動作を確認します。

まずは普通に以下の権限を与えてアクセスできることを確認します。
```
allow group グループ名 to manage object-family in compartment コンパートメント名	
```

外部からアクセスできることを確認します。
`-c`はコンパートメントのOCID、`-ns`はオブジェクトストレージネームスペースを指定しますが、環境変数に設定しています。

```
$ oci os bucket list --profile PROFILE -c $NC -ns $NN
{
  "data": [
    {
      "compartment-id": "ocid1.compartment.oc1..aaaaaaaae7aecc522jiytxxxxxxxxxxxxxxx",
      "created-by": "ocid1.user.oc1..aaaaaaaaefqcqse6glpgvqmbaxjmfs76xxxxxxxxxx",
      "defined-tags": null,
      "etag": "3bab46ec-e0cb-4eeb-8b70-607d70424509",
      "freeform-tags": null,
      "name": "nrt-bucket01",
      "namespace": "nrxxxxxxxxxxx",
      "time-created": "2024-01-23T02:09:55.981000+00:00"
    }
  ]
}
```

# IPアドレス制限
## ネットワーク・ソースの設定
OCIコンソールの`アイデンティティとセキュリティ`→`アイデンティティ`→`ネットワーク・ソース`をクリックし、`ネットワーク・ソースの作成`をクリックします。

今回は以下のようにアクセスを許可するIPアドレスを設定します。

![スクリーンショット 2024-01-25 11.00.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/8f5e3de5-2012-dfd6-bcc6-664b3f8465b0.png)

## ポリシーの設定
ポリシーを以下のように書き換えます。
（where句を追加します）

```
allow group グループ名 to manage object-family in compartment コンパートメント名 where request.networkSource.name='allow-lhr'
```

## 確認

設定したIPアドレス以外の端末からアクセスすると、以下のように拒否されます。
ネットワーク・ソースで設定した端末からは設定前と同様にアクセスできます。

```
oci os bucket list --profile PROFILE -c $NC -ns $NN
ServiceError:
{
    "client_version": "Oracle-PythonSDK/2.118.0, Oracle-PythonCLI/3.37.1",
    "code": "NamespaceNotFound",
    "logging_tips": "Please run the OCI CLI command using --debug flag to find more debug information.",
    "message": "You do not have authorization to perform this request, or the requested resource could not be found.",
    "opc-request-id": "nrt-1:R5AAn3RsCE7GRefd7FMbMni_kiIffedceafTAJOsnFRXP9i_yiuV8XwNkPqcOZS5",
    "operation_name": "list_buckets",
    "request_endpoint": "GET https://objectstorage.ap-tokyo-1.oraclecloud.com/n/nrjxxxxxx/b",
    "status": 404,
    "target_service": "object_storage",
    "timestamp": "2024-01-25T02:08:07.756790+00:00",
    "troubleshooting_tips": "See [https://docs.oracle.com/iaas/Content/API/References/apierrors.htm] for more information about resolving this error. If you are unable to resolve this issue, run this CLI command with --debug option and contact Oracle support and provide them the full error message."
}
```

ログを確認すると、ネットワーク・ソースで指定したIPアドレスからのアクセス（下）は成功していますが、それ以外のIPアドレスからのアクセス（上）は404で失敗しています。


![スクリーンショット 2024-01-25 11.10.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/c6c91c5e-c792-9f9c-de86-bd0fb3fdf299.png)

失敗したログの中身を見ると、このように詳細が確認できます。

![スクリーンショット 2024-01-25 11.11.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/ae707ff3-25c5-544a-6b47-b33bf7d65220.png)
alembicで外部キーを追加するときはCONSTRAINT 名を明示した方がいい

普通に `alembic revision --autogenerate -m "add_os_version_id"` でマイグレーションスクリプトを自動生成すると、 `op.create_foreign_key` `op.drop_constraint` の第一引数(CONSTRAINT名)が `None` となってしまう。

このスクリプトは `alembic downgrade base` 時に削除すべきCONSTERAINT名がわからずエラーになってしまう。

```python
"""add_os_version_id

Revision ID: 6479768cd289
Revises: ecd9896cb55a
Create Date: 2024-01-25 11:40:11.027316

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = '6479768cd289'
down_revision = 'ecd9896cb55a'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###

    op.add_column('devices', sa.Column('os_version_id', sa.Integer(), nullable=True))
    op.create_foreign_key(None, 'devices', 'os_versions', ['os_version_id'], ['id'], ondelete='RESTRICT')
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(None, 'devices', type_='foreignkey')
    op.drop_column('devices', 'os_version_id')
    # ### end Alembic commands ###
```

 `op.create_foreign_key` `op.drop_constraint` の第一引数(CONSTRAINT名)に何らかの値を定義してあげると、`alembic downgrade base` でエラーにならなくなる。

```python
"""add_os_version_id

Revision ID: 6479768cd289
Revises: ecd9896cb55a
Create Date: 2024-01-25 11:40:11.027316

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = '6479768cd289'
down_revision = 'ecd9896cb55a'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###

    op.add_column('devices', sa.Column('os_version_id', sa.Integer(), nullable=True))
    op.create_foreign_key("fk_devices_os_versions_id", 'devices', 'os_versions', ['os_version_id'], ['id'], ondelete='RESTRICT')
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint("fk_devices_os_versions_id", 'devices', type_='foreignkey')
    op.drop_column('devices', 'os_version_id')
    # ### end Alembic commands ###
```
高級・低級のミスリーディング

高級言語・低級言語が割とミスリーディングなので、その原因を考えてみた。

英語だと `High level`、 `Low level` と表現されるが、 `level` が指す意味が日本語の `級` とは違う意味かもしれない

辞書を引いてみると、 `level` は一般的に高さを表すもので、コーディングというコンテキストでは、その言語の機能や仕様のリッチさを指していないことが伺える。

なのでここでいう `level` とは、実現したい概念に対してどれだけ抽象化されているかという尺度で高低を表していると考えることができる。

車で例えるなら、高レベルなら「エンジンをかける」だろうし、低レベルなら「イグニッションボタンが押されたらバッテリーを通電する」みたいなイメージ。