OmniAICreator/Qiita-1.07M huggingface dataset:
【Virtualbox】ユーザの作成

# 1.目的
管理ユーザと一般ユーザを分け、セキュリティリスクを抑えるために、一般ユーザを作成する。

# 2.前提
PC：Windows11
Virtualbox：Virtualbox 7.1.4
OS：Centos Stream release 10
管理者ユーザ：root
作業用ユーザ：user

# 3.作業
①前回起動したCentosにログインする。
②ユーザ一覧を表示させる
```
cut -d: -f1 /etc/passwd
```
③ユーザの作成
```
sudo useradd username
```
④ユーザへのパスワード付与
```
sudo passwd username
```
プロンプトが表示されるため2回パスワードを入力する。
⑤ユーザの作成確認
```
cat /etc/passwd | grep username
```

# 4.最後に
最後までお読みいただきありがとうございます。
来週は、作成したサーバにwebサーバとしての機能を追加していこうとおもいまｓ。
では、また来週^^
VSCodeで一瞬でSOME_VARをsome_varに変換したい

# はじめに

変数や関数名といった識別子を、別の命名規則のものに置き換えたくなる時があると思います。
そういった時のために、VSCodeには識別子を特定の命名規則のものに変換する機能があります。

<details><summary>そもそも命名規則とは？</summary>
"snake_case"や"camelCase"のように、単語の区切りに"_"を使ったり語頭を大文字にしたりといった、識別子の名付けに関する取り決めのことです。

詳しくは以下の記事を参考にしてみてください。
https://qiita.com/shota0616/items/4ac7a8696b3f6ccbe2bc
</details>


# 方法

まず、変換したい識別子を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3027191/1a894d02-8e33-0f29-10bc-33f419eaf96d.png)

そして、コマンドパレット(⇧⌘P)から、"transf"で検索し、目的の変換を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3027191/177e673b-bfdc-1947-346c-12e57d109b3b.png)

たったのこれだけで、識別子が一括で変換されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3027191/4482d799-db25-898f-0fae-2cea88b31721.png)


上の画像にある通り、全部で7種類の変換が用意されているようです。



# おまけ

よく使う変換はショートカットに登録しておくと便利です。
コマンドパレットの右側に表示される歯車、あるいは直接キーボードショートカット(⌘K⌘S)から変更できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3027191/7bb18a6a-ab6e-c3ea-25db-3b5ecbd321ec.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3027191/b162ed61-4367-b76b-53b2-df3d7ecd6195.png)
【振り返り】2025年

# 目的
年末一気に振り返るのでなく、細かく振り返り、修正していくことでモチベーション維持を継続する。月末に更新していく予定。  

# 今年の目標
転職できる力を身に着ける。具体的には以下を目指す。
- AtCoderで茶色レート

https://atcoder.jp/?lang=ja

https://info.atcoder.jp/utilize/jobs/rating-business-impact

