OmniAICreator/Qiita-1.07M huggingface dataset:
駄目グラフ006

駄目グラフ005 でも書いたが，Jitter を使うのは最低。
Jitter は R などでも，何種類か亜種があるが，どれも使う必然性がないどころか，誤解を生じかねないので使うべきでない。

Python/seaborn
![スクリーンショット 2024-01-22 20.48.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/723d5dca-4edc-357e-dccb-7ed81e32276e.png)

背景が色付きで，グリッドが白抜きというのも，学術雑誌への投稿としては多分不向き。
IDaaS/IdP各サービスのリフレッシュトークンの調査

OAuth2.0のリフレッシュトークンのローテーション実装やexpire時間はIDaaS/IdP各サービスで結構違うので、調べた内容をまとめてみます。

リフレッシュトークンは漏れたらヤバいトークンなので、その扱いを見ることで各社のセキュリティの考え方が垣間見える気がします。

# Google

- トークン有効期限：無期限（6ヶ月使われなかったらexpire）
- ローテーション：なし
- 管理者が特定ユーザーのトークンを無効化できるか：Workspaceなら可能
  - トークンだけ無効化はできないが、OAuth承認済みアプリを管理者が削除できる

https://developers.google.com/identity/protocols/oauth2?hl=en

# AWS Cognito

- トークン有効期限：設定で変更可能（デフォルト30日）
- ローテーション：なし
- 管理者が特定ユーザーのトークンを無効化できるか：可能

https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-refresh-token.html

# Auth0

- トークン有効期限：設定で変更可能（デフォルト30日）
  - ローテーションしても有効期限は延びない
- ローテーション：あり
- ローテート済みのトークンが使われた場合の処理：該当ユーザーの全トークンが無効化
- 同じリフレッシュトークンに関する冪等性：デフォルトなし
  - 設定で猶予時間を設定できる、15秒などとすれば実用上は十分と思われる
- 管理者が特定ユーザーのトークンを無効化できるか：可能

https://auth0.com/docs/secure/tokens/refresh-tokens/configure-refresh-token-rotation

# Slack

- トークン有効期限：使われない限り無期限
- ローテーション：あり
- ローテート済みのリフレッシュトークンが使われた場合の処理：特になし
- 同じリフレッシュトークンに関する冪等性：あり
  - ローテート済みトークンは初回利用から12時間後まで有効（長すぎでは？）
- 管理者が特定ユーザーのトークンを無効化できるか：?

https://forums.slackcommunity.com/s/question/0D5Hq00009OgLQgKAN/what-is-the-expiration-time-for-refresh-token-

# 所感など

GoogleもAWSもリフレッシュトークンのローテーションを実装していないのは意外に感じました。

そもそもリフレッシュトークンのローテーションの必要性について懐疑的な関係者も多いのか、どこかの公式ドキュメントに実装する意味がないって書いてあったような記憶があります。真偽は判断しかねますが。

実際のところ相当頑張らないと「正しい」ローテーション実装にならないので実装しない方が正解と言いたくなる気持ちもわかるんですが、Auth0のローテーション実装は完璧に近いんじゃないでしょうか。（私は素人なので、むしろ専門家の人の意見が聞きたい）
新人エンジニアがDockerを勉強するのに使った資料まとめ

# 対象の読者 👨‍💻👩‍💻
・業務でDockerを使っているが、いまいち仕組みが分からない人
・```docker exec -it``` のコマンドの意味が分からない人
・コンテナ技術が分からない人
・Dockerとは何かを根本から理解したい人

# この記事から得られること ✅
・Dockerの仕組み理解に役立つドキュメントを手早に知ることができる


# はじめに 🤝
新卒未経験で入社して、9ヶ月が経ちました。現在はSaaS企業でWebアプリを開発しており、インフラでDockerを使っています。

毎回dockerに入るのに```docker exec -it```をコピペしている自分が嫌になったので色々調べていたら、「Dockerってどういう風に動いてるんだ？」と好奇心に駆られてしまったので、理解に使った資料を残しておこうと思います。

この記事を読むことで、自分と似た境遇の方があちこち調べる手間を省けたら幸いです！


# 記事一覧 📄
  
### 仮想化・コンテナ技術 📦

**①『Linuxコンテナとは何か - コンテナ技術の仕組みと歴史』**

Dockerで用いられているコンテナ技術や歴史について説明した記事です。
コンテナと仮想化の違いを示した図が特に分かりやすかったです。

https://www.redhat.com/ja/topics/containers/whats-a-linux-container

**②『Understanding containers』**

コンテナ技術とそのメリットが学べます。
勉強を進めていくと学ぶ「DockerはLinux上でしか動かない」ことを深く理解するのに、
記事で書かれている「Container vs Docker (Traditional Linux containerとDockerの違い)」が役立ちました。

https://www.redhat.com/ja/topics/containers

https://www.redhat.com/ja/topics/containers/what-is-docker



## Dockerについて 🐳