# 目次
- [月間修行時間](#月間修行時間)
- [1月](#1月)
- [2月](#2月)
- [3月](#3月)
- [4月](#4月)
- [5月](#5月)
- [6月](#6月)
- [7月](#7月)
- [8月](#8月)
- [9月](#9月)
- [10月](#10月)
- [11月](#11月)
- [12月](#12月)

# 月間修行時間
[Studyplus](https://app.studyplus.jp/users/4017ea64da8b40f7b9ab17ff2e910f39)で記録していた修行時間を月毎に記録する。

| 月 | 勉強時間 | 月 | 勉強時間 |
| :---: | :---: | :---: | :---: |
| 1月 | 31時間35分 | 7月  |  |
| 2月 | 30時間20分 | 8月  |  |
| 3月 | 31時間5分 | 9月  |  |
| 4月 | 36時間55分 | 10月 |  |
| 5月 | 21時間50分 | 11月 |  |
| 6月 |  | 12月 |  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641184/0bc2adcc-71d2-4c4b-ad34-e97a2bfc406c.png)

# 1月
今月はAtCoder参加と[アルゴリズム的思考力が身につく! プログラミングコンテストAtCoder入門](https://www.amazon.co.jp/%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E7%9A%84%E6%80%9D%E8%80%83%E5%8A%9B%E3%81%8C%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8F-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88AtCoder%E5%85%A5%E9%96%80-%E5%A4%A7%E6%A7%BB-%E5%85%BC%E8%B3%87/dp/404604408X)の修行をした。よく使われるアルゴリズムを例題、類似問題を使いながら解説してくれるためかなり進めやすい。
今年の目標に向かって修行をつづける。

# 2月
今月も7時間/週を目標に行った。最近は朝から晩まで仕事だったため夜中に修行していたため中々ハードな生活だった。我ながらよく頑張ったと褒めたい。（まだもう少しこの生活が続くが、、、）
修行の内容は先月から引き続きアルゴリズムの方を進めていた。AtCoderへの参加率は隔週くらいだったが、まぁしょうがない。
また、問題を解いてすぐにレートに反映される[paiza](https://paiza.jp/)も始めた。すぐにレート変動が行われるため、思った以上にハマる。ちなみに2月末でBレートでした、Aレート目指して精進します。

https://paiza.jp/

# 3月
今月は仕事が忙しく月の半ばまで思うように時間が取れなかったが、その後はきちんと時間が確保できてよかった。こういう終われている生活も嫌いではないと思った。
今月もpaizaとAtCoderを行った。なかなか思うようにスコアは上げられなかったが、先日paizaはレートAに、AtCoderではC問題を時間内に解くことができた。少しずつ着実に成長していっていると実感できた月だった。
また、今月は転職活動にも時間を割いた。自分がこれまで経験した仕事・得られた知識など棚卸する良い機会だった。実際に転職するしないは置いておいて、自分について振り返るのは大事だと思った。
来月から社会人5年目が始まる。急に何かが変わるわけではないが、改めて気持ちを引き締めて過ごそうと思った。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641184/14fe63df-8698-46d6-a705-7c23d6a7f5a9.png)

# 4月
今月は修行より別のことに時間を割いていたので、実際の修行時間はもうすこし少ない。新入社員も入ってくるので、お手本とまではいかないが後輩からも信頼される振る舞いを心掛ける。

また、paizaでSランク問題へ挑戦したら解けてしまった！まだ1問しか解けていないが、Sランクになることを目標にしていたので嬉しすぎる。今月は結果として20問弱解いたみたいだが、特に月の目標は決めていない。5月も解いていく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641184/6f8441e2-5ec7-4b68-ba7b-09d360027793.png)

# 5月
今月はあまり修行時間が確保できなかった。原因は平日の夜にサボってしまったり、土日は予定があり思うように時間確保ができなかったからだ。土日はいいとして、平日は全力でやりきると決めていたのに最近たるんできている。何とかモチベーション回復を行わなければ、、、。

paizaの問題も3問しか解いていない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641184/9bfde75a-2ffd-49e3-8a77-367961b1daa4.png)

最近は以前読んだ本を読み返している。当時は気になるページへ付箋を貼り、コメントを書いていたので、どういうことを思って読んでいたかを思い出せて少し楽しい。

# 6月

# 7月

# 8月

# 9月

# 10月

# 11月

# 12月
【Laravel × Docker】Laravel Sailを使う

## Laravel Sailとは？
Docker環境で構築されたLaravelアプリケーションを操作するための軽量なCLIです。
Dockerの経験・知識がない開発者でも、Sailコマンドを使えばDocker × Laravelの開発をスムーズに進めることができます。

https://laravel.com/docs/11.x/sail

## Sailを使うメリット
Sailを使う具体的なメリットを紹介します。
### 環境構築がかんたんにできる
通常であれば PHP、MySQL、Redis、Node.jsなどを手動でインストール・設定する必要がありますが…
Sailの場合、`./vendor/bin/sail up`コマンドだけで、必要なコンテナ（Webサーバー、データベース、キャッシュなど）が自動的に立ち上がります。

### コマンドがシンプルに書ける
例えばDockerで複数のコンテナ（アプリケーションコンテナ、DBコンテナなど）を起動している場合、アプリケーションコンテナでphpコマンドを実行したい場合は、コンテナを明示的に指定する必要があります。
こんな感じ↓
```bash
# docker-compose exec app で、アプリケーションコンテナを指定する必要がある
docker-compose exec app php artisan migrate
```
こうやって毎回`docker-compose exec app`を頭につけるのは面倒くさいですよね。
ですが、sailをインストールするともっとシンプルなコマンドで済みます。
```bash
sail artisan migrate
```
:::note
Sailは自動的に対象のコンテナを認識し、Laravelの環境に合わせたコマンド実行を行ってくれます。
:::

## Laravel Sailのインストール

### インストール
```bash
composer require laravel/sail --dev
```

### Sailを使うために必要な`docker-compose.yml`や`.env`の設定を行う
```bash
php artisan sail:install
```

基本的にはこれだけでSailコマンドが使えるようになります。
例えば、コンテナを起動したければ以下のコマンドで起動できるはずです。
```bash
./vendor/bin/sail up
```

## エイリアスを設定する
ここまでだと、Sailコマンドを使うためには毎回 `./vendor/bin/sail`と入力する必要があります。
これが面倒だと感じる場合は、エイリアスを設定することをお勧めします。

### ターミナルの設定ファイルに以下を追記
```bash
# Bashを使っている場合
echo "alias sail='bash ./vendor/bin/sail'" >> ~/.bashrc
# Zshを使っている場合
echo "alias sail='bash ./vendor/bin/sail'" >> ~/.zshrc
```
### 設定を反映させる
```bash
# Bashの場合
source ~/.bashrc
# Zshの場合
source ~/.zshrc   
```
:::note
ターミナルの設定ファイルに変更を加えると、シェルがその変更を認識するためには、改めて設定ファイルを読み込ませる必要があります。
`source ~/.bashrc`を実行することで、現在のシェルセッションに変更内容を即座に反映させることができます。
:::

## まとめ
Laravel Sailを使えば、アプリケーションコンテナなどを指定せずとも、以下のようなシンプルなコマンドで操作が可能になります！
ぜひ試してみてください。
```bash
# コンテナを起動する
sail up -d
# コンテナを停止する
sail down
# マイグレーションファイルを実行する
sail artisan migrate
```
apacheのアクセスログが出力される時間と出力される順番について

## 本記事でやりたいこと
会社で障害対応や顧客からの問い合わせを受けた際に、apacheのアクセスログを調査する機会があります。
その中で、「〇〇したはずが反映されていない」などの問い合わせの際にアクセスログに出力された時間と関連処理でDBに登録されたレコードを比較することがあります。

ミリ秒単位の差で結果が変わってくる場合は出力されている時間はレスポンスを受けたときなのか、完了したときなのかでさえも調査結果が変わる為、頭の中を整理する為の記事です。

## 最初に結論
・出力される【時間】はアクセスされた時間
・出力される【順番】はリクエストが終わりレスポンスを返したとき

## 検証
このようなファイルを作成します。
```nontest.php
<?php
// アクセス時刻をログに記録する（デバッグや確認用）
error_log("Accessed: " . date("Y-m-d H:i:s"));

// 30秒間待機
sleep(30);

// レスポンスを表示（適宜変更可能）
echo "30秒が経過しました。";
?>

```

出力結果は以下のようになりました。

テスト用に作成したファイルにアクセス→その後にphpinfoを二回開く、ということをやりました。

[Sat Jan 25 15:18:03.782944 2025] Accessed: 2025-01-25 07:18:03

::1 - - [25/Jan/2025:15:18:06 +0900] "GET /dashboard/phpinfo.php 
::1 - - [25/Jan/2025:15:18:20 +0900] "GET /dashboard/phpinfo.php 
::1 - - [25/Jan/2025:15:18:03 +0900] "GET /dashboard/nontest.php 

結論の通りになりました。

##途中でバッファを吐いたらどうなるか
以下のように途中でバッファを吐いてみる
```
<?php
// アクセス時刻をログに記録する（デバッグや確認用）
error_log("Accessed: " . date("Y-m-d H:i:s"));

// 30秒間待機
sleep(5);

// レスポンスを表示（適宜変更可能）
echo "5秒経過";
ob_flush();
flush();

sleep(30);

echo "5+30秒が経過しました。";
?>

```

[Mon Feb 17 15:15:39.776441 2025] Accessed: 2025-02-17 07:15:39

::1 - - [17/Feb/2025:15:15:41 +0900] "GET /dashboard/phpinfo.php 
::1 - - [17/Feb/2025:15:15:43 +0900] "GET /dashboard/phpinfo.php 
::1 - - [17/Feb/2025:15:15:39 +0900] "GET /dashboard/nontest.php 

結論は変わらない、画面にはバッファが吐かれたときに反映するが、アクセスログの出力順には影響しｎ
pywinauto でクラス名やキャプション名を得る

# Python で他のアプリをコントロールする
VBA で Win32API を利用し、クラス名やキャプション名からのウィンドウハンドルを取得して、SendMessage や PostMessage を駆使して TextBox に文字を放り投げたり、ComboBox を選択したり、Button をクリックしたりという事 **(以下①)** もやりました。

VBA で、UIAutomation を利用し、エレメントを取得して操ったりする事 **(以下②)** もありました。
(なんで IsInvokePatternAvailable が False なんだよ！って怒ったりね)

でも、最近は「Python でお願い」されることが増えました。
以前、win32gui と言うのを使って**①**を行った事はあるんです。
win32gui だと、**①**の方法を、VBA に近い記述で組めるけど、**②**の機能はない(と思う)。
という訳で色々探してたら、pywinauto と言うのが、**①**にも**②**にも対応してるっぽい。
(PyAutoGUI というのもあったけど、②に対応しているかどうかわからないので今回は未確認)

余談ですが、win32guiのインストールは、`pip install win32gui`じゃなくて`pip install pywin32`

# pywinauto の良い所
pywinauto のドキュメントは英語なんですよ・・・
https://pywinauto.readthedocs.io/en/latest/contents.html
ワタシィ、エイゴォ、ワッカリマセェ〜ン、タメィゴゥ

しかし、**①**も**②**も対応なんて、使わない手はない。

しかも、VBA で組むと全然コードが違う**①**と**②**が、ほぼ同じ記述の仕方で組めるように Wrap されてる！

ちなみに、`pip install pywinauto`を眺めてると分かりますが、win32gui も使用している様です。
# pywinauto で、意外と見つけにくかった情報
### pywinauto で、よく見るやり方
```Python:既に起動しているメモ帳に文字を記入する
from pywinauto import Desktop, Application

app = Desktop(backend='win32')
win = app.window(class_name='Notepad', top_level_only=True) #メモ帳アプリのウィンドウを取得
ed_elem = win.child_window(class_name='Edit') #メモ帳内のエディット領域を取得
ed_elem.set_edit_text(u'OK!') #OK!を書き込む
```
`app = Desktop(backend='win32')`の`backend='win32'`の部分が、**①**の方法で取得しますよ、という意味です。
`app = Desktop(backend='uia')`と記載すれば、**②**の方法で取得する事になります。
前述の通り、どちらで取得してもその後のコードは似たようになるので、どちらを選んでも良い様に思えますが、②の方法でしか取得できないコントロールがあるので、注意してください。
この辺は、[Spy++](https://learn.microsoft.com/ja-jp/visualstudio/debugger/introducing-spy-increment?view=vs-2022) や、[inspect](https://learn.microsoft.com/ja-jp/windows/win32/winauto/inspect-objects) を使って確認する事になります。
(inspect で確認できるのに、UIAutomation で取得できないモノも、ちらほら・・・)

余談ですが、
```Python:re で正規表現マッチ
win = app.window(title_re='B.*', class_name_re='N.*', top_level_only=True)
```
`title_re`や`class_name_re`を使う事で、。正規表現によるマッチが出来ます。
### とあるコントロールの次コントロールが取得したい
ComboBox などは、キャプションが無く、class_name でしか取得できない事が多いですが、ComboBox が複数ある場合、「このコントロールの次の ComboBox が取りたい！」という事も往々にしてあると思います。
```Python:当該コントロールの下に有るコントロールをループで回す
from pywinauto import Desktop, Application

app = Desktop(backend='win32')
win = app.window(title_re='BT.*', class_name='#32770', top_level_only=True) #ウィンドウを取得
flg_combo = False
for obj_ctrl in win.descendants():
    if obj_ctrl.element_info.class_name == 'Static' and obj_ctrl.element_info.name == 'フォーマット(&F)':
        flg_combo = True
    elif flg_combo and obj_ctrl.element_info.class_name == 'ComboBox':
        obj_ctrl.select('JPEG')
        break
```
当該コントロールの子コントロールは、`[当該コントロール].descendants()`で取得できます。
それを for ループで回せばOK。
今回躓いたのは、クラス名やキャプション名を取得する手法。
上記を見てもらえばわかると思いますが、
+ `[当該オブジェクト].element_info.name`でキャプション名
+ `[当該オブジェクト].element_info.class_name`でクラス名

が取得できます。
### 調べるのが面倒なので、覚書
+ `[当該オブジェクト].print_control_identifiers()`で当該オブジェクトとその子オブジェクトの情報を取得
+ `[当該オブジェクト].TypeKeys('{ENTER}')`で当該オブジェクトにキー操作(この例ではENTERキー押下)を行う
+ 普通にテキストボックス等に文字を入力する場合は`[当該オブジェクト].set_edit_text(u'OK!')`で良い
(断面二次モーメント大小比較)「一級建築士【構造力学】断面二次モーメント・断面係数」様を参考に、sympyでやってみたい。

・途中です。
**パイソニスタの方へ**
・私は、tupleの掛け算がわかっていません。アドバイスをいただけると幸いです。
・以下は、sympyの**second_moment_of_area(point=None)** です。

# オリジナル 
Youtube でめまる構造 様 　
フル　一級建築士【構造力学】断面二次モーメント・断面係数(0:00〜15:05)
https://youtu.be/47HHxwGCi_A?t=322

# sympyのweb上での実行方法
SymPy Live Shellで。
~~FreeCADのマクロは、以下で実行できません。本ページで使っていません。~~
https://qiita.com/mrrclb48z/items/00dd08b0317069be9342#web%E4%B8%8A%E3%81%AE%E5%AE%9F%E8%A1%8C%E6%96%B9%E6%B3%95sympy-live-shell%E3%81%A7

# sympyで(オリジナル 様の方法を参考に)
勉強中
・未 ver 0.1 細かく分割。???素因数分解
・未 ver 0.2 細かく分割。

# sympyで(いつもの方法で)
・ver 0.3 sympyの一筆書き ??? 私は、tupleの掛け算がわかっていません。
・second_moment_of_area(point=None)
https://docs.sympy.org/latest/modules/geometry/polygons.html#sympy.geometry.polygon.Polygon.second_moment_of_area
・変数aを使っていません。
```python
# ver 0.3 sympyの一筆書き ??? 私は、tupleの掛け算がわかっていません。
from sympy import *
var('a',nonnegative=True)
def compare_variables(**kwargs):
    # 変数名と値をペアにしてリスト化
    variables = list(kwargs.items())

    # 値を基準に降順でソート (同じ値でも順番を保つ)
    sorted_vars = sorted(variables, key=lambda x: x[1], reverse=True)

    # 結果を組み立て (等しい値は "=" で表現)
    result = []
    values = []
    for i in range(len(sorted_vars)):
        if i > 0 and sorted_vars[i][1] == sorted_vars[i-1][1]:
            result[-1] += f" = {sorted_vars[i][0]}"
            values[-1] += f" = {sorted_vars[i][1]}"
        else:
            result.append(sorted_vars[i][0])
            values.append(f"{sorted_vars[i][1]}")
    return " > ".join(result)," > ".join(values)
A_a=Polygon(( 0,-4),                                           # 1+(4+1)+1+(4+1)=12点
            ( 3,-4),( 3, 4),(-3, 4),(-3,-4),(0,-4), 
            ( 0,-2),
            (-2,-2),(-2, 2),( 2, 2),( 2,-2),(0,-2))
B_a=Polygon(( 0,-4),
            ( 3,-4),( 3,-2),( 1,-2),( 1, 2),( 3, 2),( 3, 4),   # 1+6+6*13点
            (-3, 4),(-3, 2),(-1, 2),(-1,-2),(-3,-2),(-3,-4))
C_a=Polygon(( 0,-4),                                           # 1+4=5点
            ( 2,-4),( 2, 4),(-2, 4),(-2,-4))             
print("#",A_a.area,B_a.area,C_a.area)
ansStr,ansValue=compare_variables(A=A_a.second_moment_of_area()[0],
                                  B=B_a.second_moment_of_area()[0], 
                                  C=C_a.second_moment_of_area()[0])
print("#",ansStr)                                  
print("#",ansValue)                                  
print()
ansStr,ansValue=compare_variables(A=A_a.second_moment_of_area()[1],
                                  B=B_a.second_moment_of_area()[1], 
                                  C=C_a.second_moment_of_area()[1])
print("#",ansStr)                                  
print("#",ansValue)                                  
# 32 32 32
# A = B > C
# 704/3 = 704/3 > 512/3

# A > B > C
# 368/3 > 224/3 > 128/3
```
・ver 0.4 sympyの**第Ⅳ象限だけ** の一筆書きで十分のような気がしました。 
勉強中

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342) 　開発環境


# いつもと違うおすすめです。

#### Qiita内で

https://qiita.com/mrrclb48z/items/66cbc2ec2e5c1174c7d9

・以下、AI先生に教えてもらいました。

https://qiita.com/mrrclb48z/items/d96b4e24b25dcb0fc700
【React】material-tailwindのTabのアニメーションを無効にする

## 概要
material-tailwindには[Tailwind CSS Tabs - React](https://www.material-tailwind.com/docs/react/tabs)のドキュメントで紹介されている通り、Tab実装のためのコンポーネントが用意されています。ドキュメント中のコンポーネントのサンプルをご覧いただければわかる通り、アニメーションが実装されています。
一つ目はタブ選択時のタブ移動のアニメーションで、二つ目はタブ選択時のbody要素の表示アニメーションです。デフォルトのままでも問題ないとは思いますが、個人的には少しもっさりしてるのが気になりました。というわけで、アニメーションを無効にしたい場合どうするかというのを今回メモ書きします。

## 前提
* 使用した`material-tailwind/react`のバージョンは`2.1.10`です。

## 対応方針
* タブ移動のアニメーションの無効ですが、[How to disable tab animations in @material-tailwind/react](https://stackoverflow.com/questions/76914537/how-to-disable-tab-animations-in-material-tailwind-react)の記事が参考になります。タブの要素に対して`!translate-x-0`のスタイルを設定することで移動のアニメーションを無効にできます。
* body要素の表示アニメーションについては、TabsBodyの[Custom Tabs Animation](https://www.material-tailwind.com/docs/react/tabs#tabs-custom-animation)で無効化します。処理としてはopacityでbodyの表示切り替えをしているようでしたので、opacityを1固定にして表示の切り替えは自前で実装します。

## 実装サンプル

```react
export const TabSampleComponent: FC = () => {
  const [activeTab, setActiveTab] = useState("category");

  return (
    <Tabs value={activeTab} className="max-w-[99%]">
      <TabsHeader
        className="rounded-none border-b border-blue-gray-50 bg-transparent p-0"
        indicatorProps={{
          id: "tabs-header-indicator",
          className:
            "bg-transparent border-b-2 border-gray-900 shadow-none rounded-none",
        }}
      >
        <Tab
          value={"place"}
          onClick={() => setActiveTab("place")}
          className={
            // translate-x-0でタブの移動アニメーションを無効
            "[&_#tabs-header-indicator]:!translate-x-0 " +
            (activeTab === "place" ? "text-gray-900" : "")
          }
        >
          場所を選択
        </Tab>
        <Tab
          value={"category"}
          onClick={() => setActiveTab("category")}
          className={
            // translate-x-0でタブの移動アニメーションを無効
            "[&_#tabs-header-indicator]:!translate-x-0 " +
            (activeTab === "category" ? "text-gray-900" : "")
          }
        >
          カテゴリーを選択
        </Tab>
      </TabsHeader>
      <TabsBody
        animate={
          // bodyの切り替え時のアニメーションを無効
          {
            initial: { opacity: 1 },
            mount: { opacity: 1 },
            unmount: { opacity: 1 },
          }
        }
      >
        {activeTab === "place" ? (
          <TabPanel value={"place"}>場所</TabPanel>
        ) : (
          <TabPanel value={"category"}>カテゴリー</TabPanel>
        )}
      </TabsBody>
    </Tabs>
  );
};
```
【図で覚える】LinuC試験対策_vi操作

## これは何の記事？
LinuC試験対策用に vi の操作キーをまとめた記事です
量が多いですからね，視覚的に覚えようという狙いです

## コピー
![yw_yy_Y.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/97bb991f-6b3b-74df-3891-398c910f8dd3.png)

## 切り取り
![dw_dd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/bfcf0061-d3fc-a24c-ab0e-4d168baba944.png)

![x_X.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/6b22e1c2-f53b-df42-3f80-eb2d85873e8e.png)


## ペースト
![p_P.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/0c2ae52b-2596-a272-8d85-00c00bf19cc5.png)

## 移動
![hjkl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/fe231596-3be0-aa34-31a6-04a4975870a5.png)

![移動2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/e2fd41ca-5ebf-ad18-72f5-e211407c9f06.png)

![gg_G.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/15afe058-3a97-6619-3128-24f8d3c45aff.png)

![nG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/9ccaf46f-d4b6-22cc-efa2-7422ab19c35c.png)

![bf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/0b614971-1e14-8c1c-e9cc-f1b4e995386d.png)

## 編集モードから入力モードに移行
![iIaAoO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/b911426a-7716-6488-32b8-f81012a68fc4.png)
【Kotlin Coroutines Flow】take や first は CancellationException が発生している

# はじめに

`take()` や `first()` は、条件に達したとき、`CancellationException` を継承した  `AbortFlowException` が投げられていますので、キャンセル完了をハンドリングしている場合、想定外の補足してしまう場合があります。

# 環境

- kotlin 2.0.21
- org.jetbrains.kotlinx:kotlinx-coroutines-core 1.8.1

# 注意

`take()` や `first()` よりも後の flow に対しては `CancellationException` は伝播してこないので、通常の使用で問題になることは少ないと思います。

# CancellationException を捕捉してしまう例

``` kotlin
val cancellationHandlingFlow: Flow<Unit> = flowOf(Unit)
    .onCompletion { throwable ->
        // 結果別の表示
        when (throwable) {
            null -> println("完了しました。")
            is CancellationException -> println("キャンセルされました。 $throwable")
            else -> println("エラーです。 $throwable")
        }
    }
```

上記のように、キャンセル完了もハンドリングしようとすると、`catch()`では `CancellationException` を捕捉できないので、`onCompletion()` で処理することになると思います。

このような Flow に対して、`first()` で結果を１つ得るようにします。

``` kotlin
fun main() = runBlocking {
    cancellationHandlingFlow.first()
}
```

すると、結果は、

```
キャンセルされました。 kotlinx.coroutines.flow.internal.AbortFlowException: Flow was aborted, no more elements needed
```

`cancellationHandlingFlow` の `onCompletion()` では、通常の完了ではなく、キャンセルとして flow を終了したことが伝えられました。
Flow が１つの値の放出で終了するものであっても、先に `first()` の条件を満たしてキャンセルで終了したことになります。

また、`first()` ではなく `take(1)` でも同様に `AbortFlowException` となります。

``` kotlin
fun main() {
    runBlocking {
        launch {
            cancellationHandlingFlow
                .take(1)
                .collect {}
        }
    }
}
```

```
キャンセルされました。 kotlinx.coroutines.flow.internal.AbortFlowException: Flow was aborted, no more elements needed
```

# 回避策

キャンセルハンドリングの `onCompletion()` を `collect()` や `launchIn()` の直前に呼び出すように Flow を拡張するとよさそうです。

``` kotlin
// collect() 直前で onCompletion() を呼ぶ拡張
suspend fun <T> Flow<T>.collectHandling(
    collector: FlowCollector<T>
) = this
    .onCompletion { throwable ->
        // 結果別の表示
        when (throwable) {
            null -> println("完了しました。")
            is CancellationException -> println("キャンセルされました。 $throwable")
            else -> println("エラーです。 $throwable")
        }
    }
    .collect(collector)

// launchIn() 直前で onCompletion() を呼ぶ拡張
fun <T> Flow<T>.launchInHandling(
    scope: CoroutineScope
) = this
    .onCompletion { throwable ->
        // 結果別の表示
        when (throwable) {
            null -> println("完了しました。")
            is CancellationException -> println("キャンセルされました。 $throwable")
            else -> println("エラーです。 $throwable")
        }
    }
    .launchIn(scope)
```

``` kotlin
fun main() {
    runBlocking {
        launch {
            flowOf(Unit)
                .take(1)
                .collectHandling {}
        }
    }
}
```

``` kotlin
fun main() = runBlocking {
    flowOf(Unit)
        .map { flowOf(Unit).first() }
        .launchInHandling(this)
        .join()
}
```

```
完了しました。
```
Dictionaryを二度検索しないようにする

## 参考
この記事は、以下の動画を参考にしています。
詳しくは、動画をご覧ください。

<iframe width="560" height="315" src="https://www.youtube.com/embed/8dI_nsmcW-4?si=k1fw7d-8If4srSnl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## 状況
```csharp
public static TValue GetOrAdd<TKey, TValue>(
    this Dictionary<TKey, TValue> dict, TKey key, TValue value)
    where TKey : notnull
{
    if (dict.TryGetValue(key, out var result)) // 辞書内を検索
        return result;

    dict[key] = value; // ここでも辞書内を検索
    return value;
}
```
1. 辞書に、指定したキーに対応するエントリーあれば、その値を戻す
1. キーに対応するエントリーがなければ、指定した値でキーに対応するエントリーを作り、その値を戻す

というメソッド。

このとき、1. と 2. の２回、辞書内の検索が実行されてしまう。

これを、１回の検索で済むようにできないものか。

## 解決法
```csharp
public static TValue GetOrAdd<TKey, TValue>(
    this Dictionary<TKey, TValue> dict, TKey key, TValue value)
    where TKey : notnull
{
    ref var val = ref CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out var exists);
    if (exists)
    {
        return val;
    }

    val = value; // 単なる代入
    return value;
}
```
`System.Runtime.InteropServices.CollectionsMarshal`クラスの`GetValueRefOrAddDefault`メソッドを使う。（.NET 9から）

`CollectionsMarshal.GetValueRefOrAddDefault`メソッドが、

1. 辞書に、指定したキーに対応するエントリーあれば、その参照を戻す
1. キーに対応するエントリーがなければ、エントリーを作り、その参照を戻す

まで行ってくれる。

これで、辞書を二度検索する必要がなくなる。

https://learn.microsoft.com/ja-jp/dotnet/api/system.runtime.interopservices.collectionsmarshal.getvaluereforadddefault?view=net-9.0

## 他にも
`CollectionsMarshal.GetValueRefOrNullRef`メソッドでは、キーに対応するエントリーがなかった場合、`null`参照を戻す。

https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.collectionsmarshal.getvaluerefornullref?view=net-9.0
初学者向け：PythonとLINE Notifyで環境構築からトークン取得まで、簡単にLINE通知機能を実装してみた

## はじめに
Pythonを使ってLINE Notifyを活用すると、LINEに簡単に通知を送る仕組みを実装することができます。

:::note
**このスクリプトは、Python初心者やLINE Notifyを初めて利用する方にもわかりやすい内容になっています。**
:::

***今回の記事では、必要な環境準備から実際に通知を送信するまでの手順を丁寧に解説します。***

## 書こうと思ったきっかけ
この仕組みは、前回のハッカソンでバックエンドを担当した際に実装した機能の一部です。

***実際に使用したコードはこちらに公開しています。***

https://github.com/RareTECH-Iteam/Iteam_0819/blob/main/ChatApp/notification.py

ハッカソンでは、47都道府県のユーザーをマッチングさせる機能を追加実装しました。

:::note warn
***その際、「マッチングが成立したらLINE通知を行いたい」という要件がありました。***
:::

この要件を実現する過程でLINE Notifyの存在を知り、Pythonを使えば簡単に連携できることに気づきました。**実際に試したところ、通知を送る仕組みを短時間で構築することができました。**

そのため、今回その手順をまとめて共有することで、他の方の参考になればと思っています。

## 必要な環境準備

### Python インストール

Python 3.x をインストールしてください（公式サイトからダウンロード可能）。

https://www.python.org/

### 必要なライブラリのインストール
LINE Notifyを使用するには、`requests` ライブラリが必要です。以下のコマンドをターミナルで実行してインストールしてください。

```bash
pip install requests
```

### LINE Notify トークンの取得

LINE Notify にログインし、トークンを発行して、以下コードの `lineNotifyToken` にコピー＆ペーストしてください。

https://notify-bot.line.me/en/

### コードの準備
以下のコードをローカル環境のファイル（例: `line_notify.py`）に保存します。

```line_notify.py
import requests

def sendLineNotify():
    # LINE Notifyのトークンをここに設定してください
    lineNotifyToken = "あなたのLINE Notifyトークンをここに入力"
    lineNotifyApi = "https://notify-api.line.me/api/notify"
    headers = {"Authorization": f"Bearer {lineNotifyToken}"}
    data = {"message": "Pythonから通知検証が成功！"}

    response = requests.post(lineNotifyApi, headers=headers, data=data)
    if response.status_code == 200:
        print("LINEに通知が送信されました")
    else:
        print(f"通知の送信に失敗しました: {response.status_code} - {response.text}")

# 関数を呼び出して実行
if __name__ == "__main__":
    sendLineNotify()
```

## スクリプトを実行してみた
ターミナルで保存したスクリプトを以下のコマンドで実行します。

```bash
python line_notify.py
```

### 実際の実行結果

**成功時：**

```bash
➜  Desktop git:(main) ✗ python line_notify.py
/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
LINEに通知が送信されました
```

**失敗時：**

```bash
➜  Desktop git:(main) ✗ python line_notify.py
/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
通知の送信に失敗しました: 400 - {"status":400,"message":"LINE Notify account doesn't join group which you want to send."}
```

失敗の原因として、以下のようなことが考えられます：

- **LINE Notify トークンが無効になっている**
- **トークンが「送信先のグループまたはアカウント」に紐付いていない**


:::note alert
**※私の環境では、トークンが古く無効だったため、このエラーが発生しました。**
:::

## LINE通知の結果
今回のコードを実行した結果、以下のような通知がLINEに届きました。

![Screenshot 2025-01-25 at 14.29.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/3f659251-e0ba-095b-5d82-06426c10bc2d.png)

通知メッセージの内容は「`Pythonから通知検証が成功！`」で、スクリプトを実行するたびに通知が正常に届くことを確認しました。

## まとめ
初めてLINE Notifyを使ったときは、公式サイトでのトークン発行やPythonコードの実装手順が少し不安でしたが、シンプルなAPI設計のおかげでスムーズに動作させることができました。

:::note info
***通知がLINEに届くことで、実際に動いている感覚を得られたのがとても良かったです。***
:::

特に、身近なLINEアプリを活用することで、エラーや処理完了の通知をリアルタイムで確認できるのは便利だと感じました。
JavaScript イベントの実行順序を早める方法

**キャプチャリングフェーズを使うべし**

## キャプチャリングフェーズとは何か
キャプチャリングフェーズを理解する前に、まずはバブリングフェーズを理解する必要があります。

```html:test.html
<form onclick="alert('form')">
  <div onclick="alert('div')">
    <p onclick="alert('p')"></p>
  </div>
</form>
```
バブリングフェーズとは、例えば、上記のようにform > div > p
の順番で要素が入れ子になっていた場合、p要素を押下すると、アラートは
1. p
1. div
1. form

の順番で実行されます。
泡のようにイベントが内部の要素から親に向かって実行されていくので、バブリングフェーズと呼ばれています。
何もしないとイベントは基本的にバブリングフェーズに登録されます。

キャプチャリングフェーズはその逆で、**親要素から内部に向かって実行されるフェーズのことを言います。**


- バブリングフェーズに登録されたイベントより、キャプチャリングフェーズに登録されたイベントの方が早く実行される

上記の特性を利用して、イベントを早めることが出来ます。
キャプチャリングフェーズを使用するには、addEventListenerの第二引数にtrueを渡すだけです。
#### addEventListener(event, true)


## キャプチャリングフェーズを使ってみよう
まずは、キャプチャリングフェーズを使っていない場合
```html:test.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>
<body>
    <p style="height:300px; width:300px; background:red;" id="P"></p>
</body>
</html>
<script>
document.getElementById('P').addEventListener('click',function() {
  	alert("1個目のP")
})
document.getElementById('P').addEventListener('click',function() {
  	alert("2個目のP")
})
</script>
```
上記をそのまま実行すると、「1個目のP」が先に実行されて、その後に「2個目のP」が実行されています。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3864216/93127944-e3f9-7f23-f9c4-f56ae0600527.png)
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3864216/6d13ac5e-4ccf-7f69-8de5-3433a02e3f87.png)

では、キャプチャリングフェーズを使用した場合はどうなるのか
「2個目のP」のイベントをキャプチャリングフェーズに登録します。
```html:test.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>
<body>
    <p style="height:300px; width:300px; background:red;" id="P"></p>
</body>
</html>
<script>
document.getElementById('P').addEventListener('click',function() {
  	alert("1個目のP")
})
document.getElementById('P').addEventListener('click',function() {
  	alert("2個目のP")
}, true)
</script>
```
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3864216/d6b9649c-484d-c252-3b40-ab64a304fc55.png)
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3864216/687c119b-8e4f-9ee9-f704-d2db5bffc892.png)

今度は、キャプチャリングフェーズに登録された「2個目のP」のイベントの方が先に実行されています。

上記のことから、**バブリングフェーズよりキャプチャリングフェーズを利用したほうが、イベントが早く実行**されることが分かりました。


## 参考
https://ja.javascript.info/bubbling-and-capturing
Python初心者向け：初めてのLinear Issue CSV解析 - Issue数を数えてみよう


Linearユーザーの皆さん、LinearはCSV形式で設定メニューからIssueをエクスポートできます。この記事では、プログラミング初心者の方向けに、Pythonを使って手元の環境でLinearからエクスポートしたCSVファイルのIssue数を簡単に数える方法を解説します。

　実際には、一覧に表示されるので、数える必要は実際にはありませんが、今後CSVを解析する第一歩としてやってみましょう。
 
## 処理の概要
 このスクリプトでは、引数から渡されたCSVファイルが存在するかを確認し、存在しなければ終了します。
 そしてテキストとしてCSVファイルを読み込み各行を辞書形式に変換します。
 最後にArchived(削除)されたものと、そうでないもの(Active)なIssue数を数えます。

## Python Code
```python
"""
License MIT
https://github.com/akjava/
"""

import os

import argparse
import csv


def parse_arguments():
    """引数を解析します。

    Returns:
    """
    parser = argparse.ArgumentParser(description="create rotated data")
    parser.add_argument("--input", "-i", default="example.csv", help="Input Linear CSV")
    return parser.parse_args()


def read_csv_with_newlines(filepath):
    """
    改行を含むCSVファイルを読み込む関数

    Parameters:
        filepath (str): CSVファイルのパス

    Returns:
        list: 読み込んだCSVデータをリストのリストで返す
    """
    data = []
    with open(filepath, "r", encoding="utf-8") as file:
        reader = csv.reader(file)
        for row in reader:
            data.append(row)
    return data


def issue_text_to_dict(head, csv_lines):
    """
    issue-csv-textを辞書に変換

    Parameters:
        head (str):header 通常csvの最初の行
        csv_lines:csvテキストのリスト

    Returns:
        list: 読み込んだissue-CSVデータを辞書のリストで返す
    """
    result = []
    for line in csv_lines:
        dict = {}
        for i, key in enumerate(head):
            if i < len(line):
                dict[key] = line[i]
        result.append(dict)
    return result


if __name__ == "__main__":
    args = parse_arguments()
    csv_path = args.input
    if not os.path.exists(csv_path):
        print(f"csv not exist {csv_path}")
        exit(0)

    csv_issue_texts = read_csv_with_newlines(csv_path)
    dicts = issue_text_to_dict(csv_issue_texts[0], csv_issue_texts[1:])
    archived = 0
    for dic in dicts:
        if dic["Archived"]:
            archived += 1
    print(f"total {len(dicts)} archived {archived} active {len(dicts)-archived}")

```
このPythonコードでは、csvモジュールを使ってCSVファイルを読み込んでいます。CSVの1行目は、"ID","Team","Title","Description","Status"...といったヘッダーになっており、それをキーとして各行を辞書形式に変換します。
念のため、データの長さをチェックしています。
Archivedとは、LinearでIssueが削除された時に一時的に設定される状態を表し、残りがActive Issueです。

## 実行結果
このコードは、コマンドプロンプトで実行できます。実行すると、以下のように、アーカイブされたIssueとアクティブなIssueの数が表示されます。

```
PS C:\pythons\test> python .\count_issue.py -i "Export Wed Jan 22 2025.csv"
total 104 archived 90 active 14
```

この結果から、現在のプロジェクトにおけるIssueの数を把握できます。

### まとめ
LinearのCSVに含まれる項目は以下の通り豊富で。issueごとに、かかった作業時間をガントチャートにしたり、次のCycleの予定を予測したりもできそうだ。
```
"ID","Team","Title","Description","Status","Estimate","Priority","Project ID","Project","Creator","Assignee","Labels","Cycle Number","Cycle Name","Cycle Start","Cycle End","Created","Updated","Started","Triaged","Completed","Canceled","Archived","Due Date","Parent issue","Initiatives","Project Milestone ID","Project Milestone","SLA Status","Roadmaps"
```
　ぜひ皆さんも、いろいろ試してみてください。
 私も以下レポジトリーで時間があれば、更新したいと思います。

 https://github.com/akjava/python-linear-api-examples
VS Code 拡張機能 Material Icon Theme が突然動かなくなった話

# 概要
上の通りです。

環境はWindows 11です。

# どういうこと？

画像をご覧ください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/ce8ba2ac-dc1f-8b78-b9e7-1d27a2aff8b9.png)

なんということでしょう、画面向かって左のエクスプローラーからアイコンが消えているではありませんか！

VS Codeデフォのiconでも事足りるんですが、あまり美しくないです。これはどないかせねば…

# 試行錯誤

拡張機能自体をインストールし直してみたり、vscodeやPCを再起動してみましたが駄目…

糸口は設定にありました。

問題は以下の部分。

```json
"material-icon-theme.activeIconPack": "none"
```

この項目を次のように変更してみます。

```json
"material-icon-theme.activeIconPack": "angular"
```

すると…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/76df9553-23d0-b4cd-467d-db5ea8cfa407.png)

直りました。

というか、この項目defaultの設定がangularになってるので、消しても構いません。

# 終わりに

なんで突然この項目がnoneになったのかが判然としないのが一番怖い。

あと、これ[Material Icon Themeのdocs](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme)見ても"activeIconPack"っていう設定項目の説明が載ってないんですけど…

ななめ読みなんで読み落としてるかもしれないんですが。
Excelで複数テーブルをPandasっぽく集計できるようにする

# 概要
レポートに測定結果やシミュレーション結果の数値集計をExcelファイルにまとめて提出する人は多いと思います。
Excel2021以降の機能の構造化参照は、データの集計に便利ですが、デフォルトの機能だけだと
数式の記述が冗長になって見通しが悪いし、
使い勝手も悪いのでPythonのPandasっぽく便利に使うためのTips

# 本記事の想定対象読者
1. 定型フォーマットのCSV, TSVファイルを多数集計してレポート書く必要がある人
1. レポートにJupyterNotebookを添付して提出すると嫌な顔される仕事場の人
1. Excelのマクロが職場セキュリティ的に禁止されている人
1. Python in Excelが使えない職場の人


# やりたいこと

こういう定型書式CSVファイルを多数読み込んで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/bd5e8ab5-5a52-f48d-9f76-ad0fe9bc631b.png)

こういう集計を楽に作成したい。できれば集計ファイルが増えても
集計部分は極力「範囲選択ー＞Ctrl+d」でどうにかしたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/8d8d0d71-9ba8-2aae-e0ea-04100f0cab25.png)

# Excel標準機能の問題
例として、Excel標準機能でTEST1という名前のテーブルを読み込んで集計するときテーブル名と列名を指定して集計関数で集計します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/e4787b45-5fbc-7e6e-a13a-0deb3093f503.png)

これの問題が何かといえば、
__テーブル名と列名を数式ベタ打ちする必要がある__　ことです。
見本のダミーデータはタイムスタンプ、温度とセンサ３つのデータを、４温度（４テーブル）分を集計している想定です。

しかし、実務でセンサが10個に増えて、集計対象のテーブル数１０を超えたとき、
(1+10)*10=110回以上数式を入力する必要があります。
 __「集計数式全部をベタ打ちする気力ありますか？」__
PandasでDataFrameの集計を触ったことがある人間は発狂すると思います。ソースは私。

 # これを名前で登録すれば便利と思うもの

Excel2021以降だと、リボンUIの数式タブのところに「名前の定義」というのがでているので、
名前の定義とLAMBDA式を組み合わせると、実質的にマクロ無しでExcel上で使えるユーザー定義関数を作れます。

下記表の名前とLAMBDA式を登録すると幸せになれると思います。
なお、文字列を含むテーブル全体への演算は式が冗長になるので今回は省略

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/1ff9fce5-ab80-288b-3d82-4311d4362c95.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/c7c0d84f-45dc-3b2e-ea38-625b8a5e4d98.png)

| 名前例 |Pandasでの操作| 式 |
| ---- | --- | --- |
| TAB | df | =LAMBDA(TAB,INDIRECT(TAB)) |
| TCOL | df['列名']　| =LAMBDA(TAB,COL,INDIRECT(CONCAT(TAB,"[",COL,"]"))) |
| DIFF | df.diff() | =LAMBDA(TAB,TAB-OFFSET(TAB,-1,0)) |

 # 使用例
 上述の定義した関数でテーブル名と列名指定をセル参照できるようにした例がこちら

 ### 使用例1：セル指定でテーブル列のMIN()関数適用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/d5917e75-d43e-ce25-a520-3ca8775e5b42.png)

例示したC4セルで意図した操作はpandasで書くと次のイメージです。

```python:example_df_min.py
import pandas as pd

# この行は事前のテーブルの読み込み
df_TEST1=pd.read_csv('TEST1.csv")

# C4セルで行っている操作
B3=df_TEST1
df=B3
C3='TEMP'
df[C3].min()
```

 ### 使用例2：セル指定でテーブル列のdiff()関数適用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/0dd9679f-a1d2-1be2-5aed-5055aa875b8f.png)

例示したD3セルで意図した操作はpandasで書くと次のイメージです。
```python:example_df_diff.py
import pandas as pd

# この行は事前のテーブルの読み込み
df_TEST1=pd.read_csv('TEST1.csv")

# D3セルで行っている操作
B3=df_TEST1
df=B3
D2='TEMP'
df[D2].diff()
```

# まとめ
Excelで手軽にpandasっぽい操作をしたくて３種類ほど、マクロ無で使えるユーザー関数を定義してみました。
DIFFを定義したのはスピルで使える数値列の微分向け関数がなかったからです。
JavaSE17(Silver) Recordクラスのまとめ

自分用

## Recordクラス
<details><summary>[ xxx ]なフィールドを作成</summary>

変更不可

</details>
<details><summary>[ xxx ]なクラス</summary>

final

</details>
<details><summary>[ xxx ]なクラスとしてコンパイルされる</summary>

Recordクラスを継承した

</details>
<details><summary>getterメソッド以外の3つのメソッドを自動的に宣言する</summary>

- toString()
- equals()
- hashCode()

</details>

<details><summary>getterメソッド以外の3つのメソッドを自動的に宣言する</summary>

- toString()
- equals()
- hashCode()

</details>
<details><summary>Recordには[xxx]は存在しない</summary>

デフォルトコンストラクタ
publicな引数を受け取るコンストラクタが暗黙的に宣言されるから

</details>
<details><summary>Recordを宣言できる場所はクラスと同じ。(3箇所)</summary>

1. クラスが独立したトップレベルクラス
    a. アクセス修飾子はpublic、デフォルト
2. クラス内のメンバとして宣言するインナークラス
    b. アクセス修飾子はprotected、private
3. メソッド内で宣言するローカルクラス
    c. アクセス修飾子は無し

</details>
<details><summary>Recordで宣言できないものは？</summary>

staticではない

</details>
<details><summary>Recordのgetterメソッドは[ xxxx ]名で自動的に作成される</summary>

フィールド名

</details>
<details><summary>Recordは[ xxx ]メソッドは生成されない</summary>

setter

</details>

Recordのgetterメソッドの特徴は4つある。
<details><summary>[ xxx ]はレコードの構成要素と同じ</summary>

戻り値型

</details>
<details><summary>[ xxx ]ではない</summary>

ジェネリック

</details>
<details><summary>[ xxx ]なメソッド</summary>

public

</details>
<details><summary>[ xxx ]は持たない</summary>

throws句

</details>
Recordには標準コンストラクタ、代替コンストラクタ、コンパクトコンストラクタ3種類のコンストラクタがある
<details><summary>標準コンストラクタについて説明しなさい。</summary>

自動的に生成され、フィールドを初期化するコンストラクタ

</details>
<details><summary>代替コンストラクタについて説明しなさい。</summary>

引数は、標準コンストラクタと同じ。プログラマが何らかの処理を追加するために宣言する。代替コンストラクタはレコードそのものより厳しいアクセス修飾子をつけることはできない。コンストラクタの中で、フィールドを初期化する必要がある。

</details>
<details><summary>コンパクトコンストラクタについて説明しなさい。</summary>

標準コンストラクタに渡されてきた引数の妥当性を検証するために使う。
例えば、「nullでないか」とか「空文字でないか」とか「不正な値でないか」とか。
標準コンストラクタとセットになって標準コンストラクタでフィールドが初期化される前に実行される。

</details>
コンパクトコンストラクタのルールについて4つ
<details><summary>コンパクトコンストラクタ内で[ xxx ]を記述してはいけない</summary>

return文

</details>
<details><summary>明示的に[ xxx ]を呼び出してはいけない</summary>

別のコンストラクタ

</details>
<details><summary>[ xxx ]にアクセスしてはいけない</summary>

フィールド

</details>
<details><summary>コンパクトコンストラクタは[ xxx ]しか宣言できない</summary>

1つ

</details>

### 標準コンストラクタと代替コンストラクタ以外のコンストラクタ
標準コンストラクタと代替コンストラクタ以外のコンストラクタをオーバーロードできる。
ただし、明示的に標準コンストラクタと代替コンストラクタを呼び出す必要がある。

### interfaceを実現できる
デフォルトメソッドを自動追加されるgetterメソッドでオーバーライドできる。
オーバーライドなのでシグニチャが同じで戻り値が違うとレコードのコンパイル時にエラーが起きる
picoCTF 2019 writeup logon

## logon (Web Exploitation)

The factory is hiding things from all of its users. Can you login as Joe and find what they've been looking at? https://jupiter.challenges.picoctf.org/problem/13594/ ([link](https://jupiter.challenges.picoctf.org/problem/13594/)) or http://jupiter.challenges.picoctf.org:13594

とりあえず、記載のリンクを開いてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638553/1562d067-dbcc-3087-e29e-11c7e7ce3ac2.png)
何も入力せずに`Sign In`ボタンを押すと、ログイン自体には成功するが以下のページが表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638553/d3e44faf-4615-509e-d7a5-97e3d68d2cab.png)
DevToolsでソースコードを確認すると、特に問題のありそうな所はなかった。
Networkタブでloginファイルを確認すると、ボディに`user=&password=`と書かれていたので、`Joe`を追加して再送信する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638553/1e30d3ba-b614-d261-0e5e-6634ebcb6074.png)
problemとなり、フラグが表示されなかった。
ログイン情報をCookieで管理されていそうなので、Storageタブで確認すると、Cookieが以下のようになっていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638553/a5fbdc63-6cb0-dbfe-6769-311674822035.png)
`Admin=True`, `password=Joe`, `username=Joe`に書き換えて、リロードする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638553/dceeb356-3285-b37d-c878-48009e021eb3.png)

フラグが得られた。

`picoCTF{th3_c0nsp1r4cy_l1v3s_d1c24fef}`
Windows11にインストールしたOracle Database 21c XE をアンインストールしたい

Windows11にインストールしたOracle Database 21c XE をアンインストールしたい場合、以下の公式ドキュメントを参考に作業を進めます。

https://docs.oracle.com/cd/F39414_01/xeinw/deinstalling-oracle-database-xe.html#GUID-B3AC267F-46A5-4D27-9374-B1BAC70E2953

① 設定 > アプリ > インストールされているアプリ　から Oracle Database 21c Express Editionを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/3696c25a-df31-fbb2-ed02-9d4a0bc76379.png)

② アンインストール を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/ccfe84c3-5e9f-8d07-baba-2b0f68363599.png)

③ プロンプトにしたがって、アンインストールを進める。

**環境情報**

- Oracle Database 21c Express Edition
- Microsoft Windows 11 [Version 10.0.22631.4602]
ホストオンリーアダプターが接続失敗する

## はじめに
普段は仕事でUbuntuしか使っていないので、勉強のためAlmalinuxを使ってみたいと思い、Windows環境にVirtualBoxをインストールしてゲストOSとして使うことにしました。
ホストOSとゲストOS間の接続に使用されるホストオンリーアダプタでの接続がなかなか苦労したので、その備忘録を残しておきます。
VirtualBoxにゲストOSとしてAlmalinuxをインストール手順については、他のWebサイトにたくさん記載があるので、ここでは割愛。