**①『Docker概要』**
[docker.docs](https://docs.docker.com/) が和訳されているドキュメントです。
Dockerとは何なのか、Dockerの構成要素(アーキテクチャ)が学べます。
アーキテクチャの図解が特に分かりやすいです。

https://docs.docker.jp/get-started/overview.html

**②『Docker Engineとは何か』**

Docker公式ドキュメントに載っている図を用いて、理解に必要な箇所をピンポイントで押さえてくれている記事です。

https://zenn.dev/ryoatsuta/articles/64dcc2e2b4e0cf

**③『コンテナについて』**

コンテナを作成してアプリを動かす時の基礎となる知識が得られます。
Docker社がGitHub上でアプリを公開してくれているので、手元にオリジナルアプリがなくても学べます。

https://docs.docker.jp/get-started/01_overview.html

**④ボリュームについて**
③でコンテナチュートリアルを学ぶと、アプリをDockerで起動・停止する度にデータが消えることを学びます。データが消えないようにするにはどうしたらいいのか、それの理解に役立ったのが以下の記事です。

https://matsuand.github.io/docs.docker.jp.onthefly/storage/volumes/

https://zenn.dev/fdnsy/articles/e2024d73ec2bda

https://qiita.com/aki_55p/items/63c47214cab7bcb027e0


# 最後に 

他にも、
・Docker Desktop
・Docker Image
・Docker Hub
などのドキュメントは沢山あるのですが、これらと同じドキュメント内に記載があるので今回は割愛します。

まだまだ自分自身も勉強中なので、他に役立つ記事を見つけたら追記していく予定です🙆‍♂️
MySQLで初期のrootパスワードを確認する。

## 以下のコマンドでMySQLで初期のrootパスワードを確認することできます。
ターミナルで以下のコマンドを入力してください。
```
cat /var/log/mysqld.log | grep localhost
```
以下の表示がされるはずです。
```
A temporary password is generated for root@localhost: パスワード
```
【Python3】paizaでよく使う入力・出力コードまとめ

自分用のメモに、paiza（パイザ）でよく使う入力・出力パターンをまとめました。
言語は現在学習中のPython3です。

:::note info
**paizaとは？**
paizaラーニングとは、オンラインでプログラミング入門学習ができるサービスです。PCとネット環境さえあれば、環境構築不要でさまざまな言語を学ぶことができます。

詳しくは **[paiza公式サイト](https://paiza.jp/)** をご確認ください。
:::

# 環境
Python 3.11.5

# 前提
paizaの課題では、自動で入力される値に対してプログラミング処理を施し、出力するのが基本になります。
主に処理するのは数字のため、本記事は整数の入力・出力を取り扱います。

# 入力パターン
主な入力パターンは、大きく分けて3つです。
1. 値単体を入力
1. 半角スペースで区切られた値を複数入力
    - 個別の変数に登録したい場合
    - リスト化したい場合
1. 改行で区切られた値を複数入力

それぞれのコードは下記の通りです。

### 1. 値単体を入力
```python:Python3
n = int(input())
# 入力： 1
# => n = 1
```
### 2. 半角スペースで区切られた値を複数入力
**個別の変数に登録したい場合**
```python:Python3
N, M, K = map(int, input().split())
# 入力： 1 2 3
# => N = 1
#    M = 2
#    K = 3
```
直接関係のない複数の値が入力されるときに使用します。

**リスト化したい場合**
```python:Python3
l = list(map(int, input().split()))
# 入力： 1 2 3
# => l = [1, 2, 3]
```
A_1, A_2..A_Nといった連続する値が入力される時に使用します。
このパターンですと要素数は別途用意されていることが多いのですが、そのためだけにループ処理を入れると行がかさんでしまうので、私はリスト化しています。

### 3. 改行で区切られた値を複数入力
```python:Python3
n = int(input()) # 行数
l = [] # 空のリスト
for i in range(n):
    l.append(int(input())) # 入力された値をリストに追加
# 入力： 1
#      2
#      3
# => l = [1, 2, 3]
```

改行区切りで入力される場合、その行数は必ず入力されますので、for文を使ってリスト化します。
`.append()`は引数の値をリストに追加するという意味です。

# 出力パターン
主な出力パターンは、以下の4つです。
1. 値単体を出力
1. 半角スペース区切りで複数の値を出力
1. 改行区切りで複数の値を出力
1. 半角スペース区切りで、複数行出力

それぞれのコードは下記の通りです。

### 1. 値単体を出力
```python:Python3
result = 100
print(result)
# => 100
```
### 2. 半角スペース区切りで複数の値を出力
```python:Python3
result = [1, 2, 3]
print(*result)
# => 1 2 3
```
リストの前に`*`をつけると、半角スペース区切りで出力できます。

### 3. 改行区切りで複数の値を出力
```python:Python3
result_list = [1, 2, 3]
for result in result_list:
    print(result)
# => 1
#    2
#    3
```
処理の段階で、出力したい値をリストに登録します。
`for 変数 in リスト：`とすることで、配列の中身を個々に`変数`内へ格納できるので、順番に出力します。
### 4. 半角スペース区切りで、複数行出力
```python:Python3
result_list = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
for result in result_list:
    print(*result)
# => 1 2 3
#    4 5 6
#    7 8 9
```
2と3の応用です。
事前に、改行したい位置で二次配列を生成します。
それをfor文で一行ずつ取り出し、半角スペース区切りで出力します。

# 記事をまとめた経緯
書くたびに調べるのが面倒だったので、自分がよく使っているものだけまとめました。
できれば配列関係もまとめたい（願望）

# 参考
- [Pythonでリスト（配列）に要素を追加するappend, extend, insert](https://note.nkmk.me/python-list-append-extend-insert/)
- [受け取った入力の型を指定する](https://algo-method.com/descriptions/108)
- [pythonでリストの要素をスペース区切りで出力をしたい時](https://tech-shelf.hatenablog.com/entry/programming/input_output)

などなど
Unable to load the requested class: {class名} CodeIgniterのエラー解消

## エラー内容
ブラウザでサイトにアクセスしたところ、以下のエラーが表示された。
```
An Error Was Encountered
Unable to load the requested class: {class名}
```
このときCodeIgniterのエラーログは以下の内容のみ。
```
ERROR - yyyy-MM-dd hh:mm:ss --> Unable to load the requested class: {class名}
```
通常のエラーログと違ってスタックトレースがなくこの1行だけなので、やや戸惑った。
そのため発生個所の特定も必要になる。
## 原因と対処
**原因**：ファイル名・クラス名の大文字小文字のtypoが原因で、クラスのロードに失敗していた。
**対処**：ファイル名・クラス名の大文字小文字を確認する。ファイル名は大文字にする。

## 環境
- CodeIgniter 3.1
- PHP 8.1.14
- EC2インスタンス（Amazon Linux 2）
- Apache 2.4.58

備考：ローカルのDocker環境ではこのエラーは起きず、EC2インスタンスでのみ発生した。
（エラー解消後も、ローカルで発生しなかった原因は調査しきれていない）

## 私の案件での具体的対処
私の案件ではモデルファイルに以下の記載があった。
```
$this->load->library('path/to/library/file/class_name');
```
しかし実際にclass_name.phpファイルは存在しており、ローカル環境でエラーは発生しない。

エラー文でググると参考サイトが出てきてくれたため、以下の対処で無事エラー解消できた。
- ファイル名の先頭を大文字に変更
  class_name.php → **C**lass_name.php
- ロードするファイル名を同様に大文字に変更
  path/to/library/file/class_name → path/to/library/file/**C**lass_name

## 参考サイト
**CodeIgniter Forums**
SOLVED Unable to load the requested class: Globals
https://forum.codeigniter.com/showthread.php?tid=68373
fgrep

fgrepは、grep -Fと同じ。パターン文字列をただの文字列として扱う
`       -F, --fixed-strings, --fixed-regexp
              Interpret  PATTERN  as  a  list  of  fixed strings, separated by
              newlines, any of which is to be matched.  (-F  is  specified  by
              POSIX,  --fixed-regexp  is an obsoleted alias, please do not use
              it in new scripts.)`
```
[linuxstudy@xxxx ~]$ cat find.txt 
abcdef
abc[^a]ef
[linuxstudy@xxxx ~]$ fgrep abc[^a]ef find.txt  //abc[^a]efという文字列を検索
abc[^a]ef
[linuxstudy@xxxx ~]$ grep abc[^a]ef find.txt   //正規表現abc[^a]efを検索
abcdef
```
AWS CLIの設定

公式ドキュメントとか見たら、書いてありますが・・・

https://aws.amazon.com/jp/getting-started/guides/setup-cdk/

-----



#### aws cli のインストール

```terminal:terminal
brew install awscli
//確認
aws --version
```


#### aws cliの認証情報とアクセスキーを紐付ける

まずAWSのI AMのユーザーのページかセキュリティ認証情報ページでアクセスキーを作成しておきます。

https://console.aws.amazon.com/iam/home?#/security_credentials


```terminal:terminal
aws configure
AWS Access Key ID [None]: アクセスキー ID
AWS Secret Access Key [None]: シークレットアクセスキー
Default region name [None]: ap-northeast-1
Default output format [None]: ap-northeast-1

//確認
aws configure list
```



#### aws cdk のインストール

```terminal:terminal
brew install aws-cdk
または　npm install -g aws-cdk
//確認
cdk --version
```

#### ブートストラップする

```terminal:terminal
// AWS アカウント番号を調べる
aws sts get-caller-identity
// デフォルトの地域を調べる
aws configure get region

cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```


#### CDKでプロジェクト作成

```
mkdir cdk-demo
cd cdk-demo
cdk init --language typescript
```
bin/cdk-demo.ts を変更して、AWSサービスを定義する。


デプロイ
```
cdk deploy
```

これでAWSにサービスが作成されているはず。


----
参考

https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/cli.html


https://zenn.dev/akakuro/articles/30f570b8863bef

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html


https://zenn.dev/akkie1030/articles/aws-cli-setup-tutorial

https://qiita.com/m-chan/items/f9df1b8c32ae7f18ce1d

https://dev.classmethod.jp/articles/rest-api-authentication-using-cognito/
Androidダークモード対応方法

## はじめに
[こちら](https://qiita.com/sefwgweo/items/2c80356a14b74a5df827)でダークモード対応する際の見積もり手法という記事をあげましたが、本記事では短い準備期間でダークモード対応１画面にかかるコストをパターン化するためにどんな構成にしたのかを紹介します。

## 事前準備
NewsPicksのAndroidアプリは10年もののプロダクトであるがゆえに、いわゆるカラーパレットと呼ばれるようなものがアプリ内に複数セットありました。
ダークモード対応用のカラーパレットと変数名がかぶってしまう古いものもあったため、以下なルールで対処しました(いずれもIDEAのりファクタ機能を用いて作業しています)

 - 使われていないリソースは削除、同一カラーを指定しているものは1個に可能な限りまとめる
 - ダークモード対応用に新規追加するもの以外の変数名にoldというPrefixを付けてRename(例：blue_200 -> oldblue_200)

## 手順１：ダークモード対応用カラーパレット追加
UI層のres/values/colors.xmlにiOSと共用しているFigma記載のカラーパレットを追記(以下はblueに関するカラーパレット設定例)
![スクリーンショット 2024-01-22 18.38.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541072/a2bf3697-5bc8-a5fa-dea0-83d89626c36c.png)

## 手順２:[デザイナ設計のセマンティックカラー](https://note.com/akanyoshi/n/na18930c1808f)追加
設計に従い、Body/Surface/Object/Border/Text/Overlay...etcといった区分でライトモード時セマンティックカラーをUI層のres/values/colors.xmlへ、ダークモード時セマンティックカラーをUI層のres/values-night/colors.xmlにカラーパレット内のグローバルカラーを使って定義していきます。

この時、変数名の命名方法がiOSと異なるルールになりました（iOSではBorderであれば `Border/Accent/Primary`といったディレクトリ構造で管理をしている）。
AndroidではResource名は小文字プラス記号である必要がある及び、ディレクトリ構造で管理できないという制約のためBorderであれば以下例のように、階層はアンダースコアで表現しました。

 例：ボーダー色（ライトモード） | 例：ボーダー色（ダークモードモード）
 :--: | :--: 
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541072/1c21727b-cfa1-7f37-3073-27495b0c15b8.png" width="400" /> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541072/85d1207a-2383-5ac4-093e-cc636c6dec8f.png" width="400" />  

## 手順3: Figmaに従って各セマンティックカラーをXML等に反映
手順2までで準備は完了しているので、あとはひたすらFigma通りに値を反映する作業を行っていきます。
実際に何画面かダークモード対応をやってみることで見積もり時間をわりと正確に出すことができました。

## 手順4: ライトモード・ダークモードの切り替え対応
機能要件は `ダーク/ライト/端末の設定を使用` の3パターンが設定画面で切り替えられることで、以下で判定します。

```kotlin
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)// 常にダークモードをONにする
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)// 常にダークモードをOFFにする
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); // アプリ全体に適用
```

ただ、端末の設定を使用したい場合の判定処理ではまりました。
具体的には`AppCompatDelegate.getDefaultNightMode()` で得た値と↑の3値の一致で判定するだけでは不十分な端末があり、最終的には以下な処理になりました

```kotlin
/**
 * 表示を切り替えるために現在ダークモードかどうかを返す
 */
fun isDark(): Boolean {
    val defaultNightMode = AppCompatDelegate.getDefaultNightMode()
    if (defaultNightMode == AppCompatDelegate.MODE_NIGHT_YES) {
        return true
    }
    if (defaultNightMode == AppCompatDelegate.MODE_NIGHT_NO) {
        return false
    }

    // 端末の設定に従うケース
    val currentNightMode: Int = (context.resources.configuration.uiMode
        and Configuration.UI_MODE_NIGHT_MASK)
    when (currentNightMode) {
        Configuration.UI_MODE_NIGHT_NO -> return false
        Configuration.UI_MODE_NIGHT_YES -> return true
        Configuration.UI_MODE_NIGHT_UNDEFINED -> return false
    }
    return false
}
```

## まとめ
事前準備期間をあまり多く設けず、見積もりもし易い構成が取れたかなと思います。
また、過去に何回もカラーパレットを作っては反映しなおし、ということを繰り返していたので、セマンティックカラー導入により同じことが起きずに安心して運用できる設計にしてくれたデザイナ陣に感謝！
lwc を aura で　ラップ wrappe する

aura の　pad を 0にする

```
    <aura:html tag="style">
        .cuf-content {
        padding: 0 0rem !important;
        }
        .slds-p-around--medium {
        padding: 0rem !important;
        }
        .slds-modal__content{
        overflow-y:hidden !important;
        height:unset !important;
        max-height:unset !important;
        }
    </aura:html>
BOX API（JWT認証）をPythonで使ったときの備忘録

# 背景
仕事でBOXに自動アップロードをするツールを作成しました。その時に詰まったところが何点かあったのでまとめようと思いました。

# 開発環境
MacOS
Python 3.11.2
Vscode

# 認証方式
JWT認証

# 手順
### BOX側で行うこと
##### 1.BOXの開発者ページへ移動
https://ja.developer.box.com/

参考にしたサイト
https://ja.developer.box.com/guides/tooling/sdks/python/
 
##### 2.アプリの新規作成⇒カスタムアプリを選択
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/c8224c86-7ac0-0338-10d5-325b7efd4986.png) 

##### 3.アプリ名・目的を入力（必須）
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/0061d07a-eec3-ad9d-c657-fb8c31898639.png)

##### 4.サーバー認証（JWT使用）を選択
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/01afaaa8-f456-d866-f639-af392a8afc03.png)

##### 5.構成タブのアプリアクセスレベルを"アプリ＋Enterpriseアクセス"を選択⇒変更を保存
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/60774d8a-6dfc-0eab-22a9-45ee55c49927.png)

##### 6.組織に属している場合は承認タブの確認して送信を選択
Enterpriseアクセスの場合、これが承認されないとAPIが使えない
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/56141253-00eb-d760-034d-106753ae4305.png)
 