## 環境
ホストOS：Windows 11 Home Edition 
ゲストOS：Almalinux 9.5

## 発生した問題
![virtualbox_almalinux.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750854/a611bc2e-f9aa-d0f1-1f4f-a9b1a9f0a3c7.png)


ゲストOSの[アダプター2]のネットワーク設定でホストオンリーアダプターを選択して起動したところ、以下の図のように接続失敗のポップアップが表示されて、接続できませんでした。
![alma_connectfailed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750854/a4572124-1e93-a615-8a0b-090bcef55f61.png)

## これで接続できた！
まずAlmalinuxのネットワーク設定（画面右上）からネットワークアイコンをクリックします。次に表示されたメニューから[有線設定]を選択します。
![alma_connectsetup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750854/861e2e05-d360-26af-f807-1eed5b929f3a.png)

ホストオンリーアダプターは無効になっているEthernet (enp0s8)なので、こちらの設定ボタンを選択します。

![alma_connectsetup2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750854/a9269f14-0d1d-4976-b6be-ac0d65e0b0ad.png)

ホストオンリーネットワークの設定は以下の図の通りで

![hostonlynetwork.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750854/608201f3-f085-dfe6-bb5a-f40ce496b686.png)

この範囲内のIPアドレスをAlmalinuxのEthernet (enp0s8)に手動で割り当てます。

![alma_connectsetup3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750854/467ea113-5a79-72a3-4cc8-f27ff4debd1d.png)

これによりTeratermでSSHを使ってホストOSからゲストOSへ接続することができました！
![alma_teraterm1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750854/34dcddfd-3bfe-1b7f-a5ad-e2e74b739258.png)

![alma_teraterm2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750854/9d8430ae-9ce4-36e6-5841-74c4c01db29c.png)

## 終わりに
ホストオンリーネットワークのDHCPサーバーを有効化していたのですが、それがうまく動いていないようなんですよね。その問題は残るものの、とりあえずホストOSからゲストOSへの接続ができたので気にしないことにします。

上記ではGUI上のネットワーク設定でIPアドレスなどの設定を行いましたが、端末から以下のコマンドでも接続できるようになりました。
```
nmcli connection modify '有線接続 1' ipv4.addresses 192.168.56.3/24
nmcli connection modify '有線接続 1' ipv4.gateway 192.168.56.1
```
【AWS】FSxとEFSの違いをざっくり解説するよ！


AWS のファイルストレージを使いたいとき、**Amazon EFS** と **Amazon FSx** っていう選択肢がよく出てきますよね。どちらもマネージドなファイルストレージですが、対応するプロトコルとか、使いどころが結構違います。