##### 7.承認されているか確認
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/79da6b0c-1470-de5f-a867-93a3bf3cdbe2.png)


##### 8.構成タブの公開キーの追加と管理⇒公開/秘密キーペアを生成
ボタン押下すると自動でJSONファイルがダウンロードされる。
後々のためにファイル名を"config.json"に変更しておく。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957298/a48aa20b-3a2d-0f58-f8b2-fa7a6631b9ce.png)
##### 9.対象BOXへ編集者権限
APIアカウントについて対象BOXの編集者権限を与える。APIアカウントの情報は一般設定タブのService Account IDを参考にする。

### サンプルコードの作成手順
##### 1.必要ライブラリのインストール
```
pip install boxsdk
pip install "boxsdk[jwt]"
```

##### 2.APIが使えるか下記コードで確認する。
```box_test.py
from boxsdk import JWTAuth
from boxsdk import Client
from boxsdk.exception import BoxAPIException

#jsonファイルのパス
CONFIG_FILE = '/configファイルのパス/config.json'

#BOX APIを使う準備
auth = JWTAuth.from_settings_file(CONFIG_FILE)
client = Client(auth)

# ユーザー情報を取得して表示（APIテスト）
user = client.user().get()
print(f'UserName:{user.name}(ID:{user.id}), Email: {user.login}')
```

##### 3.自動化処理を実装して検証を行う。
※BOX上に存在するファイルに対して新規アップロードをするとエラーを起こす仕様。
```box_upload.py
# 必要なライブラリをインポートします。
from boxsdk import JWTAuth
from boxsdk import Client
from boxsdk.exception import BoxAPIException

#jsonファイルのパス
CONFIG_FILE = '/configファイルのパス/config.json'

#BOX APIを使う準備
auth = JWTAuth.from_settings_file(CONFIG_FILE)
client = Client(auth)

#親フォルダのID。フォルダIDはBOX上のフォルダページのURLの末尾の数字
folder_id = '12桁のフォルダID' 

#上書きするファイルのID。ファイルIDがBOX上のファイルページのURLの末尾の数字
file_id =  '12桁のファイルID'

#Boxのフォルダ内のファイルを取得します。
box_items = client.folder(folder_id).get_items()
box_files = []
for item in box_items:
box_files.append(item.name)

#BOXフォルダ内のファイル名とアップロードするファイル名を比較して一致していれば上書き、
#一致していなければ新規アップロードをする処理をここに書く(あらかじめ辞書を作成して実装した)
#今回は省略

#上書き
try:
    updated_file = client.file(file_id).update_contents('ファイルパス')
except BoxAPIException:
    print('上書きできませんでした。ファイルIDがあっているか確認してください。')

#新規アップロード
try:
    box_file = client.folder(folder_id).upload('ファイルパス')
except BoxAPIException:
    print('アップロードできませんでした。')
 ```
C++で、設定した日付を通知する機能を作ってみる第一講

# 　　　　　　　　　役に立たずとも
## 開発経緯
　学校の課題提出が近づくごとに思う「提出まであと何日だ？」。
 windows内のアプリで設定ができる。
 　しかし個人的には、PCが起動したタイミングで通知が欲しいのだ。

## 必要な機能
　まず機能の洗い出し。
　1\. 日付の設定・記録
　2\. パソコンの起動確認
　3\. 通知を行う
今回は2および3の機能への挑戦になる。

## 開発
　開発環境
 Visual Studio Community 2022 ver.17.7.5
 windows10 Home

　開発言語
C
C++?(CとC++の違いがまだよくわからない)

## 現在の日付から目的の日付までの日数計算
　現在の日付の確保を行うためには[time.h]をincludeをする。
 コードがこちら
```cpp:time.cpp
#include <iostream>
#include <conio.h>
#include <time.h>

using namespace std;

int main ()
{
  //変数宣言
  int CurrentMonth = 0;  //現在の月
  int CurrentDay = 0;  //現在の日
  
  //現在の日付の取得
  CurrentMonth = tm_mon;  //月の取得
  CurrentDay = tm_mday;  //日の取得

 cout << CurrentMonth << "月" << CurrentDay << "日";

_getch ();
return 0;
}
```
見事にエラー。
 CurrentMonth = **tm_mon;**  //月の取得
  CurrentDay = **tm_mday;**  //日の取得

  この部分が定義されていないとのこと。
  調べてみるとローカルタイム（どこの時間か）を設定していないからっぽい。
  のでこれより前の分に
　time_t t = time(NULL);
 
　struct tm *local = localtime(&t);
  これを追加したうえで前に
  　local->
  を追加すると、

  またエラー。
  エラー内容は

C4996	'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

初めて見るエラーだぞ。
雑翻訳すると
「'localtime'←こいつ安全じゃねえぞ！'localtime_s'←こっちを使っとけ！」
とのこと。
安全じゃないってどういう…？

調べてみると何かvisial studioだと使えないっぽい？
仕方がないので従うとしよう。
変更後のプログラムがこちら
※長くなるので必要のないものを消しています
```cpp:time.cpp
int main()
{
	//変数宣言
	int CurrentMonth = 0;  //現在の月
	int CurrentDay = 0;  //現在の日

	time_t t = time(NULL);

	struct tm local;
	errno_t err = localtime_s(&local, &t);

	CurrentMonth = local.tm_tm_mon + 1;
	CurrentDay = local.tm_mday;
}
```

結果…
```
1月20日
```
行った！！！！

とりあえず日付の取得はできた。
　お次は目的の日付を入力して記録を行う。
 ここは授業でやっていたことの応用。
 ```cpp:time.cpp
int main()
{
	//変数宣言
	//日付関係
	int CurrentMonth = 0;  //現在の月
	int CurrentDay = 0;  //現在の日

	int ObjectiveMonth = 0;  //目的の月
	int ObjectiveDay = 0;  //目的の日

	time_t t = time(NULL);  //ローカルタイムの初期化？

	struct tm local;
	errno_t err = localtime_s(&local, &t);

	//ファイル関係
	ifstream inputFile;

	inputFile.open("Days.txt", ios::in);  //ファイルオープン

	if (inputFile.fail())
	{
		cout << "ファイルオープン失敗";
	}
	else
	{
		//現在の日付の所得
		CurrentMonth = local.tm_mon + 1;  //現在の月
		CurrentDay = local.tm_mday;  //現在の日

		//目的の日付の入力
		inputFile >> ObjectiveMonth;
		inputFile >> ObjectiveDay;

		cout << "現在の日付:" << CurrentMonth << "月" << CurrentDay << "日" << endl;
		cout << "目的の日付:" << ObjectiveMonth << "月" << ObjectiveDay << "日" << endl;
	}

	_getch();
	return 0;
}
```
``` Days.txt
2
1
```

結果
```
現在の日付:1月20日
目的の日付:2月1日
```
まあ楽勝ですよ。

ちなみにここまで一時間半かかってます。
あれ？思っているよりも時間が掛かった？
次行くぞい
## パソコンの起動を確認する
　多分今までのは序章的な感じ。
 序章に時間かけすぎな気がするが。

 　調べてみるとレジストリやらなんやらって話が出てきて思っているよりもこれは難しいのでは？
思い付きでやってはダメなものでは？


 って考えたがプログラムで書くよりもスタートアップに登録すれば簡単に行くことに気が付いた。
今回はこちらを採用。
次は触ってやる。

1\. まず使うプログラムのexeの場所を開く。
2\. exeのショートカットを作る。
3\. ウィンドウズキーとRキーを押す。
4\. shell:startup　と書き、実行する。
5\. 開いた場所にショートカットをコピーする。

完成！
思っているよりも簡単だった…。

再起動して確認したがうまくいった。

## 次に向けて
　とりあえず最低限のことはできた。
次に立ちはだかるは直接通知を行うことをしなければならない。
SDK関係に足を踏み入れなければならない感じで時間が掛かってしまうのでいったん終了。

初めての投稿になるため、あまりうまくまとめられなかった場面が多くあった。
プログラムが汚いやもっとこうした方がいいがあったらコメントくださるとうれしいです
テープ装置 LTOを使うためのLTFSをdebian系OSでビルドする方法。

久しぶりに記事を書くことにしました。
LTOというテープ装置についての研究です、入手したのは第５世代の物でLTFSに対応しています。

LTFSはhttps://github.com/LinearTapeFileSystem/ltfs にソースを公開されているオープンソフトソフトウェアです。
ltfsはオープンソースの規格でredhatやcentosのrpmで導入実績があり、それを行うための記事もあります。
しかしLTFSのdebianによる導入記事はなかなかなかったので作ってみることにしました。

説明を一切しなければコマンドは下記のリストになります。
        
    #全てroot
    mkdir ltfs-git ; cd ltfs-git
    apt update ; apt upgrade
    apt install git vim
    git clone  https://github.com/LinearTapeFileSystem/ltfs.git
    cd ltfs
    touch /usr/bin/icu-config  
    vim /usr/bin/icu-config
        opts=$1
            case $opts in
            '--cppflags')
                echo '' ;;
            '--ldflags')
                echo '-licuuc -licudata' ;;
            *)
                echo '/usr/lib/x86_64-linux-gnu/icu/pkgdata.inc' ;;
            esac
    
    apt install  make  automake autoconf libtool fuse uuid libxml2-dev libsnmp-dev libicu-dev  pkg-config libfuse-dev  uuid-dev 
    ./autogen.sh
    ./configure
    make
    make install
    vim /etc/ld.so.conf
        /usr/local/lib/  を追加する。
    /sbin/ldconfig
    ltfs -v  #オプションが表示されたら成功
    apt purge  make  automake autoconf libtool fuse uuid libxml2-dev libsnmp-dev libicu-dev  pkg-config libfuse-dev  uuid-dev #でっかいので気にする方はビルドに使用したバイナリを消す。

コマンド解説

vim /usr/bin/icu-config

        opts=$1
            case $opts in
            '--cppflags')
                echo '' ;;
            '--ldflags')
                echo '-licuuc -licudata' ;;
            *)
                echo '/usr/lib/x86_64-linux-gnu/icu/pkgdata.inc' ;;
            esac
            #以上を書き込む
上記は
https://github.com/LinearTapeFileSystem/ltfs/issues/153
https://github.com/LinearTapeFileSystem/Debian10-Build/blob/master/icu-config
にある修正方法で、icu-configにダミーを作らなければエラーが出るようです。

    apt install  make  automake autoconf libtool fuse uuid libxml2-dev libsnmp-dev libicu-dev  pkg-config libfuse-dev  uuid-dev 

上記はaptにあるビルドに必要なリストです。このパッケージに該当するものが必要なので、それが特定できればpacmanなどのほかのパッケージ管理システムでもビルド可能だと思います。











正直LTFSをビルドさせるのが目的でLTFSは実用するつもりがなかったので使用方法はあまり調べませんでした。
しかし注意点としては、カレントにあまり多くのファイルを置くとリストを見るときにとんでもなく冗長になります。もし使うなら大き目のファイルで消せないけどあまり使わないものにとどめるべきです。
PowerShellのヒアドキュメント経由で証明書ストアに証明書を登録する

ローカルコンピューターの「信頼されたルート証明機関」証明書ストアに証明書を登録した際の備忘録です。

```powershell
$TempFile = New-TemporaryFile

$content = @'
-----BEGIN CERTIFICATE-----
ここを証明書の中身で置き換える
-----END CERTIFICATE-----
'@

$content | Out-File $TempFile

Import-Certificate -FilePath $TempFile -CertStoreLocation 'Cert:\LocalMachine\Root'
```
【Azure Functions】【C#】インスタンスが実行中に入れ替わることがある

ごく普通の[Blobトリガー](https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-storage-blob-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4&pivots=programming-language-csharp)を作成します。


```cs
public static class BlobTriggerHoge {
    private static ILogger logger;
    private static Foo foo;

    [FunctionName("BlobTriggerHoge")]
    public static void Run(
        [BlobTrigger("container/{fileName}")] BlockBlobClient myBlobClient,
        string fileName,
        ILogger log,
    ) {
        logger = log;
    	foo = new Foo(fileName);
    	a();
    	a();
    	a();
    }

    public static void a() {
    	logger.LogInformation($"fileName:{foo.fileName} hashCode:{foo.GetHashCode()}");
    }
}

class Foo{
    public string fileName;
    public Foo(string fileName) {
    	this.fileName = fileName;
    }
}
```


同じログを3回出しているだけに見えますね。

ところがこのFoo、たまに途中から別のインスタンスになることがあります。

```
[2024-01-01T00:00:00.001Z] fileName:hoge.png hashCode:123456789
[2024-01-01T00:00:00.002Z] fileName:hoge.png hashCode:123456789
[2024-01-01T00:00:00.003Z] fileName:fuga.png hashCode:987654321
```

なんで？？？？？？？？？？？？

大量のファイルを同時にアップロードして、BLOBトリガーが同時に複数起動したときに起きたり起きなかったりします。


# 対策

Fooクラスに状態を持たせない。