この記事では、EFS と FSx の違いをざっくりまとめてみました。自分のアプリやワークロードに合うほうを選ぶ際の参考になればうれしいです！

---

## Amazon EFS とは？

**Amazon EFS (Elastic File System)** は、Linux 向け NFS 共有を手軽に使いたいときに便利なマネージドファイルストレージです。

### 特徴
- **サーバーレス ＆ 自動スケーリング**  
  ストレージ容量が必要に応じて伸び縮みするので、最初にサイズを決めなくても大丈夫。使った分だけ課金されます。

- **NFSv4.x 対応**  
  Linux の EC2 インスタンスやコンテナ (ECS/EKS) など、NFS をサポートする環境なら複数台から同時にマウント可能。

- **料金体系**  
  従量課金（使った分だけ）。**Infrequent Access** みたいなクラスを使ってコストを下げることもできます。

### 主なユースケース
- **Docker/ECS/EKS** など、複数インスタンスやコンテナから共有するストレージ  
- 分散処理やビッグデータ系でのデータ共有  
- Linux でシンプルにファイルサーバーを実現したいとき

### メリット
- **設定がシンプル**：サーバーレスなため、インフラ運用の手間が少ない  
- **自動スケール**：使用量が増えても手動でボリュームを拡張する必要なし

### 注意点
- **Windows 環境には不向き**（SMB じゃなくて NFS）  
- **性能に限界**（バーストクレジットなどを把握しておかないと、思ったほどスループットが出ないことも）