よし、staticおじさんになろう。


# 原因

いやまあ[よくあるstaticの罠](https://fundasta.co.jp/2017/10/31/static%E3%81%A8%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89%E3%82%BB%E3%83%BC%E3%83%95%E3%81%AE%E7%BD%A0/)なのですが、これ[Azure Fucntionsのドキュメント](https://learn.microsoft.com/ja-jp/azure/azure-functions/)に従って作ってたら絶対引っかかるだろ。
なにせありとあらゆるドキュメントで`static Run()`とか書いてあるので、トリガーは静的でなければならないと思い込まされてしまうわけですよ。

実際はトリガーは静的でなくても動きます。
ドキュメントではたいへんひっそりと触れられていました。

https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library?tabs=v4%2Ccmd
https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-dotnet-class-library?tabs=v4%2Ccmd

:::note info
The above example shows a static method being used, but functions aren't required to be static.
上記の例では静的メソッドが使用されていますが、関数を静的にする必要はありません。
:::

先に言えや。

ということでBlobTriggerHogeクラスからstaticを全部消して普通のクラス・インスタンスにしたところ、インスタンスが入れ替わることがなくなりました。

実のところはインスタンスが入れ替わっているのではなく書き替えられています。
`private static Foo foo`の`foo`は一見privateであり他所からは全く見えないようになっていると思えますが、実際は中身が複数のリクエストで共有されているみたいです。
そのせいで、トリガー1が`hoge.png`を書きこんだ後でトリガー2が`fuga.png`を書きこむと、その後はトリガー1からも`fuga.png`になってしまうわけです。

え、そんなの常識だって？
そうですね。


# 感想

私はC#をAzure Functions上でしか使ったことがありません。
そもそもC#は必要にかられて仕方なくやっているだけなので、とりあえず動かすのに必要なところをつまみ食いしているせいで、体系的な学習を一切していません。
なので言語の基礎や定石や風習といったところが全然わかっていないんですよね。
そんなわけで見事にstaticの罠に引っかかってしまったという話でした。
PHPerはマルチスレッドに弱いのだ。

ところでこれ、`static Run()`としつつ正しい処理にするにはどうすればいいんですかね？
Oracle DatabaseのトランザクションはBEGINがいらない

## はじめに

RDBMSはMySQLしかほとんど触ったことがなく、先日初めて業務でOracle Databaseに触れました。
前任者が残した、マスタデータをINSERTする以下のようなSQLを目にし、「**なんで`BEGIN`がなくて`COMMIT`だけあるの？**」と困惑したので、調べて簡単にまとめました。

```sql
-- ユーザー種別
TRUNCATE TABLE user_types;
ALTER TABLE user_types MODIFY (id GENERATED ALWAYS AS IDENTITY (START WITH 1)) ;
INSERT INTO user_types(cd, name) VALUES (1, '一般ユーザー');
INSERT INTO user_types(cd, name) VALUES (2, '管理者ユーザー');
COMMIT;
```

ちなみに、前任者が`BEGIN`を書き忘れたわけではないです(笑)

## 調べたこと

### 結論

- 結論を言うと、Oracle Databaseは**常にトランザクションが有効**なので、`BEGIN`を書いて明示的にトランザクションを開始する必要がありません

- 終了するときは明示的に`COMMIT`または`ROLLBACK`を書く必要があります[^1]
    - トランザクション終了後、新しいSQLが実行されると、また自動的に新しいトランザクションが開始されます

### 注意点

:::note warn
明示的に`COMMIT`または`ROLLBACK`を実行したとき以外にもトランザクションが終了する場合があります。
:::

-  トランザクションの対象にならないSQL文（つまりDDL文等）が実行されるとき
- Oracle Databaseユーティリティおよびツールを正常に終了したとき

このようなとき、トランザクションは**暗黙的にコミット**されてしまいます。意図しないコミットにつながるので注意しましょう。

#### 補足と疑問点

後者について検証するため、Oracle SQL DeveloperでINSERT文を実行した後でウィンドウを閉じようとしたところ、コミットかロールバックをするようアラートを出してくれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/f14e7589-f665-7a1e-86d6-25473f815fec.png)

てっきり上記の「Oracle Databaseユーティリティおよびツールを正常に終了したとき」に当てはまって、暗黙的にコミットされると思ったのですが。。

マニュアル（「参考」参照）を確認したところ、以下の記載がありました。

> ノート:アプリケーションでは、プログラムを終了する前に、必ず明示的にトランザクションをコミットまたは取り消す必要があります。

これを見ると、Oracle SQL Developerは「Oracle Databaseユーティリティおよびツール」ではなく「アプリケーション」に当てはまるので、アラートが出たのかもしれません。

もし何かお分かりの方はコメントでご指摘いただけますと幸いです。

## 終わりに

1つのRDBMSに慣れきっていると、それが自分の中でSQLの常識になってしまい、他のRDBMSに触れたときに相違点があると驚きますね。

## 参考

https://docs.oracle.com/cd/F19136_01/cncpt/transactions.html

https://xtech.nikkei.com/it/article/COLUMN/20060328/233487/

[^1]:自動コミットを設定していない場合
Databricks にて NULL 列を保持する Pandas データフレームから Spark データフレーム変換時のアクセスモードによる挙動差異

## 概要

Databricks にて NULL 列を保持する Pandas データフレームから Spark データフレーム変換する際に、アクセスモード（シングルユーザーモードと共有アクセス モード）による挙動が異なる事象を確認したため共有します。2024年1月22日時点では、シングルユーザーモードでは void 型のカラムとしてスキーマを推論するのですが、共有アクセスモードではスキーマを推論できないというエラーとなってしまいました。

> PySparkValueError: [CANNOT_DETERMINE_TYPE] Some of types cannot be determined after inferring.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/fabe7536-c31d-c761-3a11-a0176f70fbd0.png)


本記事では、実行したコードとその結果、その対処方法を共有します。


## 実行したコードとその結果

### 1. シングルユーザーモードでの実行

### 1-1. 事前準備

```python
import datetime
from pyspark.sql import SparkSession

# create a sample DataFrame
expected_schema_01 = """
null_col   string
"""

expected_data_01 = [
    {
        "null_col": None,
    }
]

df = spark.createDataFrame(expected_data_01, expected_schema_01)
df.display()
pdf = df.toPandas()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/335cc744-0d7a-a433-e707-8901435ec763.png)

### 1-2. Pandas データフレームから Spark データフレームへの変換

```python
pdf_to_spark_df = spark.createDataFrame(pdf)
pdf_to_spark_df.printSchema()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/177b62fa-35a1-3a2d-a7bd-ba3931218eb6.png)

### 2. 共有モードでの実行

### 2-1. 事前準備

```python
import datetime
from pyspark.sql import SparkSession

# create a sample DataFrame
expected_schema_01 = """
null_col   string
"""

expected_data_01 = [
    {
        "null_col": None,
    }
]

df = spark.createDataFrame(expected_data_01, expected_schema_01)
df.display()
pdf = df.toPandas()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/4c877547-a91a-d45c-e80e-6c971eb01740.png)

### 2-2. Pandas データフレームから Spark データフレームへの変換

```python
pdf_to_spark_df = spark.createDataFrame(pdf)
pdf_to_spark_df.printSchema()
```

> PySparkValueError: [CANNOT_DETERMINE_TYPE] Some of types cannot be determined after inferring.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/c60ede3b-ee69-153c-5036-cf5827660810.png)


## 共有モードでの対処方法

### スキーマを指定する方法

```python
schema = """
null_col   string
"""
df = spark.createDataFrame(pdf, schema)
df.printSchema()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/c71cb8b1-045f-cded-0c8e-7679d4a91921.png)
`curl error 28 while downloading https://repo.packagist.org/packages.json` でLaravelインストールできない

# 
https://qiita.com/ucan-lab/items/56c9dc3cf2e6762672f4

こちらに沿って環境構築をしていた

# やりたいこと