---

## Amazon FSx とは？

**Amazon FSx** は、Windows や Lustre、NetApp ONTAP など、**特定のファイルシステムをマネージドで提供するサービス群**の総称です。用途によっていくつか種類があります。

### 1. FSx for Windows File Server
- Windows の SMB 共有に対応  
- Active Directory や NTFS パーミッションなど、Windows ネイティブのファイル共有をクラウドで使える

### 2. FSx for Lustre
- HPC（ハイパフォーマンスコンピューティング）用の並列ファイルシステム  
- 機械学習やビッグデータ解析など、大規模データを超高速で扱うシーンに強い

### 3. FSx for NetApp ONTAP
- NetApp ONTAP をマネージドで提供  
- NFS と SMB の両対応、Snapshot や FlexClone など NetApp 独自機能をそのまま使える

### 主なポイント
- **AWS がバックエンドを管理**：ユーザーはファイルシステムの設定や操作に専念  
- **選んだファイルシステムによって料金や機能が異なる**：用途やワークロードに合わせて選ぶ必要がある

### 使いどころ
- **Windows ファイルサーバーをクラウドに** → FSx for Windows  
- **超高速 I/O が必要** → FSx for Lustre  
- **NetApp オンプレ運用を移行** → FSx for NetApp ONTAP

---

## EFS と FSx の違いを比較

| 項目                      | EFS                                 | FSx                                          |
|---------------------------|--------------------------------------|----------------------------------------------|
| **主な目的**             | Linux NFS 共有をサクッと使いたい      | Windows や Lustre、NetApp ONTAP など特化型   |
| **プロトコル**            | NFS (v4.x)                           | SMB / NFS / Lustre (種類による)             |
| **スケーラビリティ**      | サーバーレス＆自動スケール            | 容量やパフォーマンスを指定して作成する場合も |
| **ユースケース一例**      | コンテナ共有、Linux 間ファイル共有など | Windows ファイル共有、高速並列処理など      |
| **料金体系**             | 従量課金（使った分だけ）              | 容量や性能の設定で変動（指定リソースに応じて）|
| **メリット**             | シンプルな運用、NFS 共有が簡単        | Windows / HPC / NetApp など特化機能が使える |
| **デメリット (注意点)**   | Windows 環境に不向き、高性能はやや弱い | サービスによっては設定が複雑になりがち       |

---

## 結局どっちを使えばいいの？

- **Linux + NFS で共有ファイルを使いたい** → **EFS**  
  - サーバーレスで自動スケールしてくれるのがラク。Docker/ECS/EKS のコンテナからも使いやすい。

- **Windows のファイルサーバーが欲しい** → **FSx for Windows**  
  - Active Directory とか NTFS パーミッションとか、Windows ネイティブ機能が必要ならコレ。

- **機械学習やビッグデータ解析で超高速 I/O が必要** → **FSx for Lustre**  
  - HPC 向けに設計されてるから、大規模データ処理でスループットがかなり出せる。

- **NetApp ユーザー** → **FSx for NetApp ONTAP**  
  - オンプレで NetApp を使ってるなら、そのままクラウドに持ってきやすい。

---

## まとめ

- **EFS** は “NFS 共有をサーバーレスで使える” シンプルなファイルシステム。Linux 環境ならまずはコレ。
- **FSx** は “Windows / HPC / NetApp” など、特定のユースケース向けに最適化されたファイルシステムをマネージドで提供するファミリー。

要件に合わせてどっちを選ぶか決めましょう。  
EFS で十分なケースも多いですが、Windows や高速処理など特化ニーズがあるなら FSx がベターです。  

**何か質問や補足があればコメントで教えてください！** ではまた！
SELECT list is not in GROUP BY clause and contains nonaggregated column MyBatis使用時のSQLエラー解消

# SELECT list is not in GROUP BY clause and contains nonaggregated column MyBatis使用時のSQLエラー
Java,Mybatisが生成したMapperを使用していて、当エラーが出ている場合、以下SQLモードを使用しているmySQLで設定することで解消できます。

このコマンドを実行するのは、mySQLにログインして、コマンドを実行します。
または、A5:SQL Mk-2を使って、データベースに接続し、クエリ実行できます。
ダウンロード→https://a5m2.mmatsubara.com/
A5:SQL Mk-2でのコマンドの実行の仕方→https://qiita.com/kanfutrooper/items/a4db929306efcc91b610#:~:text=%E3%81%AE%E3%81%BF%E5%AE%9F%E8%A1%8C%E5%8F%AF%E8%83%BD%E3%80%82-,%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%EF%BC%88Ctl%20%2B%20Enter%EF%BC%89%E3%81%A7%E5%AE%9F%E8%A1%8C,%E3%81%B0SQL%E3%82%92%E5%AE%9F%E8%A1%8C%E5%8F%AF%E8%83%BD%E3%80%82

```
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
```

ちなみに
```
SELECT @@GLOBAL.sql_mode;
```
で現在設定されているSQLモードを確認できます。
NO_ZERO_IN_DATE,NO_ZERO_DATEもしくはONLY_FULL_GROUP_BYが含まれるとこのエラーが発生する気がします。

ちなみに、A5:SQL Mk-2にてSET GLOBAL sql_mode実行後、SELECT @@GLOBAL.sql_modeでモードの確認をされる場合、アプリ自体を再起動もしくは、再接続を行う必要があるかもしれません。

## 余談
MyBatisで生成される一部の条件設定でのクエリのコードにdistinctが含まれるのですが、その「distinctを消すことで解消できました！」なんて話もあったんですが、自動生成するたびにそれを行う必要がある上に、テーブルが多い場合、いちいち修正するのは論外かと思うので、SQLモードについて、プロジェクトで縛りがなければ、上記設定することで、解消できるかと思います。
PnP PowerShellでSharePointリストのアイテムにアクセス権限を付与する

# やりたいこと
SharePointリストのアイテム単位でアクセス権限を設定する場合、通常は「アクセス許可の管理」からユーザーまたはグループに編集権限や閲覧権限を割り当てますが、これをPowerShellで実行したいと考えています。

![sharepoit-list-item-access.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/2cc4f145-9dd0-0eac-d87f-339b01133343.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/15d81647-d18f-36ef-2350-ba597530fb00.png)

# 実装方法
実装方法はPnP PowerShellコマンドレットのドキュメントに記載されています。

https://pnp.github.io/powershell/cmdlets/Set-PnPListItemPermission.html

# PowerShellの実行コマンド
結論、実行コマンドは以下です。
ClientリストのClientName列に「テスト株式会社」と設定されているアイテムに対して、特定のユーザーに編集権限を割り当てます。
```powershell
# SharePointサイトに接続
$siteUrl = "https://{tenant_name}.sharepoint.com/sites/{site_name}"
Connect-PnPOnline -Url $siteUrl -UseWebLogin

# ClientリストのアイテムにEdit権限を割り当てる
$user = "{アクセス権限を割り当てるユーザーを指定する}"
$clientName = "テスト株式会社"
$listName = "Client"
$camlQuery = @"
<View>
  <Query>
    <Where>
      <Eq>
        <FieldRef Name='ClientName' />
        <Value Type='Text'>$clientName</Value>
      </Eq>
    </Where>
  </Query>
</View>
"@

$items = Get-PnPListItem -List $listName -Query $camlQuery
$itemId = $items | ForEach-Object { $_.Id }
Set-PnPListItemPermission -List $listName -Identity $itemId -User $user -AddRole "投稿"
```