[Laravelをインストールする](https://qiita.com/ucan-lab/items/56c9dc3cf2e6762672f4#laravel%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)

# 発生した問題
create project できない

```
root@6d7f8f27a943:/data# composer create-project --prefer-dist "laravel/laravel" .
Creating a "laravel/laravel" project at "./"


  [Composer\Downloader\TransportException]
  curl error 28 while downloading https://repo.packagist.org/packages.json: Operation timed out after 10004 milliseconds with 0 out of 0 bytes received


create-project [-s|--stability STABILITY] [--prefer-source] [--prefer-dist] [--prefer-install PREFER-INSTALL] [--repository REPOSITORY] [--repository-url REPOSITORY-URL] [--add-repository] [--dev] [--no-dev] [--no-custom-installers] [--no-scripts] [--no-progress] [--no-secure-http] [--keep-vcs] [--remove-vcs] [--no-install] [--ignore-platform-req IGNORE-PLATFORM-REQ] [--ignore-platform-reqs] [--ask] [--] [<package>] [<directory>] [<version>]
```

# 対応

https://laracasts.com/discuss/channels/general-discussion/composer-did-not-work

`composer diagnose`というトラブルシューティング用のコマンドがあるのでたたいてみたところ

```
root@6d7f8f27a943:/data# composer diagnose
Checking platform settings: OK
Checking git settings: OK
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
Checking github.com rate limit: OK
Checking disk free space: OK
Checking pubkeys: FAIL
Missing pubkey for tags verification
Missing pubkey for dev verification
Run composer self-update --update-keys to set them up
Checking composer version: You are not running the latest stable version, run `composer self-update` to update (2.2.22 => 2.6.6)
Composer version: 2.2.22
PHP version: 8.1.20
PHP binary path: /usr/local/bin/php
OpenSSL version: OpenSSL 1.1.1n  15 Mar 2022
cURL version: 7.64.0 libz 1.2.11 ssl OpenSSL/1.1.1n
zip: extension present, unzip present, 7-Zip not available
```
なんか`FAIL`になっている.
```
Checking pubkeys: FAIL
Missing pubkey for tags verification
Missing pubkey for dev verification
Run composer self-update --update-keys to set them up
```

指示に従って`composer self-update`を実行

```
root@6d7f8f27a943:/data# composer self-update
Upgrading to version 2.6.6 (stable channel).

Use composer self-update --rollback to return to version 2.2.22
```

そして、再度create project してみる
```
root@6d7f8f27a943:/data# composer create-project --prefer-dist "laravel/laravel" .
Creating a "laravel/laravel" project at "./"
Installing laravel/laravel (v10.3.2)
  - Downloading laravel/laravel (v10.3.2)
  - Installing laravel/laravel (v10.3.2): Extracting archive
  ...
  ...
  ...
```

無事 create project できた
boto3 dynamodbの batch_write_item()と batch_writer() どちらを使うべきか

## 結論
batch_writer() を使うべき。
理由：batch_writer() は batch_write_item() をwrapして便利に使えるようにしているものだから。

## [batch_write_item()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/batch_write_item.html)
DynamoDBテーブルに対してアイテムを削除するboto3のAPIとして、[delete_item](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/delete_item.html)や[put_item](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/put_item.html)がありますが、複数アイテムを削除しようとすると都度APIをコールするのでパフォーマンスがよくありません。※1
そこで、batch_write_item()を使って一括で削除・追加処理を実施できるのですが、以下のデメリットがあります。
- 1回のリクエストで処理できるのは25個ずつ
- 追加（削除）に失敗したアイテムに対するハンドリングは独自実装する必要がある

## [batch_writer()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/batch.html)
batch_writer()はbatch_write_item()のデメリットを解消（内部で処理）してくれています。くわしくはクラスメソッドさんの[こちら](https://dev.classmethod.jp/articles/lambda-python-dynamodb/)の記事がわかりやすいです。

自分は当初、delete_item()やput_item()を内部的に呼び出しているのだと勝手に思っていましたが、実装を確認するとbatch_write_item()を呼び出していました。

```python
# https://github.com/boto/boto3/blob/develop/boto3/dynamodb/table.py#L63
class BatchWriter:
    """Automatically handle batch writes to DynamoDB for a single table."""

    def __init__(
        self, table_name, client, flush_amount=25, overwrite_by_pkeys=None
    ):

略

# https://github.com/boto/boto3/blob/develop/boto3/dynamodb/table.py#L141
    def _flush(self):
        items_to_send = self._items_buffer[: self._flush_amount]
        self._items_buffer = self._items_buffer[self._flush_amount :]
        response = self._client.batch_write_item(
            RequestItems={self._table_name: items_to_send}
        )
        unprocessed_items = response['UnprocessedItems']
        if not unprocessed_items:
            unprocessed_items = {}
略
```



## 参考
- ※1: クラスメソッドさんの[検証記事](https://dev.classmethod.jp/articles/dynamodb-delete-item-all/)より
> RCUとWCUが1に指定されているテーブルでデータ削除の検証をしてみたところ、100件の削除に10秒程度、1000件の削除に12分弱かかりました。数千レコード程度のオーダーであれば大丈夫そうですね（ちなみにDeleteItemバージョンでは100件の削除に1分30秒ほどかかっていました）
割り込み処理の大まかな流れについての解説

# 割り込み処理について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092001/7343481a-5998-6876-6148-39a10f95539b.png)



この処理の概要及びそのために必要なものについて最低限説明する。

---

## 実際のコードの動きを追走しジャンプの動きを確認する

[１２ステップでできる組込みOS入門](https://kozos.jp/books/makeos/)のコードを参考にし、実際の割り込みの動作を確認する。
アセンブリコードで大まかな一連の流れが確認できる。
PCとコントロールレジスタの保存、特権モードへの切り替えはハードウェア側で自動で行われるため割愛する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092001/d22810e4-cfa6-a944-df3e-5863fce84d82.png)


rteは割り込み復帰命令である。割り込み復帰命令については後述する。



### mov.w #SOFTVEC_TYPE_SERINTR, r0について

r0に対して#SOFTVEC_TYPE_SERINTRを代入する命令である。
そして、 r0,er1共に下の ＠_interruptに渡す引数である。
interruptの本体である関数は第一引数に割り込みの種類、第２引数にspを取る。
つまり、**interruptは#SOFTVEC_TYPE_SERINTRとer1を引数として処理を実行する**

```c
void interrupt(softvec_type_t type, unsigned long sp)
{
  softvec_handler_t handler = SOFTVECS[type];
  if (handler)
    handler(type, sp);
}
```
interruptの役割は、関数ハンドラの実行である。
handlerに対して割り込みベクタに設定されている関数ハンドラを代入し、handlerが取得できた場合、ハンドラを実行する様になっている。

今回、ハンドラとして登録されている関数はmainを見ると確認できる
```c
int main(void)
{
  INTR_DISABLE;　//CCRの１ビットを上げる。CPUの割り込み処理を無効化

  puts("kozos boot succeed!\n");

  softvec_setintr(SOFTVEC_TYPE_SERINTR, intr);
  serial_intr_recv_enable(SERIAL_DEFAULT_DEVICE);

  puts("> ");

  INTR_ENABLE;//CCRの１ビットを落とし。CPUの割り込み処理を有効化
  while (1) {
    asm volatile ("sleep");
  }

  return 0;
  //このwhileループは通常、省電力モードでCPUの命令実行を停止させ、割り込みが発生することで動作します。これにより、割り込みドリブン（割り込み駆動） の仕組みを利用して、CPUの消費電力を制御しています。
}
```
softvec_setintr関数では、ハンドラとその種類を指定しており、具体的にはSOFTVEC_TYPE_SERINTRに対応するintr関数が今回実行されるハンドラ関数であることが理解できる。

実際のコードを追うことで、ジャンプがどのように処理され、ハンドラ関数がどのように実行されるのかがより理解できる。

---

# 割り込み復帰命令

ジャンプで関数を実行したあとは復旧を行う必要がある。
先述のアセンブリでは汎用レジスタの復旧のあと、 rteという割り込み復帰命令が行われていた。
これはこの本で使用されているH8マイコンの割り込み復帰命令である。この割り込み復帰命令では、PCとコントロールレジスタの値を復旧する。

以上を行うことで中断していた箇所から再開することができる。


---

# まとめ

* 特権モードに切り替え、
* 現在のPC,コントロールレジスタの値を保存する
* 汎用レジスタの情報を保存する
* 割り込みハンドラのアドレスを取得し、PCを割り込みハンドラに書き換え実行する
* 保存した汎用レジスタを復旧する
* PCとコントロールレジスタの復旧


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092001/137f8117-10e2-49db-32ca-928db4404afc.png)


以上の流れで、割り込み処理を実行することができる。
[React] MUI - ボタン押下後にMenuコンポーネントでメニューを開いた後、メニュー枠外をクリックしても閉じない現象を解消する方法

# はじめに
今回、MUIの勉強中にタイトルのような現象が起きて結構詰まってしまい、先日対処法を見つけたので備忘録として残しておきます。

# 結論
MenuコンポーネントのPropsの`onClose`を指定する

```typescript
import { IconButton, Box, Menu, MenuItem } from "@mui/material";

import IcFlagEnSVG from "@/assets/icons/ic_flag_en.svg";

import React, { useState } from "react";

export const LanguageSelector = () => {
    const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
    const open = Boolean(anchorEl);

    const handleOpen = (e: React.MouseEvent<HTMLElement>) => {
        setAnchorEl(e.currentTarget);
    };

    const handleClose = () => {
        setAnchorEl(null);
    };

    return (
        <>
            <IconButton sx={{ width: 40, height: 40 }} onClick={handleOpen}>
                <Box component="img" src={IcFlagEnSVG} alt="country flag" sx={{ width: "24px" }} />
            </IconButton>
            // ↓onCloseを追記！
            <Menu open={open} anchorEl={anchorEl} variant="selectedMenu" onClose={handleClose}>
                <MenuItem onClick={handleClose} selected>
                    English
                </MenuItem>
                <MenuItem onClick={handleClose}>German</MenuItem>
                <MenuItem onClick={handleClose}>French</MenuItem>
            </Menu>
        </>
    );
};

```
LifeKeeper for Linux コマンドあんちょこ(Ver9.2.1)

# LifeKeeper for Linux コマンドあんちょこ(Ver9.2.1)

[LifeKeeperドキュメントリンク](http://jpdocs.us.sios.com/)
※各CommandのPathは、「``/opt/LifeKeeper/bin/``」です。

## ●LifeKeeper自体
|内容|コマンド|参考|HAモニタでのコマンド|
|:--------------|:------------|:-----------------|:---------|
|LK停止|lkstop|  |monstop
|監視一時停止|lkstop -f||
|LK起動|lkstart||monstart
|LK起動確認|lktest|プロセス(lcm,lcd,ttymonlcm)が表示さていればLK起動状態|monshow
|License適用|lkkeyins file|フルパスまたは相対パス|
|License確認|typ_list -l|UNLICENSED=Core License適用<br>EVAL=Temporary License適用<br>EVAL=Temporary License適用<br>PERMANENT=Recovery Kit適用<br>NEEDED=Recovery Kit不適用||       
|SwitchBackType     |ins_list                         |INTELLIGENT=無効(default)<br>AUTOMATIC=有効 |
|設定flag一覧|flg_list|||
|flag作成|flg_create [-d destname] -f flag |flag：フラグファイル名<br>destname：サーバー名|
|flag削除|flg_remove [-d destname] -f flag |flag：フラグファイル名<br>destname：サーバー名||
|ログの参照|lk_log [-t number] [-f] log|number：行数(整数値)<br>-fオプションはリアルタイム<br>/var/log/lifekeeperを参照可|
|ノード指定のコマンド実行|lcdremexec -d destname -- "command"|destname：サーバー名<br>command：実行コマンド|
|リソースインスタンスの一覧|ins_list [-f x]|x：任意の区切り文字||
|Pathの状態確認|net_list [-f x]|[指定内容] x：任意の1文字(区切り文字)<br>ALIVE=ノード間の通信可<br>DEAD=ノード間の通信不可|monsp<br>monpath|


## ●GUI
|内容|コマンド|参考 |
|:---------|:-------------------|:--------------------------|
|GUIClient起動|lkGUIapp||
|GUIServer起動|lkGUIserver start||
|GUIServer停止|lkGUIserver stop||


## ●リソース
|内容|コマンド|参考|HAモニタでのコマンド|
|:------------|:---------------------|:------------------|:------------------|
|リソース状態|ins_list [-f x]|x：任意の区切り文字<br>ISP=Active<br>OSU=Standby<br>OSF=Failed|monshow|
|リソース状態一覧|lcdstatus [-d destname]|destname：サーバー名|monshow|
|リソース起動|perform_action -t tagname -a restore [-b] |tagname ：リソース名<br><br><br><br>|monbegin|                           |
|リソース停止|perform_action -t tagname -a remove|tagname ：リソース名|monend|
|switch over/switch back|perform_action -t tagname -a restore [-b] |tagname ：リソース名|monswap|

## ●レプリケーション
|内容|コマンド|参考|
|:---------|:----------------------|:----------------|
|Replication状態|mirror_status tagname|tagname ：リソース名|
|Replication一時停止|mirror_action tagname pause [source] [target]|tagname ：リソース名<br>source：ミラー元サーバ<br>target：ミラー先サーバ|
|Replication再開|mirror_action tagname resume [source] [target]| 
|Replication全同期|mirror_action tagname fullresync [source] [target]|
|Replication強制開始|mirror_action tagname force [source] [target] | 

## ●ポリシー管理
|内容|コマンド|参考 |
|:------------|:------------------|:---------------|
|ポリシー確認|lkpolicy -g -v|-gオプション:デフォルトから変更された箇所のみ出力|
|特定のリソースのfailover無効化|lkpolicy -s Failover -E tag="tagname" ||
|特定のリソースのfailover有効化 |lkpolicy -s Failover -e tag="tagname"||
|特定のリソースのlocal recovery無効化|lkpolicy -s LocalRecovery -E tag="tagname"||
|特定のリソースのlocal recovery有効化|lkpolicy -s LocalRecovery -e tag="tagname"|
|local recovery回数超過によるfailover有効化|lkpolicy -s TemporalRecovery -e recoverylimit=number period=number|number：整数値|

## ●その他
|内容|コマンド|参考|HAモニタでのコマンド|
|:--------|:-----------------|:------------------|:------------------|
|LK構成情報のbackup|lkbackup -c [--cluster]||
|LK構成情報のrestore|lkbackup -x -f filepath||
|hostname/ IPアドレスの変更|lk_chg_value -o old_value -n new_value -v |
|LK情報の一括取得|lksupport [--full]||monts|
GitHub ActionsでJSON形式のトークンがそのまま使えない


Node.js v21で実行していたプログラムをBunでの実行に差し替えた時に

GitHub Actions上かつBunでの実行でエラーが発生しました。

## Googleのクレデンシャルでエラー発生

```
const {client_secret, client_id, redirect_uris} = credentials.installed;
```

> ![スクリーンショット 2023-12-28 22.25.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/4dad3773-266a-8fe9-134b-e20124e785c0.png "スクリーンショット 2023-12-28 22.25.24.png")

この辺たまにでますねトークンのJSONをそのまま入れていてクオーテーション周りがうまくパースされない問題ぽいです。

```
TOKEN ENV READ ERROR: SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)
```

ローカルでは読めるんだけどね

## そもそも構造化データをGitHub Actionsのシークレットにいれてはいけないらしい

[公式にも書いている通り](https://docs.github.com/ja/actions/security-guides/using-secrets-in-github-actions)Base64変換してBase64変換したテキストをシークレットに入れるなど工夫が必要そうです。

- 参考

https://soypocket.com/it/github-actions-json-secrets/

https://zenn.dev/n0bisuke/scraps/df7dc2c9eaeb54


## シングルクォートで応急措置

とはいえちょっとすぐ動かしたかったので応急措置です。

シングルクォートで囲むことで回避できました。

- 通常

通常はこんな感じでJSONをそのままシークレット登録してました。

```bash
GOOGLE_REDENTIALS={"access_token":"色々省略","token_type":"Bearer","expiry_date":1703526591588}
```

これだとローカル実行はいけて、GitHub Actions上（のBun）だとJSON.parseのエラーが出ます。

- シングルクォートで囲ってみ

全体を''で囲むことで今回は回避できました。

```bash
GOOGLE_REDENTIALS='{"access_token":"色々省略","token_type":"Bearer","expiry_date":1703526591588}'
```

これだとローカルの`.env`ファイルからもGitHub Actions上からもいけます。

~~`.env`に書くときもシングルクォートで囲むをやっておくと良いかもですね（）~~ そもそもJSONそのままいれるのやめましょう。


## おまけ create-json

試してないけどcreate-jsonというアクションを利用する方法もありそう

https://github.com/jsdaniell/create-json

https://zenn.dev/ikepon/scraps/9fe2c471c17bb3
コミットメッセージをとことんよくするツールを作ってみた件

## コミットメッセージをとことんよくしよう

はい、どうもこんにちは。趣味でプログラミングやってるあかつきゆいとです。

ところでですね、最近、デジタルサークルと題して、UniProjectというサークルを立ち上げました。

https://unipro-tech.github.io

そこで、コミットメッセージをみんな統一していい感じにしたいという野望が生まれまして...

今回の話に至りました。

## いいコミットメッセージとは

https://www.conventionalcommits.org/ja/v1.0.0/

これを参考に、

```
プレフィクス(絵文字) 概要
本文
```

ってする感じで。

## メッセージテンプレ

https://gizumo-inc.jp/media/git-operation/

これを参考にさせていただき、ちょっと使いそうなものや使わなさそうなプレフィクスを改変して、こんな感じに。

```.gitmessage
# ==== Format ====
# ${prefix}: 実装の概要を50文字以下で記述
# ex)fix:ユーザー情報にnameが足りないのでnameを追加
#
# コミット本文(50文字で収まらない場合はこちらに)...
#一行目の上に#をつけずに入力してください。

# ==== Prefix ====
# feat 新規機能、新規ファイル追加
# delete ファイル削除
# fix バグ修正
# style 空白、セミコロン、行、コーディングフォーマットなどの修正
# refactor リファクタリング
# uppkg 依存関係のアップグレード
# chore ビルド、補助ツール、ライブラリ関連、開発環境変更、更新等
# docs ドキュメントのみ修正
# tag タグの作成
# typo タイポ

# ==== Rules ====
# 1. コミット本文を記述する場合は、概要とコミット本文の間に空行1行あける
# 2. 概要は50文字以下で記述する
# 3. 概要の末尾はピリオドで終わらない
# 4. 概要は命令法で記述する
# 5. 本文は72文字で改行する
# 6. 本文ではhowではなくwhatとwhyを記述する
```

あとは、

```
git config git config commit.template /path/to/.gitmessage
```

をぶっ叩くだけ。

## git hooks

でも、わざわざ絵文字入力はめんどくさい。
というか、テンプレに絵文字を書かなかったのは、これを後で思いついたからです。

https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF

なんかgit hooksなるものがあるらしく、それを使いました。
で、これ、ほんとはgitフォルダの中のhooksとやらに入れとかなきゃいかんらしい。
でも、リポ内に含まれないので設定ガチャガチャw

```.githooks/commit-msg
#!/bin/bash
COMMIT_MSG=$1
prefix=$(head -n 1 $COMMIT_MSG | awk '{ print $1 }')

emoji=""
case $prefix in
 "fix:")
   emoji=":bug:"
   ;;
 "feat:")
   emoji=":sparkles:"
   ;;
 "hammer:")
  emoji=":hammer:"
  ;;
 "delete:")
   emoji=":zap:"
   ;;
 "uppkg:")
   emoji=":arrow_up:"
   ;;
 "docs:")
   emoji=":memo:"
   ;;
 "style:")
   emoji=":art:"
   ;;
 "refactor:")
   emoji=":recycle:"
   ;;
 "chore:")
   emoji=":hammer:"
   ;;
 "tag:")
   emoji=":bookmark:"
   ;;
 "typo:")
   emoji=":pencil2:"
   ;;
 *)
   echo "The specified prefix is undefined.";
   exit 1
   ;;
esac

sed -i "s/$prefix/$emoji/" $COMMIT_MSG

echo $prefix 
exit 0
```

これで、

```
git config --local core.hooksPath .githooks
```

うん、よし。

ちなみに、gitmojiはもう入ってる前提です。

## これを汎用化しようぜ

汎用化という言葉があっているかは知りませんが、だれでも簡単にできるようにしてみました。

流れとしては

```
githooks、テンプレコピー
↓
共同制作者用のスクリプト設置
↓
git周りの設定
```

を自動でやってくれるスクリプトです。

ここでは割愛させていただきます。パス通ってるところに置くと、

```
git ファイル名
```

で動きます。共同制作者さんは、`colab_script.sh`を実行するだけでせっとぃがすべて完了するという優れもの。

## 最後に

コミットメッセージって効率化すると見やすくて便利(当たり前)

リポはこちら↓
実装めんどくさい人はこれのREADMEどおりに設定すれば動きます。

https://github.com/UniPro-tech/UniPro-Git-Tool
ActiveHashの初期値を設定したらエラーメッセージが出てこなかった件

# はじめに
プログラミング初心者ですので、、温かく見守って頂けると幸いです。
何か間違っていたらコメントお願いします。
# エラーメッセージが出てこない
[![Image from Gyazo](https://i.gyazo.com/47e4958e4b02fbe12628de441de857c8.png)](https://gyazo.com/47e4958e4b02fbe12628de441de857c8)
ActiveHashを使用した入力フォームの初期値に上記のような初期値を設定していましたが、そうするとエラーメッセージが出ないという状況に陥りました。
しかも、初期値ではエラーメッセージ出ないのに、普通に項目を選択して保存しようとすると、"Category can't be blank"というエラーが、、、（選択してるのに、、、）

# 解決
原因ははっきりしていませんが、修正した箇所としては、
idを0~から始めるのではなく1~から始めた。（上記の画像は修正後）
ビューのnew.html.erbの
**<%= f.collection_select(:category_id, Category.all, :id, :name, {include_blank: true}, {class:"select-box", id:"item-category"}) %>**

**を**

**<%= f.collection_select(:category_id, Category.all, :id, :name, {}, {class:"select-box", id:"item-category"}) %>**

に修正（{include_blank: true}の部分を削除しました。）
これでエラーメッセージが正常に出るようになりました。

#### ちなみに
[![Image from Gyazo](https://i.gyazo.com/a8401945b36480f3bf9aa2de3ce9332a.png)](https://gyazo.com/a8401945b36480f3bf9aa2de3ce9332a)
こちらの status: :unprocessable_entity の書き忘れでエラーメッセージが出ない場合もあるとのこと。
自分はなんとなくで記載していたので、初めて知りました。

# 追記
後から原因がわかりました。
バリデーションでid:1を選択した場合は保存ができないように設定していました。
だから、idが0だと保存されてしまうし、きちんとカテゴリーを選択していてもエラーメッセージが出てしまっていたんですね。
これにて解決。
Instagram URL Schemes


Here are the known URL schemes for Instagram that can be used to link directly to specific parts of the Instagram app. It is useful for Apple Shortcuts.

| URL Scheme                              | Description                          |
| --------------------------------------- | ------------------------------------ |
| `instagram://`                          | Open the Instagram app               |
| `instagram://settings`                  | Open the Instagram settings          |
| `instagram://direct-inbox`              | Open direct messages                 |
| `instagram://camera`                    | Open the camera or create a new post |
| `instagram://explore`                   | Open the explore tab                 |
| `instagram://user?username=[username]`  | Open a specific user's profile       |
| `instagram://location?id=[location_id]` | Open a specific location             |
| `instagram://tag?name=[hashtag]`        | Open a specific hashtag              |


## Examples


### Open the Instagram App Settings via Apple Shortcuts

1. Use the "Text" Action to store `instagram://settings` in a text variable
1. Use the "Get URLs from Input" to convert the text variable to a URL
1. Use the "Open URLs" Action to open the URL

Apple Shortcuts: [Example - Open Instagram Settings](https://www.icloud.com/shortcuts/5fd2b8567505424080239aebdb06989b)


### Open a Specific User's Instagram Profile via Apple Shortcuts

1. Use the "Ask for Input" Action to ask for a username
1. Use the "Text" Action to store `instagram://user?username=` in a text variable
1. Use the "Combine Text" Action to combine the username to the text variable:
    * Combine `instagram://user?username=` with the username's Provided Input with "Custom" set to `` (nothing)
1. Use the "Get URLs from Input" to convert the "Combine Text" value to a URL
1. Use the "Open URLs" Action to open the URL

Apple Shortcuts: [Example - Open A Instagram Profile](https://www.icloud.com/shortcuts/fbc84a967b044b539cf9603f7a7dc1a6)


### Search for a Specific Hashtag on Instagram via Apple Shortcuts

1. Use the "Ask for Input" Action to ask for a hashtag
1. Use the "Text" Action to store `instagram://tag?name=` in a text variable
1. Use the "Combine Text" Action to combine the hashtag to the text variable:
    * Combine `instagram://tag?name=` with the hashtag's Provided Input with "Custom" set to `` (nothing)
1. Use the "Get URLs from Input" to convert the "Combine Text" value to a URL
1. Use the "Open URLs" Action to open the URL

Apple Shortcuts: [Example - Search For A Hashtag](https://www.icloud.com/shortcuts/fb76c58b97194b909611d61a90e00609)


## References

* [Loggy/instagram-deeplink](https://github.com/Loggy/instagram-deeplink)
* [bhagyas/app-urls: A long list of App URLs for iOS, macOS and Android](https://github.com/bhagyas/app-urls)
* [tristinDLC's Reddit Post](https://www.reddit.com/r/shortcuts/comments/xnrz7t/comment/ipvnubg/